[Java] 변수와 자료형 - 상수와 리터럴, 형 변환

나영원·2020년 8월 24일
0

Java_basic

목록 보기
6/60

상수 (constant)와 리터럴(literal)

상수는 변하지 않는 수로 앞에 파이널이란 키워드를 사용하여 선언합니다.

리터럴은 프로그램내에서 사용되는 모든 숫자, 값, 논리 값을 나타내는 말입니다.

ex) 10, 3.15, 'A', ture 등 우리가 사용하는 모든 '값'
그림과 같이 모든 리터럴은 상수 풀에 저장 되어있습니다. 리터럴이 상수풀에 저장 될 때 정수는 int, 실수는 double로 저장되고 그범위를 넘어가는 수는 따로 식별하여 다른 자료형으로 저장합니다. 그 후 프로그램에서 값이 필요 할 때 상수풀에서 꺼내서 사용합니다. 이것을 통해서 우리가 정수 혹은 실수형 변수를 선언할때 int혹은 double이 아닌 경우 추가 부호를 붙여야 하는 이유가 알 수 있습니다.(리터럴이 상수 풀에 그런 형태로 저장되어 있는걸 변수에서 복사해서 사용하는 것이기에)

형 변환

변수마다 자료형이 다르고 자료형마다 서로 사용하는 메모리 방식도 다르기 때문에 프로그램내에서 서로 다른 자료형의 값이 대입되는 경우 형변환이 일어납니다.

묵시적인 형변환(implicit type conversion)은 작은수 => 큰수, 덜 정밀한 수 => 더 정밀한 수 로 대입되는 경우에 일어나는 형변환으로 자동으로 형변환이 됩니다. 아래 그림에서 화살표 방향으로 일어나는 형변환들이 묵시적 형변환 입니다.
명시적인 형변환(explicit type conversion)은 작은수 <= 큰수, 덜 정밀한 수 <= 더 정밀한 수 로 대입되는 경우에 일어나는 형변환으로 묵시적인 형변환과 다르게 타입 캐스팅을 표시해주어 프로그래머가 자료의 손실이 발생할 수 있다는것을 인지하고 있음을 알려주어야 일어나는 형변환 입니다.(명시적인 형변환은 자료의 손실이 일어날 수 있다는 뜻을 내포합니다.) 위에 그림에서 화살표 반대방향으로 일어나는 형변환 입니다.

예제)

묵시적 형변환

public class ImplicitConversion {

	public static void main(String[] args) {

		byte bNum = 10;
		int iNum = bNum;
		
		System.out.println(bNum); // 10
		System.out.println(iNum); // 10
		
		int iNum2 = 20;
		float fNum = iNum2; 
		
		System.out.println(iNum2); //20
		System.out.println(fNum); //20.0
		
		double dNum;
		dNum = fNum + iNum;
		
		System.out.println(dNum); //30.0
		
	}

}

byte => int 로 대입될때 자동으로 형변환 되어 10이라는 값이 출력되었습니다.

int => float으로 대입될때 정수에서 실수라는 자료형 차이가 있지만 덜 정밀한 수에서 더 정밀한 수로 대입되는 개념으로 묵시적인 형변환이 일어나서 20.0이라는 값이 출력되었습니다.

dNum = fNum + iNum; 부분에서 대입연산자는 가장 나중에 연산이 되기 때문에 먼저 iNum(int)이 float 으로 형변환되어서 fNum과 합연산이 일어나고 그다음 합쳐진 float값이 double로 형변환되서 dNum에 대입됩니다.(2번의 묵시적 형변환이 일어났습니다.)

명시적 형변환

public class ExplicitConversion {

	public static void main(String[] args) {

		int i = 1000;
		byte bNum = (byte)i;
		
		System.out.println(bNum); // -24
		
		double dNum1 = 1.2;
		float fNum = 0.9F;
		
		int iNum1 = (int)(dNum1 +fNum);
		int iNum2 = (int)dNum1 +(int)fNum;
		
		System.out.println(iNum1); // 2
		System.out.println(iNum2); // 1
	}

}

int 값에 byte를 캐스팅( (byte)i 와 같이 값 앞에 괄호안에 자료형을 써주는것을 타입 캐스팅이라고 합니다.)해서 byte 값으로 명시적 형변환을 했더니 byte의 범위를 넘어선 값이 대입되어 데이터 유실이 발생하여 -24라는 음수가 나왔습니다. 이런 데이터 유실의 발생을 프로그래머가 인지 한다는 뜻에서 명시적인 형변환을 하는 것 입니다.

iNum1은 먼저 실수 값을 더한후 int로 형변환을 한것이기에 1.2 + 0.9 = 2.1에 정수로 형변환하면서 소수점을 버리는 효과가 일어나 정수 2라는 결과가 나왔습니다. 이와 다르게 iNum2에서는 두 실수를 먼저 정수로 형변환하여 소수점을 버리고 이후에 더했기 때문에 1.0 + 0 = 1라는 다른 결과가 나오게 됩니다. 이를 통해 우리는 형변환을 언제 하느냐에 따라 결과 값이 다를 수 있다는 것을 알 수 있습니다.

2진수, 8진수, 16진수

public class BinaryTest {

	public static void main(String[] args) {
		
		int num = 10;
		int bNum = 0B1010;
		int oNum = 012;
		int xNum = 0XA;
		
		System.out.println(num); //10
		System.out.println(bNum); //10
		System.out.println(oNum); //10
		System.out.println(xNum); //10
	}

}

위에 예제처럼 10진수 외에 다른 진수도 앞에 각 진수에 해당하는 부호를 넣음으로 사용할 수 있음을 알 수 있습니다.

profile
배우는 개발 일기

0개의 댓글