Değer atarken tek Java üçlü davranışı. Java bunun gerçekleşmesi için perde arkasında ne yapıyor?


10

Birkaç gün önce, Java'nın aşağıdakilerin nasıl veya neden gerçekleştiğine dair herhangi bir belge bulamadığım büyüleyici bir senaryo ile karşılaştım. (Bu snippet, hatanın basitleştirilmiş bir şeklidir.)

    @Test
    public void test() {
      boolean bool = false;
      Integer intVal = Integer.valueOf(5);
      Long longVal = null;
      Long result = bool ? intVal : longVal;

      System.out.println(" > " + result);
   }

yukarıdaki kod parçasında:

bool = true ise, '5' değerini alırsınız;

ancak bool = false ise, üçlü işlemi değerlendirmeye çalışırken boş bir işaretçi istisnası alırsınız. Baskı ifadesi DEĞİL.


Bunu düzeltmek için sadece 'sonucu' değiştiriyorum

Long result = bool ? Long.valueOf(intVal) : longVal;

Bunu yapmak, ihtiyacım olan beklenen davranışı verecektir:

bool = true ise, '5' değerini alırsınız;

ama bool = false olursa, o zaman 'null' alırsınız


şimdi eğlenceli kısmı, eğer bu normal bir if / else deyimine bölerseniz, java derlemenize izin vermez

longVal = intVal; 

ancak üçlü operatör üzerinden bunu yakalamaz. Peki, orijinal snippet'te null noktasını göstermek için Java ne yapıyor?

(java 11)

Yanıtlar:


10

Bunu yaptığınızda:

Long result = bool ? intVal : longVal

Bu ifade a döndürür longve boolfalse olduğunda , değişkene nullsığdırmak için bir Uzun değere kutudan çıkarmaya çalışır resultve bir NPE atar.

Bunu yaptığınızda:

Long result = bool ? Long.valueOf(intVal) : longVal

Bu ifade zaten geri dönüyor, Longardından kutudan nullçıkarmaya gerek yok ve değer resultdeğişkene başarıyla atandı .

Referans:

Yorumlar bölümünde tartışıldığı gibi, bunun neden olduğunu daha iyi anlamak için JLS'nin aşağıdaki bölümlerini kontrol edin:


Farklı referans tablosu 15.25 A'dan E'ye , "Integer / Long" un bnp (Integer, Long) ile sonuçlandığı "açık" olduğu için şaşırdım.
matt

İyi cevap. Genellikle hiçbir fikrim olmadığında, içeride neler olup bittiğini, derlenen bayt koduna bir göz atmanızı öneririm, ki bu tam olarak ne olduğunu açıklar. En azından minimal bir kod snippet'i çıkarırken, bu aşağı yukarı bir eğitim meselesi, nasıl okunup anlaşılacağı.
Jan

Gibi JLS, Bölüm 5.6.2 diyor ki: "Bir işlenen bir başvuru türü ise, unboxing dönüştürme tabi tutulur"; sonra "Genişleme ilkel dönüşümü (§5.1.2) uygulanır [..]"
Diego Magdaleno
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.