2014-06-05 5 views
0

나는 해시 맵에서 무언가를 얻는 방법, 간단한 예 (즉, 많은 의미가 있지만 지금은 충분하지 않습니다)입니다있다 :자바 @Nonnull 주석

private Map<String,String> map = new HashMap<String,String>(); 

public String get(String key) { 
    return map.get(key); 
} 

이 메소드는 주어진 키에 대한 항목이 분명히 존재하지 않을 때 null을 리턴 할 수 있습니다. 문제는,이 메소드에 @Nonnull 주석을 달기를 원합니다 (왜냐하면 그것은 gazillion 장소에서 사용되기 때문에 Intellij가 NPE 생성에 대한 검사 경고를 내게 스팸하고, 검사를 끄고 싶지 않기 때문입니다. 그리고이 메소드를 호출하는 모든 곳에서 반환 된 값이 null과 다른지 확인하고 싶지 않습니다. 항상이 메소드를 항상 맵에있는 키들로 사용하기 때문에입니다. 그래서 프로그램 로직으로 인해 메서드가 @Nonnull 값을 반환하도록 바인딩되어 있습니다.

@Nonnull을 사용하여 주석을 달고 싶지만 다른 사람이 정의 된 키 이외의 다른 키로 호출하여 실제로 NullPointerException을 발생시킬 수 있다는 것을 알고 있습니다. 당신은 어설프게 나에게 유혹을 불러 일으킨다 .. 아니면 RuntimException을 던지기위한 메소드를 변경하겠습니까? 아니면 AssertionError입니까?

감사합니다.

편집 :

여기에 실제 구현의 : 지정된 키가있는 경우 확인하지 않고 @Nonnull

/** 
* Typesafe heterogeneous container pattern - implementation 
*/ 
public class HandlersMap { 

    private final Map<Class<? extends TableHandler>, TableHandler> handlers; 

    public HandlersMap() { 
     handlers = new HashMap<Class<? extends TableHandler>, TableHandler>(); 
     putHandler(RolesTableHandler.class, new RolesTableHandler()); 
     putHandler(UsersTableHandler.class, new UsersTableHandler()); 
     putHandler(DevicesTableHandler.class, new DevicesTableHandler()); 
    } 

    private <T extends TableHandler> void putHandler(@Nonnull final Class<T> type, @Nonnull final T instance) { 
     handlers.put(type, type.cast(instance)); 
    } 

    @Nonnull 
    public <T extends TableHandler> T getHandler(@Nonnull final Class<T> type) { 
     assert handlers.get(type) != null; 
     return type.cast(handlers.get(type)); 
    } 

    public Collection<TableHandler> values() { 
     return handlers.values(); 
    } 

    public int size() { 
     return handlers.size(); 
    } 

    public Map<Class<? extends TableHandler>, TableHandler> getMap() { 
     return this.handlers; 
    } 

} 

답변

3

주석 달기 확실히 할 수있는 잘못된 일이다.

주어진 키가 존재할 것으로 예상되는 것으로 보이므로 누락 된 키가 잘못된 인수이므로이 경우를 확인하고 누락 된 요소에 대해 IllegalArgumentException을 던지는 것이 올바른 방법입니다.

또는지도 초기화 방법에 따라, 당신은 대신 HashMapEnumMap를 사용하여 키 값을 열거를 만드는 것을 고려하고 get() 방법은 자유 형식 String보다는이 열거을 가지고 할 수 있습니다 . 그런 식으로 적절한 값이 사용되는지 확인하기 위해 컴파일 타임 검사를해야합니다.

그래도 요청한 열거 형 값이 아직지도에 추가되지 않은 경우에 대비하여 존재 여부를 확인해야합니다.

+0

은 enumMap의 아이디어를 좋아합니다. 나는 그런 존재가 존재한다는 것을 알지 못했습니다. 맵은 클래스 자체이며 모든 키가 생성자에 추가됩니다. 조슈아 블로흐 (Joschua Bloch)가 형식이 다른 이질 맵 컨테이너 패턴의 변형입니다. 내가 당신이 제안한 것, 감사에서 뭔가를 만들 수 있는지 좀 만료됩니다.) –

+0

나는 hashMap에 머물렀다. 다만 주장을 추가했다. 내 열쇠는 특정 클래스의 서브 클래스 일 수 있으며, 모든 서브 클래스는 이미 맵에 있습니다. 이것이 실패하는 것은 쉽지 않습니다. 그런 다음 다시 한 번 실패 할 수 있다면 조만간 실패 할 것입니다! :) EnumMap은 내 사건에 대해 구현하기가 어려웠으므로 지금 당장 포기해야합니다. 작업에 익숙해지면 실제로 구현 된 코드를 추가하여 살펴 보겠습니다! :디 –

관련 문제