IT story

Java에서 "this"가 null 일 수 있습니까?

hot-time 2020. 8. 8. 10:00
반응형

Java에서 "this"가 null 일 수 있습니까?


클래스 메서드에서이 줄을 봤는데 첫 번째 반응은이 코드를 작성한 개발자를 조롱하는 것이 었습니다.하지만 저는 먼저 제가 옳은지 확인해야한다고 생각했습니다.

public void dataViewActivated(DataViewEvent e) {
    if (this != null)
        // Do some work
}

그 라인이 거짓으로 평가 될까요?


아니요. 을 사용 this하는 경우 인스턴스에 있으므로 thisnull이 아닙니다.

JLS는 말한다 :

기본 식으로 사용되는 경우 this 키워드는 인스턴스 메서드가 호출 된 개체 (§15.12) 또는 생성중인 개체에 대한 참조 인 값을 나타냅니다.

객체에서 메소드를 호출 한 경우 객체가 존재하거나 이전이있을 것입니다 NullPointerException(또는 정적 메소드이지만 사용할 수 없음 this).


자원 :


스스로에게 "내가 살아 있나?"라고 묻는 것과 같습니다. thisnull 일 수 없음


아니요 , 키워드 'this'자체는 해당 클래스의 범위 내에서 해당 클래스의 현재 살아있는 인스턴스 (객체)를 나타내며,이를 사용하여 모든 필드와 멤버 (생성자 포함) 및 부모 클래스의 보이는 항목에 액세스 할 수 있습니다.

그리고 더 흥미롭게도 설정해보세요.

this = null;

그것에 대해 생각해? 당신이 앉아있는 가지를 자르는 것과 같지 않습니까? 키워드 'this'는 클래스 범위 내에서 사용할 수 있으므로 this = null이라고 말하자마자 사용할 수 있습니다. 클래스 내 어느 곳에서나 기본적으로 JVM이 해당 작업을 마친 후 안전하게 돌아올 필요가 있기 때문에 JVM이 발생하도록 허용 할 수없는 일부 작업 중간에 해당 객체에 할당 된 메모리를 해제하도록 JVM에 요청합니다.

또한 시도 this = null;하면 컴파일러 오류가 발생합니다. 이유는 매우 간단합니다. Java (또는 모든 언어)의 키워드에는 값을 할당 할 수 없습니다. 즉, 키워드는 할당 작업의 왼쪽 값이 될 수 없습니다.

다른 예는 다음과 같이 말할 수 없습니다.

true = new Boolean(true);
true = false;

-target 1.3또는 이전 버전으로 컴파일하는 경우 외부 thisnull. 아니면 적어도 예전에는 ...


아니요. 클래스 인스턴스의 메서드를 호출하려면 인스턴스가 존재해야합니다. 인스턴스는에서 참조하는 메서드에 매개 변수로 암시 적으로 전달됩니다 this. 만약이 thisnull다음의 메소드를 호출 할 인스턴스가 없었을 것입니다.


언어가 그것을 강요하는 것만으로는 충분하지 않습니다. VM은이를 시행해야합니다. VM이 강제하지 않는 한 Java로 작성된 메소드를 호출하기 전에 널 검사를 강제하지 않는 컴파일러를 작성할 수 있습니다. 인스턴스 메소드 호출을위한 opcode에는 스택에이 참조를로드하는 것이 포함됩니다. http://java.sun.com/docs/books/jvms/second_edition/html/Compiling.doc.html#14787을 참조하십시오 . 이것을 null ref로 대체하면 실제로 테스트가 거짓이됩니다.


정적 클래스 메서드에서는 클래스 this가 아닌 this인스턴스와 연결되어 있으므로 정의 되지 않습니다. this정적 컨텍스트에서 키워드 를 사용하려고 시도하면 컴파일러 오류가 발생할 것이라고 생각합니다 .


null참조에서 메소드를 호출하면 NullPointerExceptionJava VM에서이 메소드 가 발생합니다. 자바 VM이 엄격하게 사양을 준수하는지, 그래서 이것은 사양입니다 this수 없을 것입니다 null.


정상 thisnull실제 Java 코드 1이 될 수 없으며 예제는 정상을 사용합니다 this. 자세한 내용은 다른 답변을 참조하십시오.

A는 자격을 this 해야 결코 null하지만,이 휴식 할 수 있습니다. 다음을 고려하세요:

public class Outer {
   public Outer() {}

   public class Inner {
       public Inner() {}

       public String toString() {
           return "outer is " + Outer.this;  // Qualified this!!
       }
   }
}

의 인스턴스를 만들려면 다음 Inner을 수행해야합니다.

public static void main(String[] args) {
    Outer outer = new Outer();
    Inner inner = outer.new Inner();
    System.out.println(inner);

    outer = null;
    inner = outer.new Inner();  // FAIL ... throws an NPE
}

The output is:

outer is Outer@2a139a55
Exception in thread "main" java.lang.NullPointerException
        at Outer.main(Outer.java:19)

showing that our attempt to create an Inner with a null reference to its Outer has failed.

In fact, if you stick within the "Pure Java" envelope you cannot break this.

However, each Inner instance has a hidden final synthetic field (called "this$0") that contains the reference to the Outer. If you are really tricky, it is possible to use "non-pure" means to assign null to the field.

  • You could use Unsafe to do it.
  • You could use native code (e.g. JNI) to do it.
  • You could do it by using reflection.

Either way you do it, the end result is that the Outer.this expression will evaluate to null2.

In short, it is possible for a qualified this to be null. But it is impossible if your program follows the "Pure Java" rules.


1 - I discount tricks such as "writing" the bytecodes by hand and passing them off as real Java, tweaking bytecodes using BCEL or similar, or hopping into native code and diddling with the saved registers. IMO, that is NOT Java. Hypothetically, such things might also happen as a result of a JVM bug ... but I don't recall every seeing bug reports.

2 - Actually, the JLS does not say what the behavior will be, and it could be implementation dependent ... among other things.


If the method is static, then there isn't any this. If the method is virtual, then this cannot be null, because in order to call the method, the run-time will need to reference the vtable using the this pointer. If the method is not virtual then, yes, it is possible that this is null.

C# and C++ allow non-virtual methods, but in Java all non-static methods are virtual, so this will never be null.


tl;dr, "this" can only be called from a non-static method and we all know that a non-static method is called from some sort of object which cannot be null.

참고URL : https://stackoverflow.com/questions/3789528/can-this-ever-be-null-in-java

반응형