클래스 메서드에서이 줄을 봤고 첫 번째 반응은이 코드를 작성한 개발자를 조롱하는 것이 었습니다.하지만 저는 먼저 제가 옳은지 확인해야한다고 생각했습니다.
public void dataViewActivated(DataViewEvent e) {
if (this != null)
// Do some work
}
그 라인이 거짓으로 평가 될까요?
클래스 메서드에서이 줄을 봤고 첫 번째 반응은이 코드를 작성한 개발자를 조롱하는 것이 었습니다.하지만 저는 먼저 제가 옳은지 확인해야한다고 생각했습니다.
public void dataViewActivated(DataViewEvent e) {
if (this != null)
// Do some work
}
그 라인이 거짓으로 평가 될까요?
답변:
아니요. 을 사용 this
하는 경우 인스턴스에 있으므로 this
null이 아닙니다.
JLS는 말한다 :
기본 식으로 사용되는 경우 this 키워드는 인스턴스 메서드가 호출 된 개체 (§15.12) 또는 생성중인 개체에 대한 참조 인 값을 나타냅니다.
객체에서 메소드를 호출하면 객체가 존재하거나 이전이있을 것입니다 NullPointerException
(또는 정적 메소드이지만 사용할 수 없습니다 this
).
자원 :
this
인스턴스 메서드의 값이 NULL 일 수 있습니다. 그래서 나는 이것이 자바에서 충분한 이유라고 확신하지 못합니다.
foo.bar()
될 때 발생 foo
합니다 null
. 메서드를 입력하기 전에 발생하지만 실제 이야기는 호출을 시도 할 메서드가 없다는 것입니다.
this
키워드를 사용하고 컴파일하면 관찰 할 때 null이 아닙니다. 그러나 다른 사람들이 메소드를 호출하려고 할 때 NPE를 방지하지 않는다고 말합니다. 예를 들어, 이는 메소드로서의 제어를 완전히 벗어 났으며 메소드 내의 null 검사는 아무것도 변경하지 않습니다.
마치 "내가 살아 있나?"라고 스스로에게 묻는 것과 같습니다. this
null 일 수 없습니다.
this != null
자명 한 것처럼 들리게 만들고 있습니다 . 그렇지 않다 - C ++에서, 예를 들어, this
잘 될 수 NULL
아닌 가상위한 방법.
아니 절대 , 키워드 'this'자체는 해당 클래스의 범위 내에서 해당 클래스의 현재 살아있는 인스턴스 (객체)를 나타내며,이를 사용하여 모든 필드와 멤버 (생성자 포함) 및 부모 클래스의 보이는 항목에 액세스 할 수 있습니다.
그리고 더 흥미롭게도 설정해보세요.
this = null;
그것에 대해 생각해? 당신이 앉아있는 가지를 자르는 것과 같지 않을까요? 키워드 'this'는 클래스 범위 내에서 사용할 수 있으므로 this = null이라고 말하자마자 사용할 수 있습니다. 클래스 내 어느 곳에서나 기본적으로 JVM이 해당 작업을 마친 후 안전하게 돌아와야하기 때문에 JVM이 발생하도록 허용 할 수없는 일부 작업 중간에 해당 객체에 할당 된 메모리를 해제하도록 JVM에 요청합니다.
또한 시도 this = null;
하면 컴파일러 오류가 발생합니다. 이유는 매우 간단합니다. Java (또는 모든 언어)의 키워드에는 값을 할당 할 수 없습니다. 즉, 키워드는 할당 작업의 왼쪽 값이 될 수 없습니다.
다른 예는 다음과 같이 말할 수 없습니다.
true = new Boolean(true);
true = false;
this = null
. 내 인스턴스는 Android에 있었고 뷰를 제거하고 뷰를 처리하는 객체를 null로 설정했습니다. 그런 다음 remove()
실제 뷰를 제거 하는 방법을 사용 하고 핸들러 객체가 쓸모 없게 렌더링되기를 원했기 때문에 null을 원했습니다.
-target 1.3
또는 이전 버전으로 컴파일하는 경우 외부 this
는 null
. 아니면 적어도 예전에는 ...
Outer.this.member
언어가 그것을 강요하는 것만으로는 충분하지 않습니다. VM은이를 시행해야합니다. VM이이를 강제하지 않는 한 Java로 작성된 메소드를 호출하기 전에 널 검사를 강제하지 않는 컴파일러를 작성할 수 있습니다. 인스턴스 메소드 호출을위한 opcode에는 스택에이 참조를로드하는 것이 포함됩니다. http://java.sun.com/docs/books/jvms/second_edition/html/Compiling.doc.html#14787을 참조하십시오 . 이것을 null ref로 대체하면 실제로 테스트가 거짓이됩니다.
정상 this
은 null
실제 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
}
출력은 다음과 같습니다.
outer is Outer@2a139a55
Exception in thread "main" java.lang.NullPointerException
at Outer.main(Outer.java:19)
우리의 시도가를 만들 것을 보여 Inner
로모그래퍼 null
의가 참조 Outer
실패했습니다.
사실, "Pure Java"엔벨로프 안에 집착하면 이것을 깨뜨릴 수 없습니다.
그러나 각 Inner
인스턴스 에는에 대한 참조를 포함 하는 숨겨진 final
합성 필드 (라고 함 "this$0"
)가 있습니다 Outer
. 정말 까다 롭다면 "순수하지 않은"방법 null
을 사용하여 필드 에 할당 할 수 있습니다.
Unsafe
은 그것을 .어느 쪽이든, 최종 결과는 Outer.this
표현식이 2로 평가된다는 것입니다.null
입니다.
즉, 그것은 가능한 자격을 갖춘가 this
될 null
. 그러나 프로그램이 "Pure Java"규칙을 따르는 경우 불가능 합니다.
1-손으로 바이트 코드를 "작성"하고 실제 Java로 전달하거나 BCEL 등을 사용하여 바이트 코드를 조정하거나 원시 코드로 이동하여 저장된 레지스터를 처리하는 등의 트릭을 할인합니다. IMO는 Java가 아닙니다. 가상적으로 이러한 일이 JVM 버그의 결과로 발생할 수도 있습니다.하지만 모든 버그보고를 기억하지는 않습니다.
2-실제로 JLS는 동작이 무엇인지 말하지 않으며 구현에 따라 달라질 수 있습니다.