- '상수(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 |