2016-11-22 4 views
0

이 예제 코드에서 경고를 제거하는 방법.TreeMap의 eclipse 네온에서 "Null 타입 안전"경고를 제거하는 방법

내가 자바 1.8와 이클립스 네온을 사용하고 org.eclipse.jdt.annotation_2.1.0

import java.util.Iterator; 
import java.util.Map.Entry; 
import java.util.Set; 
import java.util.TreeMap; 

import org.eclipse.jdt.annotation.NonNullByDefault; 
import org.eclipse.jdt.annotation.Nullable; 

@NonNullByDefault 
public class NullAnnotationTest4 { 

    public static void main(String[] args) { 

     final TreeMap<@Nullable Integer, @Nullable String> treeMap = new TreeMap<>(); 

     treeMap.put(3, "Test1"); 
     treeMap.put(null, null); 

     //This produces the warning 
     final Set<@Nullable Entry<@Nullable Integer, @Nullable String>> set = treeMap.entrySet(); 

     for (final Iterator<@Nullable Entry<@Nullable Integer, @Nullable String>> it = set.iterator(); it.hasNext();) { 

      final Entry<@Nullable Integer, @Nullable String> entry = it.next(); 

      if (entry != null && entry.getKey() == null && entry.getValue() != null) 
       System.out.println(entry.getKey()+" is mapped to "+entry.getValue()); 
     } 

    } 
} 

경고입니다 : 내가 @Nullable과의 여러 가지 조합을 시도

Null type safety (type annotations): 
The expression of type 
'Set<Map.Entry<@Nullable Integer,@Nullable String>>' 
needs unchecked conversion to conform to 
'Set<[email protected] Entry<@Nullable Integer,@Nullable String>>' 

@ NonNullable. 심지어 ? extends 같은 비슷한 경우에 제안했다 : https://bugs.eclipse.org/bugs/show_bug.cgi?id=507779

그러나 경고는 항상 이동하지만 완전히 멀리 가지 않습니다.

업데이트 :이 줄을 사용하여 경고를 제거있어

:

final Set<? extends @Nullable Entry<@Nullable Integer, @Nullable String>> set = treeMap.entrySet(); 

하지만 완전히 이유로 손실입니다. 나에게 트랙이나 무언가를 잃어 버리면 유효성 검사기를 속이며 코드가 실제로 추악 해지기 시작합니다.

전체 새로운 코드 :

import java.util.Iterator; 
import java.util.Map.Entry; 
import java.util.Set; 
import java.util.TreeMap; 

import org.eclipse.jdt.annotation.NonNullByDefault; 
import org.eclipse.jdt.annotation.Nullable; 

@NonNullByDefault 
public class NullAnnotationTest4 { 

    public static void main(String[] args) { 

     final TreeMap<@Nullable Integer, @Nullable String> treeMap = new TreeMap<>(); 

     treeMap.put(3, "Test1"); 
     treeMap.put(null, null); 


     final Set<? extends @Nullable Entry<@Nullable Integer, @Nullable String>> set = treeMap.entrySet(); 

     for (final Iterator<? extends @Nullable Entry<@Nullable Integer, @Nullable String>> it = set.iterator(); it.hasNext();) { 

      final Entry<@Nullable Integer, @Nullable String> entry = it.next(); 

      if (entry != null && entry.getKey() == null && entry.getValue() != null) 
       System.out.println(entry.getKey()+" is mapped to "+entry.getValue()); 
     } 

    } 
} 

업데이트 2 쇼티는 잘못된 코드를 붙여 넣습니다.

+0

'set' 변수는'Set >'일까요? 엔트리 세트의 엔트리는 아마 null이 아니어야합니다. –

+0

나는 그것을 먼저 시도했다. 그러나 오류는 @NonNullByDefault 때문에'Set Torge

답변

1

Set<@NonNull X>Set<@Nullable X>과 같은 질문 유형의 핵심 부분은 호환되지 않습니다. 어느 쪽도 다른쪽에 할당 할 수 없습니다. 재치으로

: 당신은 Set<@NonNull X> 클라이언트가 추출물 null 이외의 요소에 기대 세트가 실제로 Set<@Nullable X> 경우 중단됩니다 경우. 반대로 Set<@Nullable X> 고객이있는 경우 null에 삽입하면 실제로 Set<@NonNull X> 인 경우 중단됩니다.

이러한 고려 사항은 지식이 부족한 "기존"유형 Set<X>을 다룰 때마다 적합합니다. Set<@NonNull X> 또는 Set<@Nullable X>으로 지정할 수 있습니다. 타입 검사는 두 가지 가능성을 고려해야한다 (클라이언트는 javadoc이 그렇게 말할 수 있기 때문에 두 가정에 의존 할 수있다).

일반적으로 Java에서 읽기 및 쓰기 문제는 바운드 와일드 카드를 사용하여 해결됩니다. Set<? extends X>은 읽기 액세스가 항상 "적어도"X 이상 (또는 그 이상)이되도록 보장합니다. Set<? super X>은 새 요소를 삽입하기위한 요구 사항이 "at at most"X 인 것을 보장합니다. 즉, 실제 목록의 실제 요구 사항이 무엇이든간에 X 이상의 값이 집합에 적용됩니다.

위의 내용을 null 주석에 적용하려면 기존 세트를 수락하고 세트에서 읽기를 지원한다고 말하면됩니다 (값은 @Nullable X 이상이어야합니다 (예 : @NonNull X). 레거시 세트에 삽입해야하는 경우 Set<? super @NonNull X> 유형의 변수에 할당하십시오. 이렇게하면 형식 검사기에 @NonNull X이 항상 삽입하기에 충분하다는 것을 알 수 있습니다.

따라서 Set<? extends @Nullable Entry<..>treeMap.entrySet()의 결과를 허용하며 실제로는 Set<Entry<@Nullable Integer, @Nullable String>> 유형을 사용합니다. 여기서 내부 유형 인수는 treeMap의 선언에서 완전히 주석을 달았고, entrySet()의 레거시 서명으로 인해 최상위 유형 인수 Entry 만 지정되지 않았습니다.

마지막 언급은 예제의 "실제"해결책을 암시합니다. 외부 주석을 사용하여 entrySet()이 실제로 @NonNull Set<@NonNull Entry<K,V>>을 반환한다는 것을 나타냅니다. 와일드 카드 마법과 같은 것이 필요하지 않습니다.