왜“short thirty = 3 * 10”이 법적 임무입니까?


102

경우 short자동으로 승격되어 int산술 연산에서, 왜이다 :

short thirty = 10 * 3;

short변수에 대한 법적 할당 thirty?

차례로 이것은 :

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

뿐만 아니라 :

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

예상대로 캐스팅하지 않고 int값을 할당 할 수 없기 때문에 컴파일되지 않습니다 short.

숫자 리터럴에 대해 특별한 일이 있습니까?


23
short thirty = 10 * 3;아마도 short thirty = 30;유효한 명령문 인 컴파일러 로 대체되었을 것입니다 . (하지만 관련 JLS 섹션을 찾아야합니다).
Thomas

컴파일러 10 * 3는 결과로 변수를 계산 하고 초기화합니다. 작동하지 않는 예제에서 계산은 JVM이 short를 캐스팅하는 런타임에 발생합니다.
Felix

나는 이것이 stackoverflow.com/questions/30346587/java-char-to-byte-casting 또는 stackoverflow.com/questions/9379983/… 의 중복이라고 생각합니다 . 그러나 : final int ten = 10; final int three = 3; short thirty = ten * three;잘 컴파일됩니다.
Marco13 2015-08-25

7
If short is automatically promoted to int in arithmetic operations-그것은 관련이 없습니다. 어느 쪽 10도 아니다 3그들은있는 거 리터럴 반바지 없습니다 없으며 승진이다.
Matthew Read

@MatthewRead :하지만 리터럴이라하더라도 특정 데이터 유형으로 평가되어야합니다. 그래서 사실이다 103같이 평가 int컴파일러로의?
LarsH

답변:


139

컴파일러는 컴파일 타임에10*3 30으로 대체되기 때문 입니다. 따라서 효율적으로 : short thirty = 10 * 3컴파일 시간에 계산됩니다.

변경 시도 tenthreefinal short(그들에게 컴파일 시간 상수을) 어떻게되는지 : P를

javap -v 두 버전 ( 10*3final short)에 대해 사용하여 바이트 코드를 검사 합니다. 차이가 거의 없음을 알 수 있습니다.

자, 여기에 다른 경우에 대한 바이트 코드 차이가 있습니다.

사례 -1 :

자바 코드 : main () {short s = 10 * 3; }

바이트 코드 :

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

사례 -2 :

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

바이트 코드 :

  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   

사례 -3 :

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

바이트 코드 :

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 

위의 경우, 103로컬 변수에서 촬영 s1s2


17
좋아하는 Try changing ten and three to final short운동 :)
Sergey Pauk 2015-08-25

1
@SergeyPauk - 그건 .. 이해 컴파일 시간 상수에서 정말 중요한 모든 프리미티브에 적용됩니다 (물론 문자열을 ..) :)
TheLostMind

1
@TheLostMind 더 나은 표현 you will see that there's no difference (between those two lines in the decompiled code)원인을 제안 할 것입니다 .
Sergey Pauk 2015 년

4
흥미롭게도 이것은 또한 case 10*3:스위치 구조에서 합법적 이라는 것을 의미합니다 .
Ceiling Gecko

5
그리고 마찬가지로 열거 형 구조에서도 마찬가지입니다. 사실, 비트 필드 열거 형 상수에 1 << 5와 같은 것을 사용하는 것은 관용적입니다.
밧세바

18

예, 리터럴 케이스에 특별한 일 10 * 3이 있습니다 . 컴파일 타임에 평가됩니다 . 따라서 (short)곱한 리터럴에 대한 명시 적 변환이 필요하지 않습니다 .

ten * three 컴파일시 평가할 수 없으므로 명시 적 변환이 필요합니다.

tenthree표시 가있는 경우 다른 문제가됩니다 final.


당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.