JAVA 기본형 변수의 형변환 관련한 질문입니다.
글쓴이: canuyes / 작성시간: 수, 2014/09/03 - 7:31오후
안녕하세요
C++을 주로 사용하다가 Java를 배우는 학생입니다.
Java가 C++에 비해 조금 더 타이트(?)한 형변환 규칙을 가지고 있는 것 같은데 쉽게 정리되지 않아 질문 올립니다.
제가 나름대로 정리해보니
1.
큰 자료형의 변수 = 작은 자료형의 변수;
는 명시적으로 형변환을 해주지 않아도 자동으로 가능하고,
2.
작은 자료형의 변수 = 큰 자료형의 변수;
는 반드시 명시적으로 형변환을 해주어야 한다는 것으로 판단 했습니다.
1, 2가 변수끼리의 대입연산에 적용되는 규칙일때는 잘 이해가 되었는데,
리터럴의 대입연산으로 끌고오니 잘 이해가 되지 않습니다.
예를 들어,
int tmp = 10; //0k byte a = 50; //OK a = 128 //오버플로우, Error! a = tmp; //Error!
위의 코드에서 2번째 줄이 이해가 되지 않습니다. 분명 Java에서 리터럴 정수는 int로 처리된다고 배웠는데, "byte 형 변수 = int 형 데이터;" 가 어떻게 명시적인 형변환 없이 가능한지 궁금합니다.
리터럴만 예외적으로 "작은 자료형의 변수 = 큰 자료형의 데이터;" 가 가능하다고 생각해도,
3번째 줄은 Error를 보여주는 것을 보면 의아해집니다.
기본형간의 형변환에 대한 규칙을 알 수 있는 문서나 링크가 있을까요?
Forums:
JVM 을 공부해보세요.
우선 위의 궁금증을 해결하기 위해서는 java의 언어 스펙보다는 jvm 에 대해서 공부를 하셔야 합니다.
질문자께서 작성한 소스를 class 로 컴파일한 뒤 javap등으로 바이트코드를 출력해보면
이 두개의 변수할당은
와 같이 정수형으로 할당됨을 알 수 있습니다. 즉 질문자께서 알고 계신대로 "리터럴 정수는 int로 처리된다" 는 것입니다.
여기서 그럴 수 밖에 없는 이유가 jvm 의 local variable section 의 구조에 있습니다.
자바에서 메소드가 호출될 때 메소드 상태 정보를 저장하기 위한 스택 프레임이 생성되게 되는데 operand stack 과 local variable section, frame data 이렇게 3개로 이뤄져 있습니다.
c/c++에서 스택의 역활을 operand stack 이 한다고 보시면 되고 메소드의 파라미터 및 지역변수는 local variable section 에 저장됩니다.
operand stack 과 local variable section 다루는 오퍼랜드를 보면 ILOAD n ISOTRE n 와 같은 식입니다. 배열과 유사하게 0이상의 정수첨자로 가능한 구조 입니다.
즉 쉽게 local variable section 을 int 의 배열로 생각하면 이해하기 쉽습니다. int 의 배열이니 byte 도 int 크기를 할당받으며 double 같은 경우는 당연히 2개의 공간을 할당받습니다.
정리하면 local variable section 은 1칸 내지는 2칸 으로 나뉘어져 있어서 정수 같은 경우는 모두 4바이트 크기 입니다.(boolean 도 4바이트 정수입니다.)
그러면 이제
의 의문을 풀어보죠.
byte 도 int와 같이 4바이트를 할당 받는데 에러가 왜 발생하는가? 타입정보을 어디서 얻는가?
jvm 에는 constants pool 이라는 영역이 있으며 메소드영역에 LocalVariable Table 이라는 것도 있습니다.
자바가 디컴파일이 손쉬운 큰 이유 중 하나 인데 constants pool 에 해당 클래스가 사용하는 변수명, 변수타입등등의 모든 메타정보가 기입되어 있습니다.
즉 LocalVariable Table 을 참고하여 해당 변수의 타입을 알 수 있습니다.
https://github.com/contra/CJBE 에 가셔서 바이트 코드 에디터를 내려받으시고 해당 에디터을 이용하여 메소드들을 보시면 이해할 수 있으리라 봅니다.
Assignment Conversion 을 읽어 보시면 도움이 될 것입니다.
상수값이 int 보다 작은 자료형을 갖는 변수에 대입될 때는 narrowing primitive conversion 이 적용되기 때문입니다.
자세한 사항은 자바 스팩에서 5.2 Assignment Conversion을 읽어 보시기 바랍니다.
댓글 달기