Programing

Java 7에서 다이아몬드 연산자 (<>)의 요점은 무엇입니까?

lottogame 2020. 2. 18. 22:36
반응형

Java 7에서 다이아몬드 연산자 (<>)의 요점은 무엇입니까?


Java 7의 다이아몬드 연산자는 다음과 같은 코드를 허용합니다.

List<String> list = new LinkedList<>();

그러나 Java 5/6에서는 간단히 다음과 같이 작성할 수 있습니다.

List<String> list = new LinkedList();

타입 삭제에 대한 나의 이해는 이것들이 정확히 동일하다는 것입니다. 어쨌든 제네릭은 런타임에 제거됩니다.

왜 다이아몬드를 전혀 귀찮게합니까? 어떤 새로운 기능 / 유형 안전이 허용됩니까? 새로운 기능을 제공하지 않으면 왜 기능으로 언급합니까? 이 개념에 대한 나의 이해가 잘못 되었습니까?


문제

List<String> list = new LinkedList();

왼쪽에서 일반 유형을 사용 List<String>하고 오른쪽에서 원시 유형을 사용하는 일반 유형 을 사용하고 있다는 것 LinkedList입니다. 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);

그러나 다이아몬드 연산자를 사용하면 할당의 오른쪽을 매개 변수를 다시 입력하지 않고도 왼쪽과 동일한 형식 매개 변수를 가진 실제 일반 인스턴스로 정의 할 수 있습니다. 원시 유형을 사용하는 것과 거의 동일한 노력으로 제네릭의 안전을 유지할 수 있습니다 .

이해해야 할 핵심은 원시 유형 (no <>)이 일반 유형과 동일하게 취급 될 수 없다는 것입니다. 원시 형식을 선언하면 제네릭의 이점과 형식 검사가 없습니다. 또한 제네릭은 Java 언어의 범용 부분 이라는 점을 명심해야합니다 Collection. s 의 no-arg 생성자에만 적용되는 것은 아닙니다 !


이해에 약간의 결함이 있습니다. 다이아몬드 연산자는 반복하지 않아도 좋은 기능입니다. 형식을 선언 할 때 형식을 한 번 정의하는 것이 합리적이지만 오른쪽에서 형식을 다시 정의하는 것은 의미가 없습니다. 건조 원리.

이제 타입 정의에 대한 모든 퍼즈를 설명하겠습니다. 유형은 런타임에 제거되는 것이 맞지만 유형 정의가있는 목록에서 무언가를 검색하려면 목록을 선언 할 때 정의한 유형으로 다시 가져옵니다. 그렇지 않으면 모든 특정 기능이 손실되고 검색된 객체를 원래 유형으로 캐스트 할 때를 제외하고는 객체 기능이 매우 까다로워 ClassCastException이 발생할 수 있습니다.

를 사용 List<String> list = new LinkedList()하면 원시 유형 경고가 표시됩니다.


이 줄은 [확인되지 않은] 경고를 발생시킵니다.

List<String> list = new LinkedList();

따라서 질문은 다음과 같이 변형됩니다. 왜 새 컬렉션이 생성 된 경우에만 [선택하지 않은] 경고가 자동으로 억제되지 않습니까?

<>기능 을 추가하는 것이 훨씬 어려운 작업이라고 생각 합니다.

UPD : 또한 원시 유형을 '몇 가지 용도로만'사용하는 것이 합법적이라면 엉망이 될 것이라고 생각합니다.


이론적으로 다이아몬드 연산자를 사용하면 반복되는 유형 인수를 저장하여보다 간결하고 읽기 쉬운 코드를 작성할 수 있습니다. 실제로, 그것은 단지 당신에게 아무것도주는 두 개의 혼란스러운 문자입니다. 왜?

  1. 제정신 프로그래머는 새 코드에서 원시 유형을 사용하지 않습니다. 따라서 컴파일러는 형식 인수를 쓰지 않고 유추하기를 원한다고 가정 할 수 있습니다.
  2. 다이아몬드 연산자는 타입 정보를 제공하지 않습니다. 단지 컴파일러가 "괜찮아요"라고 말합니다. 따라서 생략하면 해를 끼칠 수 없습니다. 다이아몬드 연산자가 합법적 인 곳이라면 컴파일러가이를 "추론"할 수 있습니다.

IMHO는 소스를 Java 7로 표시하는 명확하고 간단한 방법을 갖는 것이 그러한 이상한 것을 발명하는 것보다 더 유용 할 것입니다. 이렇게 표시된 코드에서 아무것도 잃지 않고 원시 유형을 금지 할 수 있습니다.

Btw., 컴파일 스위치를 사용하여 수행해야한다고 생각하지 않습니다. 프로그램 파일의 Java 버전은 파일의 속성이며 옵션은 없습니다. 사소한 것처럼 사용

package 7 com.example;

명확하게 만들 수 있습니다 (하나 이상의 멋진 키워드를 포함하여보다 정교한 것을 선호 할 수 있음). 다른 Java 버전 용으로 작성된 소스를 아무 문제없이 함께 컴파일 할 수도 있습니다. 호환성을 잃지 않으면 서 새로운 키워드 (예 : "모듈")를 도입하거나 사용되지 않는 일부 기능 (단일 파일에 중첩되지 않은 여러 개의 중첩되지 않은 클래스)을 제거 할 수 있습니다.


작성 List<String> list = new LinkedList();하면 컴파일러는 "확인되지 않은"경고를 생성합니다. 무시해도되지만 이러한 경고를 무시한 경우 실제 유형 안전 문제를 알리는 경고를 놓칠 수도 있습니다.

따라서 추가 경고를 생성하지 않는 코드를 작성하는 것이 좋으며, 다이아몬드 연산자를 사용하면 불필요한 반복없이 편리한 방식으로 코드를 작성할 수 있습니다.


다른 응답에서는 모두 유효하지만 사용 사례는 완전히 유효한 IMHO는 아닙니다. 구아바 와 특히 컬렉션 관련 항목을 확인하면 정적 메소드로도 마찬가지입니다. 예를 들어 Lists.newArrayList () 를 사용하면 쓸 수 있습니다.

List<String> names = Lists.newArrayList();

또는 정적 가져 오기

import static com.google.common.collect.Lists.*;
...
List<String> names = newArrayList();
List<String> names = newArrayList("one", "two", "three");

구아바에는 이와 같은 다른 강력한 기능이 있으며 실제로 <>에 대한 많은 용도를 생각할 수 없습니다.

다이아몬드 연산자의 동작을 기본값으로 설정하는 경우 즉, 유형이 표현식의 왼쪽에서 유추되거나 왼쪽의 유형이 오른쪽에서 유추 된 경우 더 유용했을 것입니다. 후자는 스칼라에서 일어나는 일입니다.


다이아몬드 연산자의 요점은 제네릭 형식을 선언 할 때 단순히 코드 입력을 줄이는 것입니다. 런타임에는 아무런 영향을 미치지 않습니다.

Java 5 및 6에서 지정하면 유일한 차이점은

List<String> list = new ArrayList();

를 지정 @SuppressWarnings("unchecked")해야합니다 list(그렇지 않으면 확인되지 않은 캐스트 경고가 표시됨). 내 이해는 다이아몬드 운영자가 개발을 쉽게하려고한다는 것입니다. 제네릭의 런타임 실행과는 전혀 관련이 없습니다.

참고 URL : https://stackoverflow.com/questions/4166966/what-is-the-point-of-the-diamond-operator-in-java-7

반응형