.getClass()が返すものを知っていますか?

ほとんどのJava開発者は、インタビューで「Objectクラスのメソッドは何ですか?」
少なくとも繰り返し聞かれました。 そして、初めて驚きだった場合(クローンを忘れていたと思う)、Objectのメソッドを既に知っていると確信しました;)

そして、数年にわたる開発の後、getClass()メソッドのシグネチャについて自分自身が無知になったとき、私は驚きました

猫の下で、Class、.class、.getClass、そして実際に私が出会った驚きについてのいくつかの言葉。


したがって、クラスAとこのクラスaのオブジェクトがあります。
public class A { } ... A a = new A(); 


0. A.classとa.getClass()


簡単なものから始めましょう。 getClass()を呼び出すと、ポリモーフィズムが解決され、結果は子孫クラスになります。
 public class B extends A { { ... A a1 = new B(); a1.getClass(); //   ,  B.class 


非表示のテキスト
コメントで私に指摘された嘘があった。 classは静的フィールドではなく、静的フィールドではなく(また、私が考えたように、ネイティブ疑似静的フィールドでさえありません)、言語の特別な構成です。 また、静的フィールドとは異なり、オブジェクトを介してアクセスすることはできません!
 a.class; // Compile error! Unknown class: "a" 



しかし、これはそうです、花。 どうぞ

1.そして、これはあなたのクラスですか?


A.class-クラスClassのオブジェクト。 Class.javaを調べます。
 public final class Class<T> implements ... 

これはジェネリックです。 そして、それは明らかに、このまさにクラス-.classの呼び出し元である

考えてみると、なぜこれが必要なのかは明らかです。特に、引数に応じて、任意の型を返すメソッドを作成できます。
 public <T> T foo(Class<T> clazz); 

A.classは、クラスClassのオブジェクトを返します。
 Class<A> result = A.class; // Compilation successfull 


2.そして、a.getClass()は何を返しますか?


上記のすべてを収集すると、次のように推測できます。
 Class<A> result1 = a.getClass(); // Compilation error! 

実際、多相性の観点から、オブジェクトaの実際のクラス-必ずしもAではない-が任意のサブクラスであることを忘れてはなりません。
 Class<? extends A> result = a.getClass(); // Compilation successfull 


3.そして、Object.javaには何が書かれていますか?


これらのジェネリックはすべて素晴らしいのはもちろんですが、Objectクラスでjava構文を使用してgetClassメソッドのシグネチャをどのように記述しますか?
しかし、決して:
 public final native Class<?> getClass(); 

そして、なぜ上記の例がコンパイルされなかったのかという質問に対して、メソッドに対するMaxim Potashev javadokは答えます:
実際の結果タイプはClass <? 拡張| X |>どこ| X | getClassが呼び出される式の静的型の消去です。


そのため、Object.javaには1つの署名が書き込まれ、コンパイラは別の署名を置き換えます。

Source: https://habr.com/ru/post/J197802/


All Articles