케네스로그

[Java] 타입 추론 var 본문

Dev/Java

[Java] 타입 추론 var

kenasdev 2022. 1. 30. 12:23
반응형

타입 추론

 

이 글은 참조(https://velog.io/@composite/Java-10-에서-var-재대로-사용하기) 하였습니다.

타입추론은 정적 타이핑을 지원하는 언어에서, 타입이 정해지지 않은 변수에 대해서 컴파일러가 변수의 타입을 스스로 찾아낼 수 있도록 하는 기능을 말합니다. 이를 통해서, 타입을 명시하지 않아도 되며, 코드량을 줄이고 코드의 가독성을 높일 수 있습니다.

 

Java10부터 var키워드가 생겼으며, Java11부터는 이를 통한 람다 타입도 지원합니다. 컴파일러는 개발자가 입력한 초기화 값을 통해 타입을 유추하는데, var는 컴파일러가 타입을 유추할 수 있도록 반드시 데이터를 초기화 해줘야만 합니다.

 

// Java 9
String message = "Good bye, Java 9"

// Java 10
@Test
public void whenVarInitWithString_thenGetStringTypeVar() {
	var message = "Hello, Java 10";
	assertTrue(message instaceof String);
}

 

  • 초기화 없이 var는 동작하지 않습니다
  • 자바7에서 나온 다이아몬드 연산자는 var와 함께 사용할 수 없습니다.
    List<Integer> list = new LinkedList<>();

var로 적을 시에 협업하는 개발자가 쉽게 타입을 유추할 수 없기에, var 데이터타입을 적용하면 자연스럽게 네이밍에 신경쓰게 됩니다.

 

var message = "hello";

public void Test() {
	var TestName = getTestName();
}

public Name getTestName() {
	return new Name("객체입니다.", MessageType.SOME);
}

 

다른 클래스파일에 두개 이상의 함수를 조회해야할 경우, 위의 코드와 같이 타입을 유추하기 힘들 수 있습니다. 물론 네이밍을 잘하면 커버할 수 있는 단점이지만, 단순한 getter/setter 함수 외에는 한계가 있어 보이고, 네이밍을 잘 하더라도 헷갈리는 경우가 많지 않을까요? 그렇다면 어디서 var를 쓰는게 적절할까요?

 

a. forEach에서의 사용

// java 9
for(People people: peopleList) {

}

// java 10
for(var people : peopleList) {

}

위의 예시에서 var 키워드를 통해 People을 클래스로 인식할 수 있게 되고, 컴파일 시에도 var 키워드를 People로 변환하게 됩니다. 타이핑이 더욱 간결해지고 Object 타입을 미리 단정지을 필요도 없습니다.

 

b. 람다 in Java 11

LTS인 자바 11은 람다 인자에도 var를 넣게 해주는데, 이것이 왜 중요한 이유는, 일반 람다의 경우 파라미터 어노테이션을 집어넣을 수 없기때문입니다. 만약 어노테이션을 넣고 싶다면 따로 메소드를 만들거나 익명 클래스로 정의해야만 합니다. 하지만, 자바8부터 람다 인자는 타입 추론의 기초였던게, 자바11부터는 타입 추론의 유연성을 추가했다고 할 수 있습니다.

 

Consumer<Person> personConsumer = (@nonnull var person) -> {};

 

 

c. 익명 클래스

가독성의 면에서 var를 사용하는 것은 좋은 선택이 아닙니다. IDE가 아닌 에디터에서 코드를 볼 때 사람은 타입추론이 힘들어집니다.

var intVal = 20;
var strVal = "string";
var list = new ArrayList<Integer>();

 

하지만 익명클래스는 정의가 거대하고 유치하기 쉬우며, 선언한 다음에 변수가 바뀌는 일도 없으므로 var를 쓰기에 적절합니다

var supply = new Supplier<String>() {
	@Override
	public String get() {
		...
	};
}

var supply = () => {};

 

 

반응형