web-dev-qa-db-ja.com

JavaのgetClassはどのように機能しますか

これが JavaDoc が言うことです:

public final Class <?> getClass()

このObjectの実行時クラスを返します。返されるClassオブジェクトは、表現されたクラスのstatic synchronizedメソッドによってロックされたオブジェクトです。
実際の結果のタイプはClass<? extends |X|>です。ここで|X|は、getClassが呼び出される式の静的タイプの消去です。たとえば、このコードフラグメントではキャストは必要ありません。

Number n = 0;
Class<? extends Number> c = n.getClass();

戻り値:
このオブジェクトのランタイムクラスを表すClassオブジェクト。

今、私はそれがネイティブメソッドであることを理解しているので、プラットフォーム依存のコードで実装されています。しかし、このメソッドの戻り型についてはどうでしょう。

public final Class<?> getClass()

また、コードを検討してください:

class Dog
{
    @Override
    public String toString()
    {
        return "cat";
    }
}

public class Main
{
    public static void main(String[] args)
    {
        Dog d= new Dog();
        //Class<Dog> dd = new Dog();  Compile time error
        System.out.println(d.getClass());
    }
}

出力:

クラス犬

したがって、私のクエリは次の場所にあります:

  1. このメソッドの戻り型
  2. toStringメソッドは呼び出されません。このトピックに関する同様の投稿は、 Javaです。 getClass()はクラスを返しますが、なぜ文字列も取得できますか?
  3. そうでなければコンパイル時エラーを与えるコメント付きコード。
9
Number945

各オブジェクトのデータには、クラスJava.lang.Classのオブジェクトへの参照が含まれており、これはメソッドgetClassによって返されます。 Java.lang.Classを記述する1つのJava.lang.Classオブジェクトもあります。

Classオブジェクトは、オブジェクトの作成元である特定のクラスを説明する「青写真」と考えてください。ブループリントにも独自のブループリントが必要であることは当然のことです(そうでなければ、エンジニアはブループリントを作成する方法をどのようにして知るでしょうか)。

これらのステートメントはこれを説明しようとします。

Integer integer = 1;
Class<?> clazzInteger = integer.getClass();
System.out.println( "class of integer=" + clazzInteger );
Class<?> clazzClazzInteger = clazzInteger.getClass();
System.out.println( "class of class Integer's class=" + clazzClazzInteger );
String string = "x";
Class<?> clazzString = string.getClass();
System.out.println( "class of string=" + clazzString );
Class<?> clazzClazzString = clazzString.getClass();
System.out.println( "class of class String's class=" + clazzClazzString );

出力:

class of integer=class Java.lang.Integer
class of class Integer's class=class Java.lang.Class
class of string=class Java.lang.String
class of class String's class=class Java.lang.Class

ブループリントによって記述されるものにブループリント自体と混同されるべきではない名前があるように、クラスには名前があります。クラスオブジェクトが特定のコンテキストで表示される場合、そのtoString()メソッドが暗黙的に呼び出され、これによりクラスのnameが返されます。クラスの詳細な詳細をすべて印刷したい場合(ブループリント自体を印刷するのと同様)、多くのコードを記述する必要があります。Java.lang.Classのjavadocを見てください。取得する多くの情報(青写真に適しています)。

7
laune

この時点で、型のtypeinstanceを区別する必要があります。例を挙げて説明しましょう。

_    public class A {
        public static void main(String[] args) {
            Class<A> typeInformation = A.class; //Type information associated with type `A`
            A instanceOfA = new A();  //actual instance of type `A`
        }   
    }
_

タイプ

上記のコードの参照 'typeInformation'は、ジェネリックをしばらく脇に置いておくタイプClassです。この情報は通常、非ヒープメモリセクションにあります。以下の情報は、type jvmロードのそれぞれに対して保存されます。

  • タイプの完全修飾名
  • 型の直接スーパークラスの完全修飾名(型がインターフェースまたはクラスJava.lang.Objectでなく、どちらにもスーパークラスがない場合)
  • 型がクラスまたはインターフェースであるかどうか
  • タイプの修飾子( `public、abstract、finalのサブセット)
  • 直接スーパーインターフェースの完全修飾名の順序付きリスト

インスタンス

instaneOfAは、ヒープメモリ内のアドレスを指すA型の実際のインスタンスへの参照です。

GetClass()の戻り値の型は、汎用のClass型です。 Java-String、Integerなどで利用可能な他の多くのtypesと同様に、Classも、関連する型情報を表す型です。

toString()メソッドは、Dogタイプ自体ではなく、Dogクラスのinstanceに関連付けられて呼び出されます。

//Class<Dog> dd = new Dog(); Compile time error

これは、右側の式の結果を同じタイプではない左側に割り当てているときにタイプの不一致が発生したためです。クラスddは、クラスタイプの参照を参照します。 Dogは完全に異なるタイプであり、新しいDog()をタイプ「Dog」の参照に割り当てることができます。

このリンクは、Javaランタイム環境 の設計側面を理解するのに役立ちます

1
deepak marathe

あなたの質問3に答えがあります

これにより、コンパイル時エラーが発生します。

理由1:Classインスタンスの場合、Dogクラスを表すクラスオブジェクトのみを割り当てることができますが、Dogクラスオブジェクトを直接割り当てることはできません。

例:Class dd = Dog.classまたはClass dd = Class.forName( "Dog");正しい構文です。

理由2:クラスClassは最終クラスですが、Dogクラスのスーパークラスではありません。 Javaの動的メソッドディスパッチの概念に戻ります。ここでは、サブクラスオブジェクトをスーパークラス変数にのみ割り当てることができます。

0
Hasitha Solasa