[Java의 정석] 상수와 리터럴(constant & literal) (1)

말하는 감자·2023년 10월 9일
0

Java의 정석

목록 보기
11/32
post-thumbnail
post-custom-banner

Chapter 02 변수(Varialbe)

2. 변수의 타입

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

'상수(constant)'는 변수와 마찬가지로 '값을 지정할 수 있는 공간'이지만, 변수와 달리 한번 값을 저장하면 다른 값으로 변경할 수 없다. 상수를 선언하는 방법은 변수와 동일하며, 단지 변수의 타입 앞에 키워드 final을 붙여주면 된다.

fianl int MAX_SPEED = 10; // 상수 MAX_SPEED를 선언 & 초기화

상수는 반드시 선언과 동시에 초기화해야 하며, 그 후 부터는 상수의 값을 변경해선 안된다.

final int MAX_SPEED;       // 에러. 상수는 선언과 동시에 초기화해야함
final int MAX_SPEED = 100; // OK. 선언과 동시에 초기화 했음
MAX_SPEED = 100;           // 에러. 상수의 값은 변경할 수 없음

상수의 이름은 모두 대문자로 하는 것이 암묵적인 관례이며 여러 단어로 이루어져있는 경우 '_'로 구분한다.

💡 JDK1.6부터 상수를 선언과 동시에 초기화 하지 않아도 되며, 사용하기 전에만 초기화하면 되도록 바뀌었다. 그래도 상수는 선언과 동시에 초기화하는 것이 좋다.

📍 리터럴(literal)

원래 12, 123, 3.14, 'A'와 같은 값들이 '상수'인데, 프로그래밍에서는 사수를 '값을 한 번 저장하면 변경할 수 없는 저장공간'으로 정의하였기 때문에 이와 구분하기 위해 상수를 다른 이름으로 불러야만 했다. 그래서 상수 대신 리터럴이라는 용어를 사용한다. 즉, 리터럴은 우리가 기존에 알고 있던 '상수'의 다른 이름이다.

변수(variable) 하나의 값을 저장하기 위한 공간
상수(constant) 값을 한번마 저장할 수 있느 공간
리터럴(literal) 그 자체로 값을 의미하는 것

int year = 2014;
final int MAX_VALUE = 100;

변수와 상수와 리터럴

📍 상수가 필요한 이유

int triangleArea = (20 + 10) / 2; // 삼각형의 면적을 구하는 공식
int rectangleArea = 20 * 10;      // 사각형의 면적을 구하는 공식

위의 코드는 삼격형과 사각형의 면적을 구해서 변수에 저장한다. 이 공식보다 복잡한 공식이라면 사용된 숫자가 무엇을 의미하는지 파악하기 어려울 것이다. 게다가 20과 10이 아닌 다른 값을 이용해서 결과를 얻고 싶다면 여러 곳을 수정해야한다.

final int WIDTH = 20;  // 폭
final int HEIGHT = 10; // 높이

int triangleArea = (WIDTH + HEIGHT) / 2; // 삼각형의 면적을 구하는 공식
int rectangleArea = WIDTH * HEIGHT;      // 사각형의 면적을 구하는 공식

상수를 이용해서 기존의 코드를 변경했더니 이전 코드에 비해 면적을 구하는 공식의 의미가 명확해졌다. 그리고 다른 값으로 계산할 때도 여러 곳을 수정할 필요없이 상수의 초기화만 다른 값으로 해주면 된다.

이처럼 상수는 리터럴에 '의미있는 이름'을 붙여서 코드의 이해와 수정을 쉽게 만든다.

📍 리터럴의 타입과 접미사

변수에 타입이 있는 것처럼 리터럴에도 타입이 있다. 변수의 타입은 저장될 '값의 타입(리터럴의 타입)'에 의해 결정되므로, 만일 리터럴에 타입이 없다면 변수의 타입도 필요 없을 것이다.
리터럴과 접미사
정수와 실수형에는 여러 타입이 존재하므로, 리터럴에 접미사를 붙여서 타입을 구분한다. 정수형의 경우 long타입의 리터럴 'l' 또는 'L'을 붙이고, 접미사가 없으면 int타입의 리터럴이다. byteshort타입의 변수에 값을 저장할 때는 int타입의 리터럴을 사용한다.
10진수 외에도 2, 8, 16진수로 표현된 리터럴을 변수에 저장할 수 있으며, 16진수라는 것을 표시하기 위해 리터럴 앞에 접두사 '0x' 또는 '0X'를, 8진수의 경우에는 '0'을 붙인다. 2진 리터럴은 JDK 1.7부터 추가되었다.

int octum = 010;   // 8진수 10, 10진수로 8
int hexNum = 0x10; // 16진수 10, 10진수로 16
int binNum = 0b10; // 2진수 10, 10진수로 2

JDK 1.7부터 정수형 리터럴의 중간에 구분자 '_'를 넣을 수 있게 되어서 큰 숫자를 편하게 읽을 수 있게 되었다.

long big = 100_000_000_000L;      // long big = 100000000000L;
long hex = 0xFFFF_FFFF_FFFF_FFFFL // long hex = 0xFFFFFFFFFFFFFFFFL;

실수형에서느 float타입의 리터럴에 접미사 'f' 또는 'F'를 붙이고 double타입의 리터럴에는 접미사 'd' 또는 'D'를 붙인다.

float pi = 3.14f;     // 접미사 f 대신 F를 사용해도 된다.
double rate = 1.618d; // 접미사 d 대신 D를 사용해도 된다.

실수형 리터럴에는 접미사를 붙여서 타입을 구분하며, float타입 리터럴에는 'f'를, double타입 리터럴에는 'd'를 붙인다. 정수형에는 int가 기본 자료형인 것처럼 실수형에서는 double이 기본 자료형이라서 접미사 'd'는 생략 가능하다. 실수형 리터럴인데 접미사가 없으면 double티입 리터럴인 것이다.

float pi = 3.14; // 에러. float타입 변수에 double타입 리터럴 저장불가.
double rate = 1.618; // OK. 접미사 d는 생략할 수 있다.

위의 문장에서 3.14는 접미사가 붙지 않았으므로 float타입 리터럴이 아니라 double타입 리터럴로 간주된다. 그래서 3.14float타입의 범위에 속한 값임에도 불구하고 컴파일 시에 에러가 발생한다. 3.14f와 같이 접미사를 붙여야 한다.
리터럴의 접두사와 접미사는 대소무자를 구별하지 않으므로 대문자와 소문자 중에서 어떤 것을 사용해도 상관없지만 소문자 'l'의 경우 숫자 '1'과 헷갈리기 쉬우므로 대문자 'L'을 사용하는 것이 좋다.

💡 리터럴에 접미사가 붙는 타입은 long, float, double뿐인데, double은 생략가능하므로 longfloat의 리터럴에 접미사를 붙이는 것만 신경쓰면 된다.

리터럴에 소수점이나 10의 제곱을 나타내는 기호 E 또는 e, 그리고 접미사 f, F, d, D를 포함하고 있으면 실수형 리터럴로 간주된다.
실수형 리터럴의 예

잘 쓰이지는 않지만 기호 p를 이용해서 실수 리터럴을 16진 지수형태로 표현할 수도 있다. p는 2의 제곱을 의미하며, p의 왼쪽에는 16진수를 적고 오른쪽에는 지수를 10진 정수로 적는다. p는 대소문자 모두 가능하며, p가 포함된 리터럴은 실수형이다.


📑 원본 자료

  • Java의 정석(3판) [남궁 성/도우출판/2016]
profile
나는 말하는 감자다
post-custom-banner

0개의 댓글