クラスメソッドでこの行を見て、私の最初の反応は、それを書いた開発者をあざ笑うことでした。
public void dataViewActivated(DataViewEvent e) {
if (this != null)
// Do some work
}
その行はfalseと評価されますか?
クラスメソッドでこの行を見て、私の最初の反応は、それを書いた開発者をあざ笑うことでした。
public void dataViewActivated(DataViewEvent e) {
if (this != null)
// Do some work
}
その行はfalseと評価されますか?
回答:
いいえ、できません。を使用this
している場合は、インスタンスにいるのでthis
nullではありません。
JLSは言う:
キーワードthisは、1次式として使用される場合、インスタンスメソッドが呼び出されたオブジェクト(§15.12)、または構築されるオブジェクトへの参照である値を示します。
オブジェクトからメソッドを呼び出した場合、オブジェクトが存在するか、NullPointerException
前に存在することになります(または、静的メソッドですが、その中では使用できませんthis
)。
リソース:
this
インスタンスメソッドのNULLになる可能性があります。したがって、これがJavaで十分な理由であるとは私はまったく確信していません。
foo.bar()
れたときにスローされるようなのnullポインタ例外。メソッドに入る前に発生しますが、実際には、呼び出すメソッドはありません。foo
null
this
キーワードを使用していて、それがコンパイルされた場合、それを観察してもnullではありません。しかし、他の人が言うように、それはメソッドを呼び出そうとするときのNPEを妨げません。たとえば、それはメソッドとして完全に制御不能であり、メソッド内のnullチェックは何も変更しません。
「私は生きているのか」と自問するようなものです。this
nullになることはありません
this != null
自明のように聞こえますか。そうでない- C ++では、例えば、this
十分であり得るNULL
非仮想メソッドのために、。
いいえ、キーワード 'this'自体は、そのクラスのスコープ内にあるそのクラスの現在有効なインスタンス(オブジェクト)を表します。これにより、すべてのフィールドとメンバー(コンストラクターを含む)およびその親クラスの表示可能なインスタンスにアクセスできます。
さらに興味深いことに、設定してみてください。
this = null;
それについて考えますか?どうしてそれが可能になるのか、それはあなたが座っている枝を切るようなものではないでしょうか。キーワード 'this'はクラスのスコープ内で使用できるため、this = null;と言うとすぐに、クラス内の任意の場所で、基本的には、JVMに操作の途中でそのオブジェクトに割り当てられたメモリを解放するように要求します。この操作は、JVMがその操作の終了後に安全に戻る必要があるため、発生させることができません。
また、実行しようとthis = null;
するとコンパイラエラーが発生します。理由は非常に単純です。Java(または任意の言語)のキーワードに値を割り当てることはできません。つまり、キーワードを割り当て操作の左側の値にすることはできません。
他の例では、あなたは言うことができません:
true = new Boolean(true);
true = false;
this = null
。私のインスタンスはandroidで、ビューを削除し、ビューを処理するオブジェクトをnullに設定したいと考えていました。次にremove()
、実際のビューを削除してハンドラーオブジェクトが役に立たなくなるようにするメソッドを使用したかったので、それをnullにしたかったのです。
言語がそれを強制するだけでは十分ではありません。VMはそれを強制する必要があります。VMがそれを実施しない限り、Javaで作成されたメソッドを呼び出す前に、nullチェックを実施しないコンパイラーを作成できます。インスタンスメソッド呼び出しのオペコードには、this refをスタックにロードすることが含まれます。http: //java.sun.com/docs/books/jvms/second_edition/html/Compiling.doc.html#14787を参照してください。これをnull参照に置き換えると、実際にテストは偽になります
法線this
がnull
実際のJavaコードに含まれることはありません1。また、例では法線を使用していますthis
。詳細については、他の回答を参照してください。
資格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
式がnull
2に評価されます。
つまり、資格を持つことが可能です。ただし、プログラムが「Pure Java」の規則に従っている場合は不可能です。this
null
1-手作業でバイトコードを「書き込み」、実際のJavaとして渡す、BCELなどを使用してバイトコードを微調整する、ネイティブコードにホップして保存されたレジスタを操作するなどのトリックを無視します。IMO、それはJavaではありません。仮に、そのようなことはJVMのバグの結果としても発生する可能性があります。
2-実際には、JLSは動作がどうなるかを述べておらず、とりわけ実装に依存している可能性があります。