Search
Duplicate

Java - Type과 형변환

글감
Java
작성자
작성 일자
2024/02/08 06:43
상태
완료
공개여부
공개
Date
생성자
작업자

변수의 타입

변수(variable)란 데이터를 저장하기 위해 프로그램에 의해 이름을 할당받은 메모리 공간을 말한다.
자바에서의 데이터 타입(자료형)이란, 변수에 적재할 데이터가 메모리에 어떻게 저장되고 프로그램에서 어떻게 처리되어야 하는지를 명시적으로 알려주는 키워드이다.
자바에서의 자료형은 크게 두 가지로 구분된다.
기본형(primitive type) : 계산을 위해 실제 값을 저장하는 타입
참조형(reference type) : 객체의 주소를 저장하는 타입. null 또는 객체의 주소를 갖는다.

기본형 타입(Primitive Type)

기본형 타입에는 크게 논리형(boolean), 문자형(char), 정수형(byte, short, int, long), 실수형(float, double)으로 나뉜다.
타입
할당되는 메모리 크기
기본값
데이터의 표현 범위
논리형
boolean
1 byte
false
true, false
정수형
byte
1 byte
0
-128 ~ 127
정수형
short
2 byte
0
-32,768 ~ 32,767
정수형
int(기본)
4 byte
0
-2,147,483,648 ~ 2,147,483,647
정수형
long
8 byte
0L
-9,223,372,036,854,775,808 ~ 9,223,372,036,854,775,807
실수형
float
4 byte
0.0F
3.4e-38 ~ 3.4e38 근사값
실수형
double(기본)
8 byte
0.0
1.7e308 ~ 1.7e308 근사값
문자형
char
2 byte (유니코드)
‘\u0000’
0 ~ 65,535
기본형 타입은 모두 소문자로 이루어진다.
비객체 타입이므로 null 값을 가질 수 없다.
스택(stack)에 메모리를 생성하고 값을 저장한다.
저장공간에 실제 자료값을 가진다.

참조형 타입(Reference Type)

8가지 기본형 타입을 제외한 나머지 모두로, 클래스와 배열, 열거 타입, 인터페이스 모두 참조형이다.
타입
기본값
할당되는 메모리 크기
배열(Array)
Null
4 byte(주소값 저장)
열거(Enumeration)
Null
4 byte(주소값 저장)
클래스(Class)
Null
4 byte(주소값 저장)
인터페이스(interface)
Null
4 byte(주소값 저장)
기본형과 달리 실제 값이 저장되지 않고, 자료가 저장된 공간의 주소를 저장한다.
힙(heap)에 실제 값을 저장하고, 스택에는 그 참조값(주소값)을 갖는 변수를 저장한다.
null 값을 가질 수 있다.

기본형의 타입 변환(Type Conversion)

byte에서 int로 바꾸는 것처럼 하나의 타입을 다른 타입으로 바꾸는 것을 타입 변환 혹은 형변환이라 한다.
프로그램에서 값 대입이나 연산은 같은 타입끼리만 가능한데, 같은 정수라도 타입이 다르면 연산을 수행하기 전에 같은 타입으로 만들기 위해 형변환 작업을 해야한다.
크기가 작은 타입에서 큰 타입으로 타입 변환은 생략 가능하지만, 큰 타입에서 작은 타입으로의 타입 변환은 데이터 손실이 발생하기 때문에 자바 컴파일러가 오류를 발생 시킨다.
자바 형변환 방법은 묵시적(자동) 형변환명시적(강제) 형변환 두 가지가 있다.

자동 형변환(Promotion)

자동 타입 변환 혹은 자동 형변환은 묵시적/암시적 형변환이라고도 불리며, 프로그램 실행 도중에 컴파일러가 자동으로 타입을 변환하는 형변환을 말한다.
작은 크기를 가지는 타입이 큰 크기를 가지는 타입에 저장될 때만 자동 타입 변환이 발생한다.
기존의 값을 최대한 보존할 수 있는 큰 타입으로 변환할 때 자동 형변환이 가능하다고 이해할 수 있다.
여기서 주의깊게 봐야할 것은 long과 float 타입인데, long은 8바이트고 float은 4바이트지만 실제 값의 범위가 정수형 표현인 long보다 부동 소수점 표현인 float이 더 크기 때문에 long에서 float으로 자동 형변환이 된다.
또한 byte 타입은 1바이트이고 char 타입은 2바이트지만, 실제 byte 타입을 char 타입에 저장할 수 없다. 그 이유는 char 타입은 유니코드와 아스키코드를 모두 표현할 목적으로 설계되어 음수를 표현할 수 없기 때문이다. 때문에 byte 타입은 short 타입에는 저장할 수 있지만, char 타입에는 저장할 수 없다.
연산식 자동 형변환
데이터 연산은 기본적으로 같은 타입의 피연산자 간에만 수행되기 때문에, 서로 다른 타입의 피연산자가 있다면 큰 타입으로 자동 형변환된 후 연산을 수행한다.
위 그림처럼 int 타입과 double 타입을 연산을 수행하면 double 타입으로 자동 형변환이 되기 때문에, result1처럼 int 타입이 기대되지만 double 타입이 들어온다는 오류를 알려준다.
자바는 피연산자를 4바이트 단위로 저장하기 때문에, 정수 연산일 경우 int 타입을 기본으로 한다.
그런 이유로 위와 같이 byte나 char 타입끼리 연산하더라도 자동으로 int 타입으로 형변환되어 계산된다.

강제 형변환(Casting)

캐스팅(casting) 혹은 강제 형변환은 명시적 형변환이라고 불리며, 사용자가 타입 캐스트 연산자를 사용하여 값의 타입을 강제적으로 변환하는 것을 말한다.
작은 타입에서 큰 타입으로는 자동 형변환이 되지만 그 반대의 경우에는 자동 타입 변환을 할 수 없기 때문에, 필요에 의해 작은 타입으로 처리해주어야 한다면 강제 형변환을 수행해야 한다.
크기가 큰 타입에서 작은 타입으로 진행되는 형변환이기 때문에, 경우에 따라 데이터의 손실이 발생할 수 있다.
int num = 60000; byte value = (byte)num; // 데이터 손실 발생 : 96 int num2 = 10; byte value2 = (byte)num2; // 데이터 손실 X : 10
Java
복사
데이터 손실을 감수한다면, 기본 자료형 중 boolean을 제외한 모든 자료형은 형변환이 가능하다.
실수 타입과 정수 타입 간의 형변환
실수 타입을 정수 타입으로 강제 형변환하면 소수점 이하의 데이터들은 버려진다.
double num = 12.3456; int num2 = (int)num; // 12
Java
복사
강제 형변환의 데이터 손실 외에도 실수 타입과 정수 타입 간에 형변환에는 부동 소수점으로 인한 오차가 발생한다.
int num1 = 123456780; float num2 = num1; // 1.23456784 * e8 int num3 = (int)num2; // 123456784 int result = num1 - num3; // -4
Java
복사
강제 형변환의 데이터 손실을 방지하기 위해, 자바에서는 형변환 안전장치로 코드 데이터를 검사하기 위한 모든 데이터 타입의 최대값과 최소값을 상수로 제공한다. 이를 통해 형변환 전에 최소값과 최대값을 벗어나는지 검사하여 데이터 손실 방지를 위한 타입 변환 가드를 할 수 있다.
int i = 128; if ((i < Byte.MIN_VALUE) || (i > Byte.MAX_VALUE)) { System.out.println("타입 캐스팅 할 수 없음"); } else { byte b = (byte)i; System.out.println(b); }
Java
복사