본문 바로가기
Today I Learned/Java

[Java] var

by dbs_ 2025. 8. 10.

 

var란?

  • Java 10에서 도입된 지역 변수 타입 추론 문법
  • var로 선언하면 컴파일러가 우변(= 초기화 값)을 보고 정적 타입을 결정
  • 예약된 타입 이름(reserved type name)
  • 타입 위치에서만 특별한 의미가 있고, 그 외 위치(메서드명 등)에서는 식별자로 쓸 수 있다

 

어디서 사용하나

  • 지역 변수, for-each 변수, try-with-resources 리소스 변수, 람다 파라미터(Java 11 이상)에서 사용 가능.
  • 단, 필드(멤버 변수), 메서드 매개변수/반환 타입(람다 파라미터는 예외)에서는 사용 불가!

 

예시

// 지역 변수: 우변으로 정적 타입이 확정
var n = 1;                     // int
var l = 1L;                    // long
var name = "test";            // String
var list = new ArrayList<String>(); // ArrayList<String>

// for-each
for (var e : list) { /* ... */ }

// try-with-resources
try (var br = new BufferedReader(new FileReader("a.txt"))) {
    // br은 BufferedReader로 추론
}
// 반드시 초기화가 있어야한다
var x;              // 컴파일 에러 (초기화 필요)
var y = null;       // 컴파일 에러 (null만으론 타입 추론 불가)
var z = (Short) null; // 가능 : 캐스트로 타입 지정

 

특징

1. var는 동적이 아니다. 한 번 추론된 정적 타입으로 컴파일된다.

var n = 1;     // int
// n = "text"; // 컴파일 에러 (타입 불일치)

2. 제네릭은 우변이 기준 : 우변에 타입 인자를 명시하지 않으면 의도치 않게 Object로 갈 수 있음

var list1 = new ArrayList<>();          // 보통 ArrayList<Object>로 추론됨
var list2 = new ArrayList<String>();    // ArrayList<String> (권장)

3. 배열 리터럴 문법 주의

var a = new int[]{1,2,3}; // OK → int[]
// var b = {1,2,3};       // 에러 (배열 리터럴만으로는 불가)

 

언제 쓰면 좋을까?

  • 우변이 명확할 때 : var out = new ByteArrayOutputStream();
  • 보일러플레이트 감축 : Map <String, List <User>> 같은 장황한 타입에
  • 로컬 범위에서만 쓰는 임시 변수

 

언제 피하는 게 좋은까?

  • 우변 타입이 직관적이지 않을 때 (가독성 저하).
    • 예 : var result = service.process(input); → 타입이 무엇인지 코드만 봐선 모호.
  • API 경계(필드, 파라미터, 반환)
    • 애초에 사용할 수 없거나, 명시 타입이 문서 역할을 하므로 명시하는 편이 좋다.
  • 제네릭 타입 인자 생략으로 Object가 될 가능성이 있을 때.

 

결론, var는 지역 변수의 타입 선언을 줄여주는 문법일 뿐이며, 정적 타입 언어 특성은 그대로 유지된다. 초기화 값이 명확하고 가독성이 좋아지는 경우에만 사용하면 될 것 같다.