[Java] 변수와 상수
변수와 메모리
프로그래밍에서 변수는 코드 중간에 그 값이 변할 수 있는 것을 의미한다. 변수에는 선언과 할당이 있다. 선언 시에는 그 변수의 자료형을 먼저 명시하고 변수명을 작성하는 방식이다.
short num;
선언과 동시에 해당 변수에 값을 할당하는 것도 가능하다.
short num = 1;
만약 코드 전반에 걸쳐 선언만 하고 할당을 하지 않고 그 변수를 참조하려한다면 에러가 발생한다.
public class App {
public static void main(String[] args)
{
short number;
System.out.println(number);
}
}
Exception in thread "main" java.lang.Error: Unresolved compilation problem:
The local variable number may not have been initialized
at App.main(App.java:5)
따라서 선언과 동시에 할당을 하지 않았다면, 그 변수를 참조하기 전에 반드시 그 변수에 값을 할당해야 에러가 발생하지 않는다.
public class App {
public static void main(String[] args)
{
short number;
number = 1;
System.out.println(number);
}
}
1
한 편, 변수를 선언함과 동시에 값을 할당할 때 메모리에서 일어나는 일은 다음과 같다. 먼저, 해당 변수의 자료형을 파악하고, 그 자료형이 사용하는 메모리 공간을 확보한다. 위 예제의 number 변수의 경우, short 자료형을 사용하였으므로 2바이트의 메모리 공간을 확보한다. 그 후, 10진수로 표현되는 정수, 실수의 경우 이를 2진수로 변경하여 해당 메모리 공간에 저장하고, char 형의 경우 유니코드표를 이용하여 2진수로 변경하여 저장한다. 그 후, 해당 데이터가 저장된 2바이트 메모리가 시작되는 공간의 주소를 변수에 바인딩시킨다. 이로 인해, 사용자는 굳이 해당 데이터가 저장된 메모리 주소까지 알 필요없이, 해당 변수명만 알면 되는 것이다.
변수를 선언 및 할당하였다면 당연히 그 변수를 사용할 것이다. 위 예제의 경우,
System.out.println(number);
위 코드를 통해 변수 number를 참조하고 있다. 이 때 메모리 상에서는 다음의 일이 일어난다. 우선 해당 변수에 바인딩 된 메모리 주소값을 이용하여 해당 메모리의 시작 위치를 검색한다. 그 다음, 해당 변수의 자료형의 메모리 용량 크기, 그러니깐 이 경우 short 자료형의 크기 2바이트 만큼을 메모리 시작 위치로부터 읽어들인다. 그러면 해당 변수가 가리키는 데이터를 읽어올 수 있는 것이다. 메모리 공간에 저장된 2진수를 정수, 실수형의 경우 10진수로, char 형의 경우 유니코드표를 이용해 디코딩한 문자를 반환한다.
즉, 변수는 데이터를 메모리 공간에 저장할 때 그 메모리 공간 주소를 기억함과 동시에 해당 메모리 공간 주소를 이용하여 데이터를 참조하는 역할도 하는 것이다. 변수 덕분에 메모리 공간 주소 자체를 알아야 할 필요 없이 인간이 알아들을 수 있는 변수명을 이용하면 되는 것이다.
변수명 명명 규칙과 권장사항
자바에서 꼭 지켜야 하는 변수명 명명 규칙은 다음과 같다.
- 변수명은 숫자로 시작될 수 없다.
- $, _ 이외 다른 특수문자는 사용할 수 없다.
- public, int와 같이 이미 자바에서 정의된 키워드는 변수명으로 사용할 수 없다.
변수명 명명 시 권장 사항은 다음과 같다.
- 첫 글자는 소문자로 시작한다.
- 해당 변수에 할당된 데이터의 의미를 알 수 있는 이름으로 짓는다. 예를 들면 p = 3.14라 하면 모르겠지만, pi = 3.14라 하면 해당 데이터가 “파이”를 가리키는 것을 알 수 있는 것처럼 말이다.
- 두 영단어 이상을 이어 붙여 변수명으로 사용할 때 두 번째 단어부터 첫 글자를 대문자로 하는 카멜 표기법(camel case)을 사용하거나 (예: myNumber) 또는 언더 스코어(_)를 이어서 표기하는 스네이크 표기법(snake case)을 이용한다(예: my_number).
상수
수학에서 상수는 그 값이 변하지 않듯, 프로그래밍에서도 상수는 코드 실행 내내 바뀌지 않는 값을 의미한다. 자바에서는 “리터럴 상수”와 “final 상수”가 존재한다.
Literal
원래 리터럴(literal)의 영단어 뜻은 “문자 그대로”란 뜻이다. 즉, 1, 2, 3 등의 숫자, a, b, c 등의 알파벳과 문자, true, false 의 논리값들이 모두 리터럴에 해당한다. 숫자 1을 숫자 1이라고 생각하지 다른 의미로는 생각하지 않는 것처럼, 문자 그대로의 의미를 사용하는 값을 뜻한다.
리터럴 상수의 경우, 프로그램 실행 시 상수 풀(constant pool)이라는 특수 메모리 공간에 자동으로 호출된다. 그리고 이러한 리터럴 값을 코드 상에서 변수에 핟당하여 사용할 경우, 이 리터럴 값을 상수 풀로부터 복사하여 해당 변수에 할당하는 방식이다.
final
앞서 리터럴 상수는 사용자가 어찌할수 없는, 컴퓨터에 미리 정의된 값이라고도 볼 수 있다. 반면, 사용자가 상수를 정의하여 사용할 수도 있는데, 이 경우 final 상수를 이용하는 것이다. 사용법은, 변수 선언 시 자료형 앞에 final 키워드를 사용하며, 상수명은 모두 대문자로 작성하는 것이다. 이 경우, 카멜 표기법으로는 두 단어를 구분할 수 없기에 이 경우 스네이크 표기법을 이용하면 된다.
다음은 final 상수를 활용한 예제이다.
public class App {
public static void main(String[] args)
{
final double PI = 3.14;
final short MY_HEIGHT = 179;
System.out.println("만약 내 키를 원의 반지름으로 삼는다면?");
System.out.println("원의 둘레");
System.out.println(2 * PI * MY_HEIGHT);
System.out.println("원의 넓이");
System.out.println(PI * MY_HEIGHT * MY_HEIGHT);
}
}
만약 내 키를 원의 반지름으로 삼는다면?
원의 둘레
1124.1200000000001
원의 넓이
100608.74
이것도 상수이기에, 이미 한 번 할당된 값은 변경할 수 없다. 만약 변경하려고 시도하면 에러가 발생한다.
public class App {
public static void main(String[] args)
{
final double PI = 3.14;
final short MY_HEIGHT = 179;
MY_HEIGHT = 180; // 사실 이게 내 진짜 키야!
System.out.println(PI);
System.out.println(MY_HEIGHT); // 어딜 거짓말을!!
}
}
Exception in thread "main" java.lang.Error: Unresolved compilation problem:
The final local variable MY_HEIGHT cannot be assigned. It must be blank and not using a compound assignment
at App.main(App.java:7)
단, 만약 상수 선언 시 할당을 하지 않았다면 이후에 딱 한 번 값을 할당할 수는 있다.
public class App {
public static void main(String[] args)
{
final double PI = 3.14;
final short MY_HEIGHT; // 상수 선언만 함.
MY_HEIGHT = 179; // 상수 할당을 이제야 함.
System.out.println(PI);
System.out.println(MY_HEIGHT);
}
}
3.14
179
References
[1] 이재환, “이재환의 자바 프로그래밍 입문”, (골든래빗, 2021)
This content is licensed under
CC BY-NC 4.0
댓글남기기