JAVA 기본형 변수의 형변환 관련한 질문입니다.

canuyes의 이미지

안녕하세요

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를 보여주는 것을 보면 의아해집니다.

기본형간의 형변환에 대한 규칙을 알 수 있는 문서나 링크가 있을까요?


익명 사용자의 이미지

우선 위의 궁금증을 해결하기 위해서는 java의 언어 스펙보다는 jvm 에 대해서 공부를 하셔야 합니다.
질문자께서 작성한 소스를 class 로 컴파일한 뒤 javap등으로 바이트코드를 출력해보면

int tmp = 10;
byte a = 50;

이 두개의 변수할당은
BIPUSH 10
ISTORE x
BIPUSH 50
ISTORE x

와 같이 정수형으로 할당됨을 알 수 있습니다. 즉 질문자께서 알고 계신대로 "리터럴 정수는 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바이트 정수입니다.)

그러면 이제

a = 128 //오버플로우, Error!

의 의문을 풀어보죠.
byte 도 int와 같이 4바이트를 할당 받는데 에러가 왜 발생하는가? 타입정보을 어디서 얻는가?

jvm 에는 constants pool 이라는 영역이 있으며 메소드영역에 LocalVariable Table 이라는 것도 있습니다.
자바가 디컴파일이 손쉬운 큰 이유 중 하나 인데 constants pool 에 해당 클래스가 사용하는 변수명, 변수타입등등의 모든 메타정보가 기입되어 있습니다.
즉 LocalVariable Table 을 참고하여 해당 변수의 타입을 알 수 있습니다.

https://github.com/contra/CJBE 에 가셔서 바이트 코드 에디터를 내려받으시고 해당 에디터을 이용하여 메소드들을 보시면 이해할 수 있으리라 봅니다.

익명 사용자의 이미지

상수값이 int 보다 작은 자료형을 갖는 변수에 대입될 때는 narrowing primitive conversion 이 적용되기 때문입니다.

자세한 사항은 자바 스팩에서 5.2 Assignment Conversion을 읽어 보시기 바랍니다.

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.