Java 7의 다이아몬드 연산자는 다음과 같은 코드를 허용합니다.
List<String> list = new LinkedList<>();
그러나 Java 5/6에서는 간단히 작성할 수 있습니다.
List<String> list = new LinkedList();
타입 삭제에 대한 나의 이해는 이것들이 정확히 동일하다는 것입니다. 어쨌든 제네릭은 런타임에 제거됩니다.
왜 다이아몬드를 전혀 귀찮게합니까? 어떤 새로운 기능 / 유형 안전이 허용됩니까? 새로운 기능을 제공하지 않으면 왜 기능으로 언급합니까? 이 개념에 대한 나의 이해가 잘못 되었습니까?
답변
문제
List<String> list = new LinkedList();
왼쪽에, 당신은 사용하고 있다는 점이다 일반적인 유형의 List<String>
오른쪽에 당신이 사용하는 원시 유형을 LinkedList
. Java의 원시 유형은 사실상 제네릭 이전 코드와의 호환성을 위해서만 존재하며 반드시 필요한 경우가 아니면 새 코드에서 사용해서는 안됩니다.
이제 Java에 처음부터 제네릭이 있고 제네릭을 갖기 LinkedList
전에 처음 생성 된 유형이없는 경우 제네릭 유형의 생성자가 자동으로 왼쪽에서 유형 매개 변수를 유추하도록 만들 수 있습니다. 가능하면 과제의 손. 그러나 이전 버전과의 호환성을 위해 원시 유형과 일반 유형을 다르게 처리해야합니다. 잎 그들은 만들 필요가 약간 다른 그 유형 매개 변수 … 다이아몬드 연산자를 반복 할 필요없이 일반 객체의 새로운 인스턴스를 선언하지만, 똑같이 편리한 방법을.
의 원래 예제 List<String> list = new LinkedList()
에서 컴파일러는 해당 할당에 대한 경고를 생성해야합니다. 이걸 고려하세요:
List<String> strings = ... // some list that contains some strings
// Totally legal since you used the raw type and lost all type checking!
List<Integer> integers = new LinkedList(strings);
제네릭은 잘못된 일을하지 않도록 컴파일 타임을 보호하기 위해 존재합니다. 위의 예에서 raw 유형을 사용하면이 보호 기능을 사용할 수 없으며 런타임시 오류가 발생합니다. 이것이 원시 유형을 사용하지 않아야하는 이유입니다.
// Not legal since the right side is actually generic!
List<Integer> integers = new LinkedList<>(strings);
그러나 다이아몬드 연산자를 사용하면 할당의 오른쪽을 매개 변수를 다시 입력하지 않고도 왼쪽과 동일한 형식 매개 변수를 가진 실제 일반 인스턴스로 정의 할 수 있습니다. 원시 유형을 사용하는 것과 거의 동일한 노력으로 제네릭의 안전을 유지할 수 있습니다 .
이해해야 할 핵심은 원시 유형 (없음 <>
)을 일반 유형과 동일하게 취급 할 수 없다는 것입니다. 원시 형식을 선언하면 제네릭의 이점과 형식 검사가 없습니다. 또한 제네릭은 Java 언어의 범용 부분 이라는 점을 명심해야합니다 Collection
. s 의 no-arg 생성자에만 적용되는 것은 아닙니다 !