출처 : https://stackoverflow.com/questions/3680625/integer-arithmetic-in-java-with-char-and-integer-literal
// 해당코드가 왜 되는지
char ch = 'a' + 1; // 산술변환 없음?
// 이 코드는 왜 안되는지
int result = 1_000_000 * 1_000_000L; // 산술변환 있네?
이해가 안되서 끙끙대다가 찾음.
상수, 리터럴은 고정값
이므로 컴파일러가 컴파일 시점에 결과 값을 구해서 대입시킨다.
타입변환에 특수 케이스가 있는게 아니라면, 'a' + 1
의 연산도 int + int = int
로 정리되야 한다.
미리 연산을 진행한다고 해도,
타입이 일치하지않으면 연산이 불가능하다.
'a' + 1
의1
을 컴파일러가char 타입으로 인식해야하고 산술 변환도 제외
해야 대입이 가능하다는 뜻이 되는 것 같은데...
이는 말그대로 특수 케이스
라고 생각이 될 수 밖에 없어서 멘붕이 왔다.
String.valueOf('A' + 1); // ?
int i = 1;
String.valueOf('A' + i); // int
Thanks to all who answered. For anyone interested, section 5.2 of the language specification (Assignment Conversion) does in fact say "In addition, if the expression is a constant expression (§15.28) of type byte, short, char or int : ... A narrowing primitive conversion may be used if the type of the variable is byte, short, or char, and the value of the constant expression is representable in the type of the variable."
설명을 보니 특수 케이스가 맞는 것 같다. "상수 표현식" 이라는 데,
불변 값으로 구성되는 식
, 상수나 리터럴으로 구성되는 식
을 말하고 있다.
변수의 유형이 byte, short 또는 char이고 상수 표현식의 값이
변수의 유형으로 표현 가능한 경우
축소 원시 변환을 사용할 수 있습니다."
byte b = (Byte.MAX_VALUE - 1) + 1;
b = (Byte.MAX_VALUE) + 1; // 이건 안되네
b = (byte) ((byte) (Byte.MAX_VALUE) + 1); // 하려면 캐스팅
short s = (Short.MAX_VALUE - 1) + 1;
s = (Short.MAX_VALUE) + 1; // 이건 안되고
char c = (Character.MAX_VALUE - 1) + 1;
c = (Character.MAX_VALUE) + 1; // 이것도 안되네
상수표현식
이라고 함불변값
으로 컴파일러가 컴파일 시점에 상수표현식을 결과값으로 변환시킴
byte
, char
, short
일 경우, 상수 표현식의 결과 값이 변수타입이 표현할 수 있는 값이라면 축소 원시변환
을 이용해서 변수 타입에 맞는 값을 도출 함 int intValue = (Byte.MAX_VALUE - 1) + 1;
byte b = (Byte.MAX_VALUE - 1) + 1;
불변 값이 아닌 변수
가 식에 포함되었을 경우, 상수 표현식
이 아니라서 축소 원시변환
은 일어나지 않음
int intValue = 1;
byte b = Byte.MAX_VALUE -1 + intValue;// X -> 상수표현식은 축소원시변환이 일어나지 않음
byte b = (byte) (Byte.MAX_VALUE -1 + intValue);
해결!