java-school logo
Last Modified 2016.4.7

자료형(Data Type)과 형변환(Type Casting)

리터럴과 변수

int year = 2016;
위에서 2016처럼 쓰이는 프로그램 요소를 리터럴(Literal)이라 한다. 리터럴은 소스 코드에서 고정된 값을 표현한다. year처럼 쓰이는 프로그램 요소를 변수라 한다. 변수란 값을 저장하기 위해 이름 붙인 메모리 기억공간으로 기억공간의 크기는 자료형으로 결정된다.

자바의 자료형(Data Type)

자바의 자료형은 크게 두 종류로 나뉜다.
기본형은 일반적인 데이터를 위한 자료형이다. 참조형은 객체지향 프로그래밍 언어에서 추가된 자료형으로 참조형 테이터를 위한 자료형이다.

기본형

자료형 설명
boolean true 또는 false boolean present = true;
char 2 바이트 유니코드 문자.
언제나 ' '(홑따옴표)를 사용하여 표현.
char grade = 'A';
char ch = '\uFFFF';
(UTF-16 문자셋에서 16진수 FFFF에 해당하는 문자)
char ech = '\n'; //new line
char ech = '\b'; //백스페이스
char ech = '\t'; //탭
char ech = '\\'; //역슬래시
char ech = '\"'; //큰 따옴표
char ech = '\''; //작은 따옴표
byte 1 바이트 정수형 데이터 byte weight = 71;
short 2 바이트 정수형 데이터 short bill = 30000;
int 4 바이트 정수형 데이터 int balance = 56219618;
long 8 바이트 정수형 데이터 long balance = 56219000L;
float 4 바이트 실수형 데이터 float rate = 6.195f;
double 8 바이트 실수형 데이터 double rate = 6.195;

값의 자료형

int i1 = 3;//정수형 숫자 뒤에 아무것도 붙지 않으면 int 리터럴
int i2 = 300000000;//컴파일 에러!
3000000000은 int 리터럴이다. 하지만 3000000000(30억)은 int 값이 가질 수 있는 범위를 벗어난다. 따라서 int형으로 3000000000이란 값은 만들어지지 않고 컴파일 에러가 발생한다.
long money = 1000L;//1000L은 long 리터럴 
double d1 = 3.14;//소수점을 가진 숫자 뒤에 아무것도 붙지 않으면 double 리터럴
double d2 = 3.14D;//3.14D는 double 리터럴
double d3 = 3.14d;//3.14d는 double 리터럴
float f2 = 3.14f;//3.14f는 float 리터럴
float f3 = 3.14F;//3.14F는 float 리터럴

int 리터럴이 int형 값이 아닐 수 있다.

자바에는 byte와 short를 위한 리터럴이 없다.
아래와 같은 경우에 int 리터럴이 int 값이 아니다.
byte b = 1; //1은 int 리터럴이지만 byte형 값이 된다.
short s = 2; //2는 int 리터럴이지만 short형 값이 된다.

참조형

Student kim = new Student();
자바에서 변수를 선언할 때, 변수 앞에 자료형이 먼저 나와야 한다. 따라서 위의 변수 kim의 자료형은 Student이다. 기본형에 Student란 자료형이 없으니 Student는 참조형이다. new Student()가 실행되면, 생성된 객체의 참조가 kim에 할당된다. 객체의 참조는 메모리상에서 객체 주소를 의미한다. 변수 kim과 .(도트)를 사용한다면 kim이 참조하는 객체에 접근할 수 있다.
kim.name = "김선달";
만약 kim이 어떤 학생 객체도 가리키지 않도록 하려면 null 값을 할당한다.
kim = null;

형변환(Type Casting)

형변환이란 값의 자료형을 원하는 자료형으로 변환하는 작업을 말한다.
형변환에는 JVM이 판단해서 행하는 자동 형변환과 프로그래머가 의도적으로 일으키는 명시적 형변환이 있다.

자동 형변환(Up-Casting)

long money = 300;//300은 int 리터럴
위 코드는 long형 변수 money에 int형 값 300을 할당하려 한다. 자바는 자료형의 적용에 엄격하다. long형 변수 money에 저장되는 값은 long형이여야 한다. 이 경우 JVM은 할당하기 전에 300을 long형으로 변환한다. 자동 형변환은, 작은 자료형에서 큰 자료형 방향으로 변환이 일어나므로, Up-Casting이라 한다.
byte --> short --> int --> long --> float --> double
long --> float 방향에 주목하자. 비록 float이 4바이트 영역의 메모리를 차지하지만 실수이므로 long에서 float으로 자동 형변환된다. 다음 예를 보자.
float x = 10L;//JVM은 long형 값 10을 float형의 값 10으로 형변환한다.

사칙연산에서 일어나는 자동 형변환

int x = 3 + 3.5 + 4; //컴파일 에러!
3.5는 double형 값이고, 3과 4는 int형 값이다.
int를 포함하여 자료형이 int 이상의 값들이 참여하는 산술 연산에서는 값들 중 가장 큰 자료형으로 나머지 값들의 자료형이 변환된다. 따라서 위 코드에서 3과 4는 연산이 실행되기 전에 double형으로 변환된다.
int x = 3.0 + 3.5 + 4.0;
3.0 + 3.5 + 4.0의 결과는 dobule형 값이고, 이 결과값은 int형 변수에 할당할 수 없으니 컴파일 에러가 발생한다. 이해했다면 다음 예에서 z에 할당되는 값을 예상해 보자.
int x = 10; int y = 4; int z = x / y;
z에는 2가 할당된다.(2.5가 아니다) 이유는 x와 y가 모두 int형 값이므로 연산 결과 역시 int형이여야 하기 때문이다.

명시적 형변환(Down-Casting)

float f = 1.1; //컴파일 에러!
변수에 값을 대입할 때 값의 자료형이 변수의 자료형보다 크면 컴파일 에러가 발생한다.
위 코드는 float형 변수에 double형 값을 대입하려고 했기 때문에 컴파일 에러가 발생한 것이다.
다음 코드는 double형 값의 자료형을 float형으로 의도적으로 바꾸는 코드이다.
float f = (float) 1.1;
다음 예를 보자.
byte b = (byte) 258; //b엔 2가 할당된다.
int형 값의 자료형을 byte형으로 바꿀 때 int의 앞 3byte는 떨어져 나간다.

z는 뭐가 될까?
int x = 10; int y = 4; double z = x / y;
z가 2.5가 되려면 연산에 참여하는 x 나 y를 double로 명시적 형변환한다.
double z = (double) x / y; 
또는
double z = x / (double) y; 

byte 또는 short형 값이 참여하는 산술연산에서의 자동 형변환

byte형이나 short형 값이 참여하는 산술연산은, 연산이 실행되기 전에 모든 값이 int형으로 변환된다.
short s1 = 1;
short s2 = 2;
short sum = s1 + s2; //컴파일 에러!
만약 컴파일 에러를 피하려면 다음과 같은 명시적 형변환이 필요하다.
short sum = (short) (s1 + s2);

String 클래스 : 자바 프로그램에서 문자열을 사용하려면

자바에서 문자열을 표현하는 방법은 String 클래스로부터 String 객체를 생성하여 사용하는 것이다. String 클래스는 자바 API에 존재한다. "안녕하세요"라는 문자열이 필요하다고 하면 아래처럼 코딩해야 한다.
char arrayOfHello = {'H','e','l','l'.'o'};
String greetings = new String(arrayOfHello);
그런데 자바에서는 다음과 같이 문자열 리터럴을 제공한다.
String greetings = "안녕하세요";//여기서 "안녕하세요"는 리터럴이다.
문자열은 자주 사용되므로, 문자열을 마치 기본 자료형처럼 사용할 수 있도록 배려한 것이다.
참고