회고록 블로그

[공부 쉬어가기] Java: 왜 복합 대입 연산자는 형변환 에러가 발생하지 않을까 본문

2. 프로그래밍 언어 공부/Java

[공부 쉬어가기] Java: 왜 복합 대입 연산자는 형변환 에러가 발생하지 않을까

김간장 2021. 9. 1. 22:27

Java에서 복합 대입 연산자(+=, -=, *= 등)를 공부하다가

아래와 같은 경우에는 에러가 발생하지 않는다는 사실을 알게 되었다.

 

 

상황 설명을 조금 하자면..

num이라는 변수는 데이터 타입이 short형이다.

그리고 num변수(short형)에 50 이라는 숫자(long형)를 더하고 싶다.

 

보통 'num = num+50L'으로 코드를 작성하면 에러가 발생한다.

덧셈 연산을 처리하는건 괜찮은데 데이터 타입이 short인 곳에 값을 대입하지 못해서 에러가 발생하는 것이다.

 

즉, 이런 과정으로 문제가 생긴다.

1) num 변수에 있는 값은 데이터 타입이 short형이다.

num 변수에 있는 '10'을 long형으로 변환한다. (자동 형변환)

2) long형으로 변환한 '10'과 long형인 '50'을 더한다.

그리고 이 더한 값은 데이터 타입이 long형이 된다

3) long형인 데이터를 short형인 num이라는 변수에 대입하려고 한다.

당연히 크기가 큰 자료형(long)에서 작은 자료형(short)으로 자동 형변환이 되지 않기 때문에

long을 short로 변환할 수 없다고 에러가 발생한다.

(아래 그림 참조)

 

 

그렇기 때문에 보통은 강제 형변환을 해주거나 해야하는데..

복합 대입 연산자에서는 에러가 발생하지 않았다.

 

그 이유를 알고 싶어서 스택오버플로우를 뒤적뒤적 거리며 해답을 찾아왔다.

역시 사람 사는 곳은 다 비슷한 생각을 하나보다.

 

출처 : https://stackoverflow.com/questions/8710619/why-dont-javas-compound-assignment-operators-require-casting

 

Why don't Java's +=, -=, *=, /= compound assignment operators require casting?

Until today, I thought that for example: i += j; Was just a shortcut for: i = i + j; But if we try this: int i = 5; long j = 8; Then i = i + j; will not compile but i += j; will compile fine....

stackoverflow.com

 

놀랍게도 답변들(Answers)을 보면 "오라클 공식 문서"를 보라고 얘기한다.

역시 진리의 Java SE Specifications. 모든 것이 다 들어있다.

 

https://docs.oracle.com/javase/specs/jls/se14/html/jls-15.html#jls-15.26.2

 

Chapter 15. Expressions

 

docs.oracle.com

 

얕은 영어 실력이지만 15.26.2의 Compound Assignment Operators를 대충 해석해보기로 했다.

 

대충 내용을 보면..

"복합 대입 연산자(E1 += E2, E1 -= E2 등 형태)는 아래의 형태와 동일합니다.

E1 = (T)((E1) + (E2))

E1 = (T)((E1) - (E2)) 등..

여기에서 "T"는 E1의 (데이터) 타입을 말합니다.

단, E1은 단 한번만 평가 됩니다.

 

예를 들어서, 아래의 코드는 올바른 코드입니다.

short x = 3;
x += 4.6;

그리고 "여기서 결과는 7이 됩니다. 즉, x는 7입니다.

왜냐하면 아래와 동일하기 때문입니다."

short x = 3;
x = (short)(x+4.6);

 

 

Java 프로그래밍 언어를 만들 때, 기획자와 개발자들이 위와 같은 규칙을 만들어 놓은 것 같다.

 

큰 데이터 타입에서 작은 데이터 타입으로 변환할 때, 자동 형변환이 되지 않도록 만들어 놓았으면서

왜 복합 대입 연산자에는 암묵적으로 허용을 해줬는지 모르겠다.

 


개인적으로 생각하기에는 복합대입연산자는 사용한 의도가 확실하기 때문에 이렇게 만들어놓은게 아닐까 싶다.

 

즉 num += 30L 같은 경우,

왼쪽의 표현식과 오른쪽의 표현식에 'num' 변수가 모두 존재한다는 것을 알기 때문에

"개발자가 'num'에게 어떤 연산을 하고, 다시 그 값을 'num' 변수에 대입하고 싶어하는구나 ▶ 결과적으로 'num'(왼쪽 피연산자)의 값이 중요하구나 ▶ 그렇다면 왼쪽 피연산자의 자료형에 맞춰 형변환을 자동으로 해줘도 되겠다"라는 컨셉으로 자동으로 형변환이 되도록 해준 것이 아닐까.

뭐.. 아는게 없으니까 결국 개인적인 추측일 뿐이다.

 

 

어쨌든 왜 형변환이 필요없는지는 이해했으니 '왜 저렇게 만들었을까'하는 궁금증은 일단 넣어놓기로 했다.

 

 

Comments