본문 바로가기
Language/Java

[Java] 변수와 형변환

by 선서니 2023. 1. 28.

📌변수(Variable)이란?

뜻 그대로 해석을 하면 변할 수 있는 값으로 변할 수 있는 데이터이다.

이런 변수는 숫자나 문자와 같은 자료를 저장하기 위한 메모리 공간(그릇)으로 타입에 따라 변수가 가지는 크기가 달라진다.  변수를 사용할 때는 메모리 공간에 값을 할당 한 후 사용한다.

 


변수의 타입

변수의 타입은 기본형 참조형 두 가지로 나뉜다.

 

기본형(Primitive Type)

먼저 기본형은 미리 정해진 크기의 Memory Size로 표현하며 변수 자체에 값을 저장한다. 기본형은 총 8개의 종류가 있으며 논리형 / 정수형 / 실수형 / 문자형으로 구분할 수 있다.

  Type bit 수
논리형 boolean   true / false
정수형 byte 8 -2^7 ~ 2^7-1 (-128 ~ 127)
short 16 -2^15 ~ 2^15-1
(-32,768 ~ 32,767)
int 32 -2^31 ~ 2^31-1
(-2,147,483,648 ~ 2,147,483,647)
long 64 -2^63 ~ 2^63-1
(-9,223,372,036,854,775,808 ~ 9,223,372,036,854,775,807)
실수형 float 32 3.4 X 10^-38 ~ 3.4 X 10^38
double 64 1.7 X 10^-308 ~ 1.7 X 10^308
문자형 char 16 0 ~ 2^16-1

 

🙋‍♀️ 표에서 색이 다른 int와 dobule은 무엇을 나타내나요?
int와 double은 각각 정수와 실수에서 변수의 타입을 설정하지 않으면 기본적으로 설정되는 타입이다.

 

🙋‍♀️ byte는 8비트인데 왜 2의 7승까지만 처리하나요? (다른 정수형 타입들도!)
자바에서는 맨 앞의 한 비트를 부호비트로 사용하기 때문에 부호비트를 제외한 나머지 비트로 값을 표현

 

정수 계산과 오버플로우(overflow)

int가 표현할 수 있는 범위를 넘어섰기 때문에 오버플로우가 발생해서 가장 작은 수로 변하기 때문에 정수 계산 시 오버플로우에 주의해서 타입을 선택해야 한다.

int num1 = Integer.MAX_VALUE;
int num2 = num1+1;

System.out.println(num2); // -2147483648

 

 

참조형(Reference Type)

크기가 미리 정해질 수 없는 데이터를 표현한다. 실제 값은 메모리 어딘가에 저장되어 있으며 이를 참조할 수 있는 주소만을 변수에 저장한다. (그래서 참조형!)

 

참조형은 기본형 8개를 제외한 모든 타입을 참조형이라고 한다. (String, Object ...)


📌 형 변환(Type casting)이란?

변수의 타입을 다른 타입으로 변환하는 것을 형 변환이라고 한다. 예를 들어 int라는 변수의 데이터 타입을 필요에 따라 double로 바꾸거나 long으로 바꾸거나 하는 것을 말한다. 

 

이런 형 변환은 기본형은 기본형끼리만 가능하며 참조형은 참조형끼리 가능하다. 하지만 기본형 중에서도 boolean 타입은 다른 기본 타입과 호환이 되지 않는다. 

 

🙋‍♀️ 그럼 기본형과 참조형은 형 변환 할 수 없는건가요?
자바에서는 이를 지원하기 위해 Wrapper 클래스라는 것을 제공한다. Wrapper 클래스는 기본형을 객체화 한 것으로 이를 이용하면 기본형과 차조형을 형 변환 할 수 있다.

 

형 변환 방법

형변환 연산자인 (괄호) 를 사용하며 (데이터 타입) 데이터 값 형식으로 표현한다.

byte b = 10;
int i = (int)b; //byte타입을 int 타입으로 형변환

 

형 변환 종류

형 변환을 나눠보면 이렇게 두 가지가 있다.

1. 표현 범위가 좁은 타입  -> 표현 범위가 넓은 타입으로 형 변환
2. 표현 범위가 넓은 타입  -> 표현 범위가 좁은 타입으로 형 변환 

 

묵시적 형 변환

형 변환의 1번에 해당한다. 표현 범위가 좁은 타입에서 표현 범위가 넓은 타입으로 변환되기 때문에 내부적으로 자료가 손실될 걱정이 없다. 마치 작은 그릇에 있던 물을 큰 그릇으로 옮기는 것과 같다. 

그렇기 때문에 프로그래밍의 편의성을 위해서 JVM은 이런 형식의 형 변환은 자동으로 서비스 해준다. 

byte b = 10;
int i = (int)b; //byte타입을 int 타입으로 형변환
int i2 = b; // 형변환을 명시하지 않아도 byte타입이 int타입으로 형변환 됨 - 묵시적 형 변환

 

그래서 기본형 타입들의 묵시적 형 변환이 가능한 방향을 이렇게 그려볼 수 있다.

이 때, 값의 크기나 타입의 크기가 기준이 아니라 타입의 표현 범위가 커지는 방향으로 형 변환을 했을 때 묵시적 형변환이 발생한다.

 

🙋‍♀️ short도 2바이트, char도 2바이트인데 왜 char과 short는 묵시적 형 변환이 안되는 건가요?
short는 부호가 있기 때문에 음수와 양수를 모두 표현 할 수 있지만, char는 양수만 표현이 가능하기 때문에 자동으로 되지 않아 반드시 명시를 해줘야 한다.

 

 

명시적 형 변환

형 변환의 2번이다. 표현 범위가 넓은 타입에서 표현 범위가 좁은 타입으로 변환되기 때문에 내부적으로 자료가 손실된다. 물 그릇으로 얘기하자면 큰 그릇에 있던 물을 작은 그릇으로 옮기는 거다. 옮길 때 물이 흘러서 넘치는 게 자료가 손실되는 것과 같다고 말할 수 있을 것 같다.

 

이렇게 값 손실의 위험이 있을 때는 프로그래머의 책임하에 명시적으로 형 변환을 진행하며 형변환 연산자를 생략해서는 안된다. 

float f = 3.14f;
int i = (int) f; // int타입으로 float 타입을 형 변환

System.out.println(f); // 3.14
System.out.println(i); // 3

이 코드처럼 실수형 타입인 float 타입을 정수형 타입인 int 타입으로 명시적 형 변환을 했을 때 소수점은 손실되고 정수만 남아 있는 것을 볼 수 있다.

 

 

형 변환 시 주의할 점

 

위와 같이 코드를 적었을 때 에러가 발생하는 걸 볼 수 있다. 에러의 내용은 int를 byte로 형 변환 할 수 없다는 것이다.

10이 byte의 범위를 벗어나지도 않았고 명시적 형 변환 예제에 있었던 아래 코드를 보면 같은 int형 타입의 10을 byte에 대입하는데 묵시적 형변환이 잘 되고 있는 것을 알 수 있다.

byte b = 10;

 그럼 에러는 무슨 이유 때문일까?

 

이전의 예시와 다른 점은 byte로 형 변환하려고 하는 값(여기서는 10)이 리터럴(상수)인가 아닌가 이다.

이전 예시의 10은 상수로 변하지 않는 값이다. 하지만 현재 예시는 10을 값으로 가지고 있는 int형 변수를 묵시적 형 변환을 하려고 하고 있다. 

 

컴파일러 입장에서는 변수에 들어 있는 값을 확신할 수 없기 때문에 byte 표현 범위보다 더 큰 표현 범위를 가지는 int형 변수를 형 변환하려고 했을 때 묵시적 형 변환을 진행하지 않고 에러를 표시하는 것이다. 

 

그래서 이 경우에는 명시적 형 변환을 해줘야 하며 이렇게 수정할 수 있다.


참고

 

형변환 연산자, 자동 형변환

형변환 연산자 형변환이란? 변수또는 상수의 타입을 다른 타입으로 변환하는 것 바꾸는 방법은 쉽다. (타입)피연산자 이러한 형태로 피연산자 앞에다가 괄호안에 바꿀 타입을 적어주기만 하면

mgyo.tistory.com

 

Wrapper Class 이란?

이번 글은 Wrapper Class 에 대한 개념과 사용 이유에 대해 정리해 보려고 합니다. 'wrapper'라는 말의 의미는 '감싼' 이라는 뜻으로 랩으로 음식을 감싸는 이미지를 생각하시면 될것 같습니다. 그럼 이

jminc00.tistory.com

 

'Language > Java' 카테고리의 다른 글

[Java] 배열  (0) 2023.01.29
[Java] 연산자와 조건문/반복문  (0) 2023.01.28

댓글