1. 구문 설탕

프로그래머는 복잡한 코드나 논리를 몇 줄로 작성하여 코드를 간결하고 읽기 쉽게 만들 수 있는 것을 좋아합니다. 그리고 프로그래밍 언어를 만든 사람들이 때때로 이것을 돕습니다.

지름길(코드를 적게 작성)을 사용할 수 있는 매끄러운 언어 기능을 구문 설탕 이라고 합니다 . 그러나 솔직히 말해서 Java에는 거의 없습니다.

Java 제작자는 Java의 중복성을 제거하기 위해 최선을 다했습니다. C++에서 20가지 방식으로 작업을 수행할 수 있다면 Java에서는 한 가지 방식으로만 작업을 수행할 수 있습니다.

그러나 Java 프로그래머도 Java 작성자도 자유의 부족을 좋아하지 않았습니다. 그리고 때때로 설탕은 당신과 나 같은 평범한 사람들의 삶을 더 쉽게 만듭니다.

그건 그렇고, 당신은 이미 autoboxingunboxing 과 같은 몇 가지 구문 설탕을 접했습니다 . 비교해보자:

긴 코드 컴팩트 코드
Integer a = new Integer(5);
int b = a.intValue();
Integer a = 5;
int b = a;
int b = 5;
Integer c = new Integer(b);
int b = 5;
Integer c = b;
Integer a = new Integer(1);
int b = 1;
if (a.intValue() == b)
{
   ...
}
Integer a = 1;
int b = 1;
if (a == b)
{
   ...
}

왼쪽과 같은 긴 코드 대신 오른쪽에 더 간결한 코드를 작성할 수 있습니다. 지능형 Java 컴파일러는 짧은 버전의 코드를 기반으로 자세한 버전의 코드를 생성합니다. 이것이 바로 구문 설탕입니다.


2. 변수 유형 추론: var키워드

Java 11에서는 컴파일러가 훨씬 더 똑똑해졌으며 이제 할당된 값의 유형을 기반으로 선언된 변수의 유형을 결정할 수 있습니다 . 코드에서는 다음과 같습니다.

var name = value;

여기서 name는 새 변수의 이름이고, value 는 초기 값이며 var변수를 선언하는 데 사용되는 키워드입니다. 이름 변수 의 유형은 할당된 값의 유형과 동일합니다.

예:

우리가 코드를 보는 방법 컴파일러가 보는 것
var i = 1;
int i = 1;
var s = "Hello";
String s = "Hello";
var console = new Scanner(System.in);
Scanner console = new Scanner(System.in);
var list = new ArrayList<String>();
ArrayList<String> list = new ArrayList<String>();
var data = new int[]{1, 2, 3};
int[] data = new int[]{1, 2, 3};

컴파일러 자체는 변수 에 할당된 값을 기반으로 변수의 유형을 결정하거나 유추합니다.

프로그래머들은 그러한 기능을 언어에 추가할지 여부에 대해 열띤 토론을 벌였습니다. 많은 사람들은 그것이 var남용되고 그 결과 코드 가독성이 떨어질 것을 두려워했습니다.

이것에는 진실이 있으므로 var코드의 가독성을 높이는 곳에 사용하는 것이 가장 좋습니다. 예를 들어 다음과 같은 두 가지 경우입니다.

사례 1: 변수에 할당된 값을 보면 변수의 유형이 즉시 명확해집니다.

암호 설명
var stream = url.getInputStream();
변수는InputStream
var name = person.getFullName();
변수는String

이러한 경우에는 를 사용 하면 안 됩니다var . 음, 변수의 유형은 무엇입니까?

암호 설명
var result = task.execute();
변수의 유형을 결정하기 어렵습니다.
var status = person.getStatus();
변수의 유형을 결정하기 어렵습니다.

사례 2: 변수의 유형은 코드를 이해하는 데 중요하지 않습니다.

코드는 변수에 대한 메서드를 호출할 필요가 없는 경우가 많습니다. 예를 들어 변수가 단순히 무언가를 임시로 저장하는 데 사용되는 경우입니다. 이 경우 다음을 사용해 var도 코드의 가독성이 떨어지지 않습니다.

긴 코드 컴팩트 코드
var data = stream.getMetaData();
storage.save(data)
스트림 에서 메타데이터를 가져와 저장소 stream에 저장했습니다 storage. 변수 data의 특정 유형은 중요하지 않습니다.

황금률

이제 동일한 코드를 작성하는 세 가지 방법을 제시하겠습니다. 사용하는 것이 var최선의 선택이 될 것입니다.

암호 메모
dest.writeHeaderInfo(src.getFileMetaInfo());
너무 콤팩트하다
var headerInfo = src.getFileMetaInfo();
dest.writeHeaderInfo(headerInfo);
바로
FileMetaInfo headerInfo = src.getFileMetaInfo();
dest.writeHeaderInfo(headerInfo);
너무 상세하다

headerInfo1줄 버전에서 2줄 버전으로 넘어가면서 변수명( ) 을 사용하여 코드를 좀 더 읽기 쉽게 만들었습니다 . 이제 메서드가 메타 정보뿐만 아니라 헤더 정보도 반환한다는 것이 분명해졌습니다.

세 번째 버전은 지나치게 장황합니다. headerInfoa라는 사실은 FileMetaInfo이미 getFileMetaInfo()메서드에서 상당히 명확합니다. 메타 정보의 목적은 훨씬 더 흥미롭습니다.



3. 다이아몬드 연산자로 유형 생략:<>

연산자가 등장 하기 전부터 var컴파일러에게 컬렉션 유형을 유추하는 방법을 가르치려는 시도가 있었습니다. 이 표기법이 약간 중복된 것처럼 보인다는 데 동의할 것입니다.

ArrayList<String> list = new ArrayList<String>();

자바 7버전부터는 컬렉션 타입을 작성할 때 변수 선언 시 컬렉션 요소의 타입을 지정했다면 생략할 수 있다. 즉, 위의 코드는 약간 축약된 형식으로 작성할 수 있습니다.

ArrayList<String> list = new ArrayList<>();

보시다시피 더 이상 String을 두 번 작성할 필요가 없습니다. var 연산자만큼 멋지지는 않지만 당시에는 진보처럼 보였습니다.

컬렉션 유형의 빈 꺾쇠괄호는 두 개의 꺾쇠괄호가 다이아몬드와 어렴풋이 닮았기 때문에 다이아몬드 연산자 라고 했습니다.

var키워드와 다이아몬드 연산자를 동시에 사용하는 것은 바람직하지 않습니다 .

var list = new ArrayList<>();

컬렉션에 저장된 요소의 유형에 대한 정보가 전혀 없으며 컬렉션 유형은 ArrayList < Object >가 됩니다.



4. 이중 중괄호

빠른 어레이 초기화를 기억하십니까?

다음과 같이 중괄호 안에 값을 나열했습니다.

int[] data = new int[] {1, 2, 3, 4, 5, 6, 7};
int[] data = {1, 2, 3, 4, 5, 6, 7};

Java 제작자는 중괄호를 사용하여 배열의 요소 쓰기를 단순화한다는 아이디어를 좋아했습니다. 그러나 컬렉션은 어떻습니까?

Java의 제작자는 컬렉션에 대해서도 충분한 창의적 사고를 가지고 있었기 때문에 이중 중괄호로 트릭을 사용할 수 있었습니다.

설탕과 함께 설탕없이
var list = new ArrayList<String>()
{{
   add("Hello");
   add("How's");
   add("Life?");
}};
var list = new ArrayList<String>();

list.add("Hello");
list.add("How's");
list.add("Life?");

컴파일러가 왼쪽의 예와 같은 코드를 만나면 오른쪽의 코드로 변환합니다.

코드가 훨씬 더 간결해지지 않습니다. list여기에서 절약되는 것은 상당히 미미합니다. 매번 쓸 필요가 없습니다 . 이것은 변수 이름이 매우 긴 경우에 유용할 수 있습니다.

그러나 프로젝트에서 이와 같은 코드를 발견하더라도 놀라지 마십시오 🙂