2016-09-28 10 views
2

오늘 심하게 중첩 된 객체가 포함 된 내 코드에서 불필요한 null 상태 검사를 제거하는 것에 대해 숙고했습니다. 예 :반복 된 null 검사 대신 try catch 블록 활용하기

I 클래스 Big가 그것을 Small 객체에 대한 참조가 그 게터와 세터 마찬가지로 Small Tiny 객체에 대한 참조가 그 게터와 세터와 Tiny 객체가있는 tinyLength 변수를 갖는다 Integer 변수.

나는 Big 개체 매개 변수에 걸릴 맨 끝에 tinyLength 반환하는 방법을 쓰고있어 경우에 따라서, 예를 들어, 나는 보통 이런 식 을 수행

public Integer getTinyLength (Big big) { 
    if (big!=null && big.getSmall()!=null && big.getSmall().getTiny()!=null && 
     big.getSmall().getTiny().getTinyLength()!=null) { 
    return big.getSmall().getTiny().getTinyLength(); 
} 
else { 
    // throw exception or return null or do whatever 
} 

그래서 내 질문을 여기에 오히려이 모든 빚을 것보다, 왜 난 그냥 같은 것을하지 않아도됩니다 : 나는 두 번째 코드 같은 느낌

try { 
    return big.getSmall().getTiny().getTinyLength(); 
}  
catch (Exception e){ 
    //null pointer exception being a subclass of Exception class 
    log your error here 
    throw new NullPointerException(); 
} 

매우 간결하고 요점이다. 이런 일을하는 데 어떤 단점이 있습니까? 특히 중첩 된 객체가 여러 개있을 때 각각의 객체를 역 참조하는 경우 대개 읽을 수없는 코드가 발생하며 그 중 하나를 놓치면 null이됩니다.

+0

유용한 정보 http://stackoverflow.com/questions/14813877/advantages-and-disadvantages-of-using-try-catch –

+0

이 내용은 Groovy 및 Kotlin에서 정상적으로 처리됩니다. 나는 순수 Java로 긴 null 검사를 다루는 데 신경 쓰지 않을 것이다. – Alexiy

+0

글쎄, 당신은 분명히 그것을 위해 갈 수 있습니다. 코드를 훨씬 쉽게 읽을 수 있습니다. [이] (http://stackoverflow.com/questions/16451777/is-it-expensive-to-use-try-catch-blocks-even-if-an-exception-is-never-thrown) 질문에 따르면, try-catch 블로그를 사용하는 것은 비싸지 않습니다. –

답변

1

첫 번째 코드 샘플은 비효율적이며 스레드가 안전하지 않습니다. getSmall()이 네 번 호출되면 getTiny()이 세 번 호출되고 getTinyLength()이 두 번 호출됩니다.

두 번째 코드 샘플은 위험합니다. NullPointerException을 붙잡고 싶을 때 Exception을 붙잡는 것은 잡으려고하지 않았다는 예외를 잡을 수 있습니다. 또한 NullPointerException 객체를 생성하고 던지고 잡아 버리고 버리고 또 다른 NullPointerObject을 생성하는 오버 헤드가 있습니다. 더 나은

은 다음과 같습니다

Integer length = null; 
if (big != null) { 
    Small small = big.getSmall(); 
    if (small != null) { 
     Tiny tiny = small.getTiny(); 
     if (tiny != null) { 
      length = tiny.getTinyLength(); 
     } 
    } 
} 
if (length != null) { 
    return length; 
} else { 
    // Throw exception, return null, or do whatever 
} 

더 나은 여전히 ​​멀리 Big#getTinyLength() 내부의 게터에 그 코드를 숨기는 것입니다.

데이터 모델을 자세히 살펴 봐야합니다. Small이없는 Big을 사용할 수 있습니까? Tiny이 포함되지 않은 Small을 사용할 수 있습니까? Tiny에는 길이가없는 이유는 무엇입니까?

return big.getSmall().getTiny().getTinyLength(); 

편집 :이 회원 null을 안 경우, 단지 1 당량을 다시 발생하는, 그것을위한 JVM 체크를하게하고 예외를 던져,하지만 그것을 잡을하지 않습니다

public Integer getTinyLength (Big big) { 
    return Optional.ofNullable(big) 
     .map(Big::getSmall) 
     .map(Small:getTiny) 
     .map(Tiny::getTinyLength) 
     .orElse(null); 
} 

이 : 자바 (8)을 사용하는 경우

, 다음 Optional 유형은 코드를 단순화 할 수 big에서 Optional<Big>을 생성하고 언 랩핑하여 작은 길이 값을 얻습니다.bignull이거나 호출에 사용 된 매핑 함수가 null을 반환하면 빈 선택적 요소가 생성됩니다. 마지막으로 Optional<Integer>의 값이 있으면 반환하고 그렇지 않은 경우 null의 값을 반환합니다.