상수(Constant)라는 것은 변하지 않는 수
를 의미합니다.
이 상수로 표현하기 위해 자료형 앞에 final 예약어를 사용합니다.
하지만 이 상수라는 것은 왜 사용하는 것일까요?
final 예약어를 통해 상수로 표현하면 의미있는 문자로 인식하기 쉽고 변하더라도 선언한 부분만 변경하면 되기 때문에 여러 부분을 수정할 필요가 없습니다.
아래의 코드와 같이 표현할 수 있습니다.
final int MAX = 12345678;
System.out.println(MAX);
// MAX = 100; (에러 발생)
먼저, 상수로 표현하기 위해 변수명은 대문자로 작성하는 것이 규칙입니다. 그리고 final 예약어를 지정한 변수에 값을 저장 후 다시 값을 수정할 수 없습니다.(위에서 말했듯이 상수는 변하지 않는 수이기 때문에 수정할 수 없습니다.)
리터럴(Literal)은 프로그램에서 사용하는 숫자, 문자, 논리 값
을 뜻합니다.
int number = 10; // 변수 number에 저장된 값 10이 리터럴을 뜻합니다.
여기에 정수 리터럴과 실수 리터럴로 구분하며, 정수 리터럴은 int 형으로 실수 리터럴은 double 형으로 저장됩니다.
프로그램을 사용하다 보면 모든 자료형이 동일한 크기는 아닙니다.
만약, 두 연산을 할 때, 하나는 int형 다른 하나는 float 형으로 크기가 다를 수 있습니다.
형을 맞춰서 계산해야 하기 때문에 형 변환이 발생합니다.
즉, 서로 다른 자료형 간에 연산 등의 수행을 위해 하나의 자료형으로 통일하는 것을 말합니다.
여기에 묵시적 형 변환(Explicit Type Conversion)과 명시적 형 변환(Implicit Type Conversion)으로 구분할 수 있습니다.
예를 들어, 다음과 같이 코드로 작성할 수 있습니다.
/* 묵시적 형 변환(자동 형 변환)
크기가 작은 자료형 -> 큰 자료형으로 형 변환
*/
byte bNum = 10;
int iNum = bNum;
/*
int형이 float 형으로 자동 형 변환
*/
int iNum1 = 20;
float fNum = iNum1;
/*
명시적 형 변환(강제 형 변환)
*/
int iNum2 = 10;
byte bNum2 = (byte) iNum2;
double dNum = 3.14;
int iNum3 = (int) dNum;
하지만 다음과 같이 명시적 형 변환 경우는 잘못된 값을 반환할 수 있습니다.
int iNum = 255;
byte bNum = (byte) iNum;
system.out.println(bNum);
// 결과
-1
int 형을 byte 형으로 강제적으로 형 변환하는데, byte형이 갖고 있는 값의 범위보다 크면 오버플로우가 발생하여 -1이 출력하게 됩니다.
형 변환을 통해 다음과 같이 계산할 수 있습니다.
double dNum = 1.2;
float fNum = 0.9f;
int value1 = (int)dNum + (int)fNum;
int value2 = (int)(dNum + fNum);
System.out.println(value1);
System.out.println(value2);
각각 결과는 어떤식으로 나올까요?
1
2
value1의 경우는 dNum과 fNum을 각각 강제적으로 int형으로 변환하면서 자료가 유실되어 1 + 0
이 되어 1이 출력이 됩니다.
value2의 경우는 dNum과 fNum을 먼저 연산하는데, 묵시적으로 더 정밀한 자료형인 double형으로 형 변환되어 1.2 + 0.9
로 계산되어 2.1
이 된 상태에서 int형으로 강제적으로 형 변환시켰기 때문에 소수점은 없어지고 2가 출력이 됩니다.
이상 간단하게 상수와 리터럴, 형 변환에 대해서 알아봤습니다.