.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つの署名が書き込まれ、コンパイラは別の署名を置き換えます。



All Articles