"Kısa otuz = 3 * 10" neden yasal bir görevdir?


103

Eğer shortotomatik terfi edilir intaritmetik işlemlerinde, sonra neden olduğunu:

short thirty = 10 * 3;

shortDeğişkene yasal bir atama thirtymı?

Sırayla, bu:

short ten = 10;
short three = 3;
short thirty = ten * three; // DOES NOT COMPILE AS EXPECTED

bunun kadar iyi:

int ten = 10;
int three = 3;
short thirty = ten * three; // DOES NOT COMPILE AS EXPECTED

bir intdeğer atamaya shortbeklendiği gibi çevrim yapılmadan izin verilmediğinden derlemez.

Sayısal değişmezlerle ilgili özel bir şey mi var?


23
short thirty = 10 * 3;büyük ihtimalle short thirty = 30;geçerli bir ifade olan derleyici ile değiştirilir . (Yine de ilgili JLS bölümüne bakmam gerekir).
Thomas

Derleyici 10 * 3, değişkeni sonuçla hesaplar ve başlatır. Çalışmayan örneğinizde, hesaplama, JVM'nin kısa devre yaptığı çalışma zamanında gerçekleşir.
Felix

Sanırım bu, stackoverflow.com/questions/30346587/java-char-to-byte-casting veya stackoverflow.com/questions/9379983/… adresinin bir kopyası . Ancak: İyi final int ten = 10; final int three = 3; short thirty = ten * three;derlediğine dikkat edin.
Marco13

7
If short is automatically promoted to int in arithmetic operations- bu alakalı değil. Ne 10de 3onlar, konum değişmezleri şort ne de terfi bulunmaktadır.
Matthew

@MatthewRead: ama değişmez değerler olarak bile, belirli bir veri türü olarak değerlendirilmeleri gerekiyor, değil mi? Bu yüzden doğrudur 10ve 3olarak değerlendirilir intderleyici tarafından s?
LarsH

Yanıtlar:


139

Çünkü derleyici 10*3, derleme zamanında 30 ile değiştirilir . Yani, etkili bir şekilde: short thirty = 10 * 3derleme zamanında hesaplanır.

Değiştirmeyi deneyin tenve threekarşı final short(onları derleme zamanı sabitleri yapma) ve ne olduğunu görün: P

Bayt kodunu kullanarak inceleyin javap -v Her iki sürüm için ( 10*3ve final short) . Çok az fark olduğunu görebileceksiniz.

Tamam, işte farklı durumlar için bayt kodu farkı.

Dava 1 :

Java Kodu: main () {kısa s = 10 * 3; }

Bayt kodu:

stack=1, locals=2, args_size=1
         0: bipush        30  // directly push 30 into "s"
         2: istore_1      
         3: return   

Durum -2:

public static void main(String arf[])  {
   final short s1= 10;
   final short s2 = 3;
   short s = s1*s2;
}

Bayt kodu:

  stack=1, locals=4, args_size=1
         0: bipush        10
         2: istore_1      
         3: iconst_3      
         4: istore_2      
         5: bipush        30 // AGAIN, push 30 directly into "s"
         7: istore_3      
         8: return   

Durum -3:

public static void main(String arf[]) throws Exception {
     short s1= 10;
     short s2 = 3;
     int s = s1*s2;
}

Bayt kodu:

stack=2, locals=4, args_size=1
         0: bipush        10  // push constant 10
         2: istore_1      
         3: iconst_3        // use constant 3 
         4: istore_2      
         5: iload_1       
         6: iload_2       
         7: imul          
         8: istore_3      
         9: return 

Yukarıdaki durumda 10ve 3yerel değişkenlerden alınır s1ves2


17
Try changing ten and three to final shortegzersizi beğendim :)
Sergey Pauk

1
@SergeyPauk - Derleme zaman sabitlerini anlamak için bu gerçekten önemlidir .. tüm ilkel
öğeler

1
@TheLostMind Daha iyi bir ifade öneririm you will see that there's no difference (between those two lines in the decompiled code)çünkü bu senin amacın değil mi?
Sergey Pauk

4
Eğlenceli bir şekilde, bu aynı zamanda case 10*3:bir anahtar yapısında bunun yasal olduğu anlamına gelir .
Ceiling Gecko

5
Ve benzer şekilde enum yapılarında. Aslında, bitfield enum sabitleri için 1 << 5 gibi şeyler kullanmak deyimseldir.
Bathsheba

18

Evet, gerçek durumla ilgili özel bir şey var: derleme zamanında 10 * 3değerlendirilecek . Bu nedenle , çarpılmış değişmez değerler için açık bir dönüşüme ihtiyacınız yoktur .(short)

ten * three derleme zamanı değerlendirilebilir olmadığından, açık bir dönüştürme gerektirir.

Eğer farklı bir konu olacağını tenve threeişaretlenmiştir final.


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.