Java 변수와 리터럴 완전 정리

Java 변수 선언 구조, 네 가지 변수 종류, 여섯 가지 리터럴 형태를 코드와 함께 깊이 있게 정리한다

· 10 min read · PALDYN Team

지난 글에서 Hello World 프로그램을 작성하고 컴파일·실행 흐름까지 살펴봤다. 이번에는 Java 코드의 가장 기본 재료인 변수(variable)리터럴(literal) 을 다룬다. “변수 선언은 다 알고 있다”고 생각하기 쉽지만, 지역 변수와 인스턴스 필드의 초기화 규칙이 어떻게 다른지, 0xFF1_000L 같은 리터럴 표기법이 내부에서 어떻게 해석되는지를 정확히 알아야 컴파일 오류와 런타임 버그를 예방할 수 있다.

변수란 무엇인가

변수는 이름이 붙은 메모리 공간이다. Java 프로그램이 실행될 때 JVM은 이 공간에 값을 저장하고, 코드에서는 이름(식별자)을 통해 그 값을 읽거나 갱신한다.

int count = 42;        // 선언 + 초기화
count = count + 1;     // 값 갱신 (43)

변수 선언은 네 가지 요소로 구성된다.

Java 변수 선언 구조

구성 요소역할예시
타입저장할 값의 종류와 크기 결정int, String
한정자 (선택)final, static 등 속성 제한final
변수명값을 참조하는 lowerCamelCase 식별자count
초기값 (선택)= 뒤의 리터럴·식·객체42

네 가지 변수 종류

지역 변수 (Local Variable)

메서드 또는 블록 내부에서 선언하며, 스택 프레임에 저장된다.

void process() {
    int result = 0;          // 지역 변수 선언 + 초기화
    for (int i = 0; i < 10; i++) {
        result += i;
    }
    System.out.println(result);
}

지역 변수는 자동으로 초기화되지 않는다. 초기화하지 않고 읽으면 컴파일 오류가 발생한다.

void broken() {
    int x;
    System.out.println(x); // 컴파일 오류: variable x might not have been initialized
}

인스턴스 필드 (Instance Field)

클래스 내부, 메서드 외부에 선언하며 객체마다 독립적인 공간을 갖는다. 힙(Heap) 에 저장되고, 선언 시 기본값으로 자동 초기화된다.

public class Counter {
    int count;          // 기본값 0 으로 자동 초기화
    String label;       // 기본값 null 로 자동 초기화
    boolean active;     // 기본값 false 로 자동 초기화
}

정적 필드 (Static Field)

static 키워드로 선언하며 클래스당 하나의 공간만 존재한다. 메서드 영역(Method Area) 에 저장되고 모든 인스턴스가 공유한다.

public class Config {
    static int instanceCount = 0;   // 클래스당 하나
    static final String VERSION = "1.0.0"; // 상수 관례

    Config() {
        instanceCount++;
    }
}

static final 조합은 Java에서 상수를 표현하는 관용적 방법이며, 이름을 UPPER_SNAKE_CASE로 짓는 것이 관례다.

매개변수 (Parameter)

메서드 시그니처에 선언하며, 호출 시 전달된 값이 복사된다.

void greet(String name, int repeat) {
    for (int i = 0; i < repeat; i++) {
        System.out.println("Hello, " + name);
    }
}

기본형(primitive) 매개변수는 값이 복사되므로 메서드 내부에서 변경해도 호출자 변수에 영향을 주지 않는다. 참조형(reference)은 참조가 복사되어 객체 상태는 변경 가능하지만, 참조 자체를 바꿔도 호출자에게 반영되지 않는다.

var — 타입 추론 (Java 10+)

Java 10부터 var 키워드를 사용하면 컴파일러가 오른쪽 초기값에서 타입을 추론한다.

var count  = 42;           // int
var name   = "Alice";      // String
var list   = new ArrayList<String>(); // ArrayList<String>
var reader = new BufferedReader(
                 new InputStreamReader(System.in));

var는 지역 변수에만 허용된다. 필드, 매개변수, 반환 타입에는 사용할 수 없다. 초기값 없이 var 선언도 불가하다.

리터럴(Literal) 완전 정리

리터럴은 소스 코드에 직접 쓴 고정 값이다. 컴파일러가 리터럴을 읽어 그에 맞는 타입의 값으로 변환한다.

Java 리터럴 종류

정수형 리터럴

int  dec  = 42;          // 10진수 (기본)
int  hex  = 0xFF;        // 16진수 (0x/0X 접두사)
int  bin  = 0b1010_1010; // 2진수 (0b/0B 접두사, JDK 7+)
int  oct  = 0755;        // 8진수 (0 접두사)
long big  = 9_000_000_000L; // long 접미사 L (구분자 _ JDK 7+)

접미사 없는 정수 리터럴의 기본 타입은 int다. long 범위의 값은 반드시 L을 붙여야 한다. 소문자 l도 허용되지만 숫자 1과 구분이 어려워 대문자 L 사용이 관례다.

부동소수점 리터럴

double pi    = 3.14;       // double (기본)
double e     = 2.718d;     // double (명시, d/D 생략 가능)
float  ratio = 1.618f;     // float  (f/F 반드시 필요)
double nano  = 1.0e-9;     // 과학적 표기법

소수점을 포함한 리터럴의 기본 타입은 double이다. float에 소수점 리터럴을 대입할 때 f를 빠뜨리면 “가능한 손실 변환(possible lossy conversion)” 컴파일 오류가 발생한다.

문자 리터럴

char a = 'A';        // 단일 문자
char nl = '\n';      // 이스케이프 시퀀스
char uni = 'A'; // 유니코드 이스케이프 (= 'A')

char는 16비트 부호 없는 정수(0 ~ 65535)로, UTF-16 코드 단위를 저장한다.

문자열 리터럴

String hello = "Hello, World!";
String empty = "";
String tab   = "col1\tcol2";

문자열 리터럴은 String Pool에 저장된다. 동일한 리터럴을 여러 번 써도 JVM은 풀에서 같은 객체를 재사용한다.

String a = "java";
String b = "java";
System.out.println(a == b);      // true  (같은 풀 객체)
System.out.println(a == new String("java")); // false (힙 새 객체)

==는 참조를 비교하므로 문자열 내용 비교에는 반드시 equals()를 사용해야 한다.

논리형 리터럴

boolean flag = true;
boolean done = false;

truefalse는 Java 예약어로, 대·소문자를 구분한다. 1이나 0boolean에 대입할 수 없다.

null 리터럴

String s = null;  // 참조가 없는 상태
Object o = null;

null은 참조형 변수에만 대입 가능하며 기본형에는 사용할 수 없다. null 참조에 메서드를 호출하면 런타임에 NullPointerException이 발생하므로 방어적으로 다뤄야 한다.

변수 명명 규칙 정리

대상규칙예시
지역 변수·필드·매개변수lowerCamelCaseuserName, totalCount
상수 (static final)UPPER_SNAKE_CASEMAX_SIZE, DEFAULT_TIMEOUT
클래스·인터페이스UpperCamelCaseMyService, Runnable
패키지소문자, . 구분com.example.util

식별자에는 유니코드 문자도 허용되지만, ASCII 알파벳·숫자·_·$만 사용하는 것이 현업 관례다. $는 자동 생성 코드(람다·익명 클래스 등)에서 JVM이 사용하므로 직접 쓰지 않는 것이 좋다.

정리

변수는 Java 타입 시스템의 출발점이다. 지역·인스턴스·정적·매개변수라는 네 종류의 차이(초기화 방식, 저장 위치, 생명 주기)를 명확히 이해해야 메모리 관련 문제를 예방할 수 있다. 리터럴 표기법도 접두사·접미사·구분자를 정확히 써야 의도한 타입의 값이 만들어진다. 다음 글에서는 변수에 담기는 기본형(primitive type) 여덟 가지를 크기·범위·기본값 관점에서 낱낱이 살펴본다.


지난 글: Hello, Java World — 첫 번째 Java 프로그램

다음 글: Java 기본형(Primitive Types) 완전 정리


읽어주셔서 감사합니다. 😊