object == null 또는 null == object?


97

수표 null == object보다 나은 사람에게서 들었어object == null

예 :

void m1(Object obj ) {
   if(null == obj)  // Is this better than object == null ? Why ?
       return ;
   // Else blah blah
}

이유가 있습니까 아니면 이것은 또 다른 신화입니까? 도와 줘서 고마워.


271,561 및 1,957,836의 속는 사람 (이 하나가 '자바'라는 점을 제외하고)
Gishu

20
자바는 C #을 다른
Jijoy

5
이 경우 했다 대폭적인 성능 향상, 다음 확실히 컴파일러가 ... 그것을 최적화 것
안드레아스 돌크

대한 null참조, 행동의 기본 과정은 NPE를 던질 수 있어야합니다. 일부 멋진 라이브러리 (예 : JDK7 Java 라이브러리)에는 public static <T> T notNull(T obj) { if (obj == null) { throw new NullPointerException(); } else { return obj; } }. 이 또한 @NonNull(또는 @Nonnull?),하지만 "삭제"됩니다.
Tom Hawtin-tackline

답변:


140

이것은 아마도 이런 종류의 오타를 피하기 위해 C에서 배운 습관 일 것입니다 ( =double 대신 single ==) :

if (object = null) {

상수를 왼쪽에 두는 규칙은 ==Java에서 실제로 유용하지 않습니다. Java에서는 표현식 ifboolean값을 값으로 평가해야하기 때문에 상수가이면 boolean어떤 식 으로든 컴파일 오류가 발생합니다. 인수. (그리고 그것이 부울이라면 ==어쨌든 사용해서는 안됩니다 ...)


4
오타로 인해 자바에서 컴파일 오류가 발생하기 때문에 자바에게는 매우 유용한 습관이
아닙니다.


3
부울의 경우 @Chandru x.booleanValue()또는 !x.booleanValue(). x == true또는 x == false조건 표현에서 나쁜 냄새, IMHO입니다.
Laurence Gonsalves

2
그는 여기서 null을 확인하고 있습니다. 그리고 null이 true도 false도 아니기 때문에 그가 Boolean에서 null을 확인해야하는 경우가 있습니다.
Chandra Sekar

1
null == object실수로 오타로 객체를 덮어 쓰지 않도록하기 위해 습관적으로 사용 하는 것이 전혀 사용 사례가되어서는 안됩니다. 즉, 이제는 "null"을 먼저 사용하므로 실수를해도 괜찮습니다. 그렇다고 코드가 예상대로 작동한다는 의미는 아닙니다. 해도 null = object의 장소에 제시되어 null == object예상대로 프로그램이 작동하지 않을! 그렇다면이 대회를 따를 필요가 없습니다!
VanagaS

33

다른 사람들이 말했듯이 오타를 피하기 위해 C에서 배운 습관입니다. C에서도 경고를 줄만큼 충분히 높은 경고 수준의 괜찮은 컴파일러를 기대합니다. Chandru가 말했듯이 이러한 방식으로 Java의 null과 비교하면 유형의 변수를 사용하는 경우에만 문제가 발생합니다 Boolean(샘플 코드에 없음). 이것은 매우 드문 상황이며 다른 곳에서 코드를 작성하는 방식을 변경할 가치가있는 상황은 아닙니다. (이 경우에도 피연산자를 뒤집는 것을 귀찮게하지 않을 것입니다. 그 반대를 고려할만큼 명확하게 생각하고 있다면 등호를 셀 수있을 것입니다.)

무엇 않은 언급하는 것은 많은 사람들이 (자신을 확실히 포함)을 찾을 수 있다는 것입니다 if (variable == constant)그것은 자신을 표현하는 자연스러운 방법 - 더 읽을 수 있도록 양식을. 이것이 C의 관례를 맹목적으로 모방 하지 않는 이유 입니다. 한 환경에서 유용 할 수있는 것이 다른 환경에서 유용하다고 가정하기 전에 항상 관행에 대해 질문해야합니다.


3
나는 당신이 특히 "맹목적으로 관례를 베끼는"부분을 말한 모든 단어에 동의합니다. 나는 지금 코드를 읽고 있는데 null = object 스타일은 나를 너무 짜증나게해서 찾아서 여기에 왔습니다. 코더는 어떻게 생각 했나요?
Adrian M

28

이것은 객체 유형이 인 경우를 제외하고는 Java (1.5+)에서 그다지 가치가 없습니다 Boolean. 어떤 경우에도 이것은 여전히 ​​편리 할 수 ​​있습니다.

if (object = null)객체가 있으면 Java 1.5 이상에서 컴파일 실패가 발생하지 Boolean않지만 NullPointerException런타임에 발생합니다.


아마도 컴파일 실패를 일으킬 것이라고 생각했을 것입니다. :)
vava

7
아니요, 개체가 부울 일 때 컴파일 오류가 발생하지 않습니다.
Chandra Sekar

Boolean을 제외한 모든 객체 유형에 대해 동일하지 않습니까?
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功 2015 년

2
부울이 아닌 유형의 경우 "object = null"표현식의 유형이 부울이 아니므로 코드가 컴파일되지 않습니다. 자동 박싱으로 인해 부울 용으로 컴파일됩니다.
Chandra Sekar 2015 년

그런데 왜 Boolean이 이런 행동을하는 걸까요? 근거가 있습니까?
Rohit Banga

9

자바에는 타당한 이유가 없습니다.

다른 몇 가지 답변은 평등 대신 실수로 할당 할 수 있기 때문이라고 주장했습니다. 그러나 Java에서는 if에 부울이 있어야합니다.

if (o = null)

컴파일되지 않습니다.

이것이 Java에서 문제가 될 수있는 유일한 경우는 변수가 부울 인 경우입니다.

int m1(boolean x)
{
    if (x = true)  // oops, assignment instead of equality

4
그런데 왜 당신은 이제까지 작성합니다 == true동등하게 나 == true == true.
Tom Hawtin-tackline

7
글을 쓸 이유가 없습니다 == true. 그러나 나는 내 경력에서 너무 많은 나쁜 코드를 보았 기 때문에 더 이상 누군가가 무언가를 작성하는 이유를 묻지 않고 일부 사람들이 불필요하고 의심스러운 코드를 작성했다는 사실을 인정합니다.
R Samuel Klatchko

1
사실, 주위를 비행하는 가난한 많은 코드가있을 고려할 때, 여전히 x == true이 실수로 기록 될 수 있기 때문에 나쁜대로 x = true,로 변경 훨씬 의미가 없을 것 true == x대신 단지 x.
Holger

9

이것은 또한 다음과 밀접한 관련이 있습니다.

if ("foo".equals(bar)) {

NPE를 다루고 싶지 않은 경우 편리합니다.

if (bar!=null && bar.equals("foo")) {

편리 할 수 ​​있지만 위험 할 수 있습니다 blue-walrus.com/2010/11/…
Oliver Watkins

@OliverWatkins :이 기사가 약하다고 생각합니다. 변수가 int 유형이라고 가정합니다. 초기화되지 않은 상태로두면 값은 0이되고 기사의 약속은 유지되지 않습니다. 문자열이 객체이고 정수가 원시적이라는 사실은 프로그래머가 변수를 초기화하는 것을 잊을 수 있다는 사실과는 무관합니다. 이 질문에서 우리는 단순히 null String 비교 문제를 해결합니다.
cherouvim 2014 년

사실 @cherouvim int기본 유형이 있다 가 호출에서는 불가능하기 때문에, 중요한 equalsint용도에 아니던 논의 아무 소용이 없다, 따라서, x.equals(constant)또는 constant.equals(x)에 대한 int값. 그리고에 대한 Integer값을 기본 값입니다 null보다는 0.
Holger

5

이 트릭 v = null은 일종의 오타 를 방지하기위한 것입니다.

그러나 Java는 if()조건으로 부울 표현식 만 허용 하므로 트릭이별로 의미가 없으므로 컴파일러는 어차피 오타를 찾습니다.

그래도 C / C ++ 코드에서는 여전히 귀중한 트릭입니다.


3

같은 이유로 C에서 수행합니다. 할당은 표현식이므로 리터럴을 왼쪽에 배치하여 실수로 =대신을 사용하는 경우 덮어 쓰지 않도록합니다 ==.


그래도 부울 유형에 대한 Java의 문제 일뿐입니다. 다른 유형의 할당에는 부울 유형이 없으므로 컴파일러 오류가 발생해야합니다.
Scott Smith

1
아니, 자바 컴파일러는 당신이 선호하는 어떤 순서 오타의 종류 잡을 것
vava

@Jijoy-나는 이것이 성능과 관련이 없다고 생각합니다. 이것은 조건부 표현 내에서 무서운 할당 실수를 피하기 위해 C에서 오래된 트릭처럼 들립니다. 이 아이디어는 xequals 인지 확인하려고 할 5때 실수로를 입력 if (x = 5)하면 조용히 컴파일됩니다 ( true값에 관계없이 항상으로 평가됩니다 x). 그러나 항상 리터럴을 먼저 지정하는 습관을들이는 경우 : 'if (5 = x)', 컴파일러는 작업을 다시 확인하고 디버거에서 시간을 절약 할 수 있습니다. 현대 컴파일러는 이러한 습관을 불필요하게 만듭니다.
스콧 스미스

6
-1 : 실수로 =를 사용하면 Java로 컴파일되지 않습니다. 그래서 C의 이유는 적용되지 않습니다.
Jon Skeet

기술적 obj으로 유형 java.lang.Boolean(big B)이면 차이를 만들 수 있습니다 (실제로 시도하지 않았거나 아무것도하지 않은 것 같습니다).
Tom Hawtin-tackline

3

그것은 왼쪽에 상수를 선호하는 사람들을위한 것입니다. 대부분의 경우 상수가 왼쪽에 있으면 NullPointerException이 throw되거나 다른 null 검사가 발생하지 않습니다. 예를 들어 String 메서드 equals는 null 검사도 수행합니다. 왼쪽에 상수가 있으면 추가 수표를 작성할 수 없습니다. 다른 방식으로도 나중에 수행됩니다. 왼쪽에 null 값이 있으면 일관성이 있습니다.

처럼:

 String b = null;
 "constant".equals(b);  // result to false
 b.equals("constant");  // NullPointerException
 b != null && b.equals("constant");  // result to false

NPE이 숨어은 버그 다운 스트림 찾기도 어렵게 만듭니다
올리버 왓킨스

2

다른 방식으로 쓰는 요다 조건

자바에서

String myString = null;
if (myString.equals("foobar")) { /* ... */ } //Will give u null pointer

요다 상태

String myString = null;
if ("foobar".equals(myString)) { /* ... */ } // will be false 

1

다음 코드와 비교하십시오.

    String pingResult = "asd";
    long s = System.nanoTime ( );
    if ( null != pingResult )
    {
        System.out.println ( "null != pingResult" );
    }
    long e = System.nanoTime ( );
    System.out.println ( e - s );

    long s1 = System.nanoTime ( );
    if ( pingResult != null )
    {
        System.out.println ( "pingResult != null" );
    }
    long e1 = System.nanoTime ( );
    System.out.println ( e1 - s1 );

출력 (다중 실행 후) :

null != pingResult
325737
pingResult != null
47027

따라서 pingResult != null승자입니다.


7
추가 루프에서 테스트를 실행하십시오! 또는 IF 문을 전환하십시오. 짧게 말하면 차이가 없습니다! 첫 번째 루프는 항상 느립니다.
Marcel Jaeschke 2012 년

이 테스트에서 pingResult는 항상 null이 아닙니다. pingResult가 null 인 타이밍은 어떻게됩니까? 나는 그것이 플랫폼 독립적이라고 확신하지만, 내 Oracle Java 1.6 / Linux 스택에서는 pingResult가 null 인 경우 두 검사가 모두 몇 퍼센트 빠르다는 점을 제외하면 결과가 거의 균일합니다 (루프).
Ogre Psalm33 2013-08-02

1
! 당신이 "! pingResult = 널 블록 널 전에 = pingResult 블록이이 같은됩니다"pingResult을 NULL = 325737 "넣어 경우
솔라 양

@Sola Yang이 말했듯이 pingResult! = null을 앞에 넣으면 null! = pingResult보다 시간이 더 걸린다는 것을 알 수 있습니다. pingResult! = null이 null보다 빠르면! = pingResult IDE (IntelliG, Eclipse 등)는 개발자가이 역할을 사용하도록 강제하라는 경고를 표시합니다.;)
adil.hilmi

1

교환 속성 때문에 object == nullnull == object( Yoda 버전 ) 의 유일한 차이점 은 인지 적 특성입니다 . 코드를 읽는 사람이 코드를 읽고 소화하는 방법입니다. 나는 확실한 답을 모르지만, 내가 검사하는 객체와 다른 것을 비교하는 것보다 내가 검사하는 객체를 다른 것과 비교하는 것을 개인적으로 선호한다는 것을 알고 있습니다. 주제로 시작한 다음 비교할 값으로 시작합니다.

다른 언어에서는이 비교 스타일이 더 유용합니다.

그러나 일반적으로 누락 된 "="기호를 방지하기 위해 글쓰기 null == object방어 프로그래밍 의 잘못된 행위 라고 생각 합니다 . 이 특정 코드를 우회하는 더 좋은 방법은 junit 테스트로 동작을 보장하는 것입니다. "="가 누락 될 수있는 실수는 메소드의 입력 인수에 의존하지 않습니다. 다른 사람이이 API를 올바르게 사용 하느냐에 의존하지 않습니다. 따라서 junit 테스트가 그 대신에 완벽하게 보호 할 수 있습니다. 어쨌든 동작을 확인하기 위해 junit 테스트를 작성하고 싶을 것입니다. 누락 된 "="는 당연히 범위 내에 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.