Guava checkNotNull의 요점은 무엇입니까
나는 구아바를 처음 접했고 (솔직히 말해서, 나는 "아주 새롭지 않다", 나는 그 주제에 대한 완전한 신인입니다) 그래서 몇 가지 문서를 검토하기로 결정했고 이것을 읽는 동안 상당히 놀랐습니다.
com.google.common.base.Preconditions.checkNotNull(...)
이 방법의 요점을 이해하지 못합니다. 이것은 대신 다음을 의미합니다.
myObject.getAnything();
(이로 인해 NullPointerException
myObject가 null 인 경우 발생할 수 있음 )
나는 사용해야한다
checkNotNull(myObject).getAnything();
하는 것입니다 를 던질 NullPointerException
경우 myObject
null이 반환이 myObject
null가 아닌 경우.
나는 의아해하고 이것은 가장 어리석은 질문 일지 모르지만 ...
이것의 요점은 무엇입니까? 이 두 줄은 내가 생각할 수있는 모든 상황에서 결과와 똑같은 일을합니다.
후자가 더 읽기 쉽다고 생각조차하지 않습니다.
그래서 뭔가 빠졌 나봐요. 뭐야?
아이디어는 빨리 실패하는 것입니다. 예를 들어, 다음과 같은 어리석은 클래스를 고려하십시오.
public class Foo {
private final String s;
public Foo(String s) {
this.s = s;
}
public int getStringLength() {
return s.length();
}
}
에 대해 null 값을 허용하지 않기를 원한다고 가정 해 보겠습니다 s
. (또는 그렇지 않으면 getStringLength
NPE를 던질 것 입니다). 수업이있는 그대로 null
, 그것을 잡을 때 까지는 너무 늦었습니다. 누가 그것을 거기에 넣었는지 알아 내기가 매우 어렵습니다. 범인은 완전히 다른 클래스에 Foo
있을 수 있으며 해당 인스턴스는 오래 전에 생성되었을 수 있습니다. 이제 누가 null
값 을 넣을 수 있었는지 찾기 위해 코드베이스를 살펴 봐야 합니다.
대신 다음 생성자를 상상해보십시오.
public Foo(String s) {
this.s = checkNotNull(s);
}
이제 누군가가 null
거기 에 a 를 넣으면 즉시 알 수 있으며 잘못된 호출을 정확히 가리키는 스택 추적을 갖게됩니다.
이것이 유용 할 수있는 또 다른 경우는 상태를 수정할 수있는 작업을 수행하기 전에 인수를 확인하려는 경우입니다. 예를 들어, 모든 문자열 길이의 평균을 계산하는 다음 클래스를 고려하십시오.
public class StringLengthAverager {
private int stringsSeen;
private int totalLengthSeen;
public void accept(String s) {
stringsSeen++;
totalLengthSeen += s.length();
}
public double getAverageLength() {
return ((double)totalLengthSeen) / stringsSeen;
}
}
호출 accept(null)
하면 NPE가 발생하지만 이전 stringsSeen
에는 증가 하지 않습니다 . 이것은 당신이 원하는 것이 아닐 수도 있습니다. 클래스의 사용자로서 null을 허용하지 않으면 null을 전달하면 상태가 변경되지 않을 것으로 예상 할 수 있습니다 (즉, 호출이 실패해야하지만 객체를 무효화해서는 안 됨). 분명히이 예제 에서는 s.length()
증가하기 전에 가져 와서 수정할 수도 stringsSeen
있지만 더 길고 더 복잡한 메서드의 경우 먼저 모든 인수가 유효한지 확인한 다음 상태를 수정하는 것이 유용 할 수 있습니다.
public void accept(String s) {
checkNotNull(s); // that is, s != null is a precondition of the method
stringsSeen++;
totalLengthSeen += s.length();
}
myObject.getAnything();
(which might cause a NullPointerException if myObject is null)
No... it will throw NPE whenever myObject == null
. In Java, there's no chance of calling a method with null
receiver (a theoretical exception are static methods, but they can and should be always called without any object).
I should use
checkNotNull(myObject).getAnything();
No you should not. This would be rather redundant (Update).
You should use checkNotNull
in order to fail fast. Without it, you may pass an illegal null
to another method, which passes it further, and so on and so on, where it finally fails. Then you can need some good luck to find out that actually the very first method should have refused null
.
The answer by yshavit mentions an important point: Passing an illegal value is bad, but storing it and passing it later is even worse.
Update
Actually,
checkNotNull(myObject).getAnything()
makes sense, too, as you clearly express your intent to not accept any nulls. Without it, someone could think that you forgot the check and convert it into something like
myObject != null ? myObject.getAnything() : somethingElse
OTOH, I don't think the check is worth the verbosity. In a better language, the type system would consider nullability and give us some semantic sugar like
myObject!!.getAnything() // checkNotNull
myObject?.getAnything() // safe call else null
myObject?.getAnything() ?: somethingElse // safe call else somethingElse
for nullable myObject
, while the standard dot syntax would be allowed only when myObject
is known to be non-null.
I have read this whole thread few minutes ago. Nevertheless I was confused why should we use checkNotNull
. Then look over Precondition class doc of Guava and I got what I expected. Excessive use of checkNotNull
will degrade performance definitely.
My thought is checkNotNull
method is worth required for data validation which comes from user directly or very end API to user interaction. It shouldn't be used in each and every methods of internal API because using it you can't stop exception rather correct your internal API to avoid Exception.
According to DOC: Link
Using checkNotNull:
public static double sqrt(double value) {
Preconditions.checkArgument(value >= 0.0, "negative value: %s", value);
// calculate the square root
}
Warning about performance
The goal of this class is to improve readability of code, but in some circumstances this may come at a significant performance cost. Remember that parameter values for message construction must all be computed eagerly, and autoboxing and varargs array creation may happen as well, even when the precondition check then succeeds (as it should almost always do in production). In some circumstances these wasted CPU cycles and allocations can add up to a real problem. Performance-sensitive precondition checks can always be converted to the customary form:
if (value < 0.0) {
throw new IllegalArgumentException("negative value: " + value);
}
참고URL : https://stackoverflow.com/questions/26184322/whats-the-point-of-guava-checknotnull
'IT TIP' 카테고리의 다른 글
셔플 대 영구 numpy (0) | 2020.11.27 |
---|---|
AngularJS 팩토리에서 $ scope에 액세스합니까? (0) | 2020.11.27 |
탭 너비 지정? (0) | 2020.11.27 |
객체에 대한 이전 기대치를 지우는 방법은 무엇입니까? (0) | 2020.11.27 |
JSP에서 함수 선언? (0) | 2020.11.27 |