Back-end/JAVA

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

peridott 2026. 1. 12. 18:39
  • '상수(constant)'는 변수와 마찬가지로 '값을 저장할 수 있는 공간'이지만, 변수와 달리 한 번 값을 저장하면 다른 값을 변경할 수 없다.
  • 상수를 선언하는 방법은 변수와 동일하며, 단지 변수의 타입 앞에 키워드 'final'을 붙여주기만 하면 된다.
final int MAX_SPEED = 10;	// 상수 MAX_SPEED를 선언 & 초기화
  • 상수는 반드시 선언과 동시에 초기화해야 하며, 그 후 부터는 상수의 값을 변경하는 것이 허용되지 않는다.
final int MAX_SPEED;		// 에러. 상수는 선언과 동시에 초기화해야 함.
final int MAX_VALUE = 100	// OK. 선언과 동시에 초기화 했음.
MAX_VALUE = 200;		// 에러. 상수의 값은 변경할 수 없음.
  • 상수의 이름은 모두 대문자로 하는 것이 암묵적인 관례
  • 여러 단어로 이루어져 있는 경우 '_'로 구분한다.

리터럴(literal)

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

 

상수가 필요한 이유

  • '그냥 리터럴을 직접 쓰면 될 텐데, 굳이 상수가 따로 필요한가?'라는 의문이 들 것도 같다. 먼저 다음의 코드를 보자.
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;			// 사각형의 면적을 구하는 공식
  • 상수를 이용해서 기존의 코드를 변경한 것인데, 이전 코드에 비해 면적을 구하는 공식의 의미가 명확해졌다.
  • 다른 값으로 계산할 때도 여러 곳을 수정할 필요없이 상수의 초기화만 다른 값으로 해주면 된다.
  • 이처럼 상수는 리터럴에 '의미있는 이름'을 붙여서 코드의 이해와 수정을 쉽게 만든다.

리터럴의 타입과 접미사

  • 변수에 타입이 있는 것처럼 리터럴에도 타입이 있다.
  • 변수의 타입은 저장될 '값의 타입(리터럴의 타입)'에 의해 결정되므로, 만일 리터럴에 타입이 없다면 변수의 타입도 필요없을 것이다.
종류 리터럴 접미사
논리형 false, true 없음
정수형 123,0b0101,077, 0xFF, 100L L
실수형 3.14, 3.0e8, 1.4f, 0x1.0p-1 f, d
문자형 'A', '1', '\n' 없음
문자열 "ABC", "123", "A", "true" 없음
  • 정수형과 실수형에는 여러 타입이 존재하므로, 리터럴에 접미사를 붙여서 타입을 구분한다.
  • 정수형의 경우, long타입의 리터럴의 접미사 'l' 또는 'L'을 붙이고, 접미사가 없으면 int타입의 리터럴이다.
  • byte와 short타입의 리터럴은 별도로 존재하지 않으며 byte와 short타입의 변수에 값을 저장할 때는 int타입의 리터럴을 사용한다.
  • 10진수 외에도 2, 8, 16진수로 표현된 리터럴을 변수에 저장할 수 있으며, 16진수라는 것을 표시하기 위해 리터럴 앞에 접두사'0x' 또는 '0X'를, 8진수의 경우에는 '0'을 붙인다.
int octNum = 010;		// 8진수 10, 10진수로 8
int hexNum = 0x10;		// 16진수 10, 10진수로 16
int binNum = 0b10;		// 2진수 10, 10진수로 2
  • JDK1.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를 사용해도 된다.
  • 정수형에서는 int가 기본 자료형인 것처럼 실수형에서는 double이 기본 자료형이라서 접미사 'd'는 생략이 가능하다.

타입의 불일치

  • 리터럴의 타입은 저장될 변수의 타입과 일치하는 것이 보통이지만, 타입이 달라도 저장범위가 넓은 타입에 좁은 타입의 값을 저장하는 것은 허용된다.
int i = 'A'		// OK. 문자 'A'의 유니코드인 65가 변수 i에 저장된다.
long l = 123;		// OK. int보다 long타입이 더 범위가 넓다.
double d = 3.14f	// OK. float보다 double타입이 더 범위가 넓다.
  • 그러나 리터럴의 값이 변수의 타입의 범위를 넘어서거나, 리터럴의 타입이 변수의 타입보다 저장범위가 넓으면 컴파일 에러가 발생한다.
int i = 0x123456789;		// 에러. int 타입의 범위를 넘는 값을 저장
float f = 3.14;			// 에러. float 타입보다 double 타입의 범위가 넓다.
  • 3.14는 3.14d에서 접미사가 생략된 것으로 double타입이다. 이 값을 float타입으로 표현할 수 있지만, double타입의 리터럴이므로 float타입의 변수에 저장할 수는 없다.
  • float는 접미사나 정밀도 등 신경 쓸 것이 많다. 이런 것들이 귀찮다면 그냥 double을 사용하자.
  • byte와 short타입의 리터럴은 따로 존재하지 않으므로 int타입의 리터럴을 사용한다. 단, short타입의 변수가 저장할 수 있는 범위에 속한 것이어야 한다.
byte b = 65;		// OK. byte타입에 저장 가능한 범위의 int타입 리터럴
short s = 0x1234;	// OK. short타입에 저장 가능한 범위의 int타입 리터럴
  • 각 타입의 저장범위만 알아도 충분히 판단가능한 내용이다.
  • 값의 크기에 상관없이 double 타입의 리터럴을 float타입의 변수에 저장할 수 없다는 것만 주의하자.

문자 리터럴과 문자열 리터럴

  • 'A'와 같이 작은따옴표로 문자 하나를 감싼 것을 '문자 리터럴'이라고 한다.
  • 두 문자 이상은 큰 따옴표로 감싸야 하며 '문자열 리터럴'이라고 한다.
    • 문자열은 '문자의 연속된 나열'이라는 뜻이며, 영어로 'string'이라고 한다.
char ch = 'J';			// char ch = 'Java'; 이렇게 할 수 없다.
String name = "java";		// 변수 name에 문자열 리터럴 "java"를 저장
  • char타입의 변수는 단 하나의 문자만 저장할 수 있으므로, 여러 문자(문자열)를 저장하기 위해서는 String타입을 사용해야 한다.
  • 문자열 리터럴은 ""안에 아무런 문자도 넣지 않는 것을 허용하며, 이를 빈 문자열(empty string)이라고 한다.
  • 그러나 문자 리터럴은 반드시 ''안에 하나의 문자가 있어야 한다.
String str = "";		// OK. 내용이 없는 빈 문자열
char ch = '';			// 에러. ''안에 반드시 하나의 문자가 필요
char ch = ' ';			// OK. 공백 문자(blank)로 변수 ch를 초기화
  • 원래 String은 클래스이므로 아래와 같이 객체를 생성하는 연산자 new를 사용해야 하지만 특별히 위와 같은 표현도 허용한다.
String name = new String("Java");	// String객체를 생성
  • 덧셈 연산자를 이용하여 문자열을 결합할 수 있다.
String name = "Ja" + "va";		// name은 "Java"
String str = name + 8.0;		// str은 "Java8.0"
  • 덧셈 연산자(+)는 피연산자가 모두 숫자일 때는 두 수를 더하지만, 피연산자 중 어느 한 쪽이 String이면 나머지 한 쪽을 먼저 String으로 변환한 다음 두 String을 결합한다.
  • 기본형과 참조형의 구별 없이 어떤 타입의 변수도 문자열과 덧셈연산을 수행하면 그 결과가 문자열이 되는 것이다.
  • 예를 들어 7 + "7"을 계산할 때 7이 String이 아니므로, 먼저 7을 String으로 변환한 다음 "7" + "7"을 수행하여 "77"을 결과로 얻는다.
7 + " " → "7" + " " → "7 "
" " + 7 → " " + "7" → " 7"

7 + "7" → "7" + "7" → "77"

7 + 7 + "" → 17 + "" → "14" + "" → "14"
"" + 7 → 7 → "7" + 7 → "7" + "7" → "77"

true + "" → "true" + "" → "true"
null + "" → "null" + "" → "null"
  • 덧셈 연산자는 왼쪽에서 오른쪽의 방향으로 연산을 수행하기 때문에 결합순서에 따라 결과가 달라진다는 것에 주의하자.
  • 7과 같은 기본형 타입의 값을 문자열로 변환할 때는 아무런 내용도 없는 빈 문자열("")을 더해주면 된다는 것도 알아두자.

'Back-end > JAVA' 카테고리의 다른 글

2.4 화면에서 입력받기 - Scanner  (0) 2026.01.27
2.3 형식화된 출력 - printf()  (0) 2026.01.16
2. 변수의 타입 - 2.1 기본형(primitive type)  (0) 2026.01.11
02. 변수  (0) 2026.01.10
1. 자바(Java Programming Language)  (0) 2026.01.09