web-dev-qa-db-ja.com

Javaのa.getClass()とA.classの違いは何ですか?

Java a.getClass()またはA.classを使用する選択を取り巻く長所/短所は何ですか?Class<?>が期待されるところならどこでも使用できますが、異なる状況で両方を使用することによる他の微妙な利点(Class.forName()およびClassLoader.loadClass()の場合と同様です。

97
IAmYourFaja

長所/短所の点でそれらを比較することはありません。なぜならそれらには異なる目的があり、2つの間で「選択」することはめったにないからです。

  • a.getClass()は、aランタイムタイプを返します。つまり、A a = new B();がある場合、a.getClass()Bクラスを返します。

  • A.classAクラスstaticallyに評価され、反射に関連することが多い他の目的に使用されます。

パフォーマンスの面では、[mayには測定可能な差がありますが、最終的にはJVMやコンパイラに依存するため、それについては何も言いません。


この投稿は記事として書き直されました here

155
aioobe

実際には、どこで使用できるかによって異なります。 _A.class_はコンパイル時に機能しますが、a.getClass()A型のインスタンスを必要とし、実行時に機能します。

パフォーマンスの違いもあります。 _A.class_はAの実際の型を知っているため、コンパイラによって解決できますが、a.getClass()は実行時に発生する仮想メソッド呼び出しです。

参考までに、バイトコードをターゲットとするコンパイラは通常、Integer.getClass()に対して次の命令を発行します。

_aload_1
invokevirtual   #3; //Method Java/lang/Object.getClass:()Ljava/lang/Class;
_

および_Integer.class_の場合:

_//const #3 = class  #16;    //  Java/lang/Integer

ldc_w   #3; //class Java/lang/Integer
_

前者は通常、仮想メソッドのディスパッチを伴うため、おそらく実行に時間がかかります。ただし、最終的にはJVMに依存します。

32

以下の例をご覧ください

a.getClass()!= A.class、つまりaはAのインスタンスではなく、Aの匿名サブクラスのインスタンスです

a.getClass()にはタイプAのインスタンスが必要です

6

クラス/タイプのインスタンスがあり、その正確なタイプを取得する場合は、a.getClassを使用します。 a.classは、typeが使用可能で、そのインスタンスを作成するときに使用されます。
また、getClass()はインスタンスのランタイムタイプを返しますが、.classはコンパイル時に評価されます。
getClass()および.class.classのパフォーマンスを考慮すると、getClass()よりもパフォーマンスが向上します。
例:

public class PerfomanceClass {

    public static void main(String[] args) {
        // TODO Auto-generated method stub

        long time=System.nanoTime();
        Class class1="String".getClass();
        class1="String".getClass();
        class1="String".getClass();
        class1="String".getClass();

        System.out.println("time (getClass()) :"+(System.nanoTime()-time)+" ns");     


        long time2=System.nanoTime();
        Class class2=String.class;
        class2=String.class;
        class2=String.class;
        class2=String.class;

        System.out.println("time (.class):"+(System.nanoTime()-time2)+" ns");
    }

}

出力:

time (getClass()) : 79410 ns
time (.class)     : 8032 ns
4
Rohan

追加したい違いが1つあります。以下に示すように、Classオブジェクトを受け取るスーパークラスを持つクラスのコンストラクタがあるとします。サブクラスオブジェクトが作成されるたびに、サブクラスのクラスオブジェクトをスーパークラスに渡す必要があります。以下のコードは、コンストラクターでインスタンスメソッドを呼び出すことができないため、コンパイルされません。その場合、myObject.getClass()MyClass.classに置き換えると。完全に実行されます。

Class MyClass
{
    private MyClass myObject = new MyClass();
    public MyClass()
    {
        super(myObject.getClass()); //error line compile time error
    }
}
1
prashant

p.getClass()は、pがオブジェクトのインスタンスである場合、このオブジェクトpのランタイムクラスを返します。 pは、コンパイル時エラーを引き起こすタイプにすることはできません。オブジェクトのインスタンスである必要があります。

_// B extends A
A a = new B();
System.out.println(a.getClass());
//output: class B
_

_p.class_は式です。 _.class_はクラス構文と呼ばれます。 pはタイプです。クラス、インターフェイス、または配列の名前、さらにはプリミティブ型を指定できます。 a.getClass() == B.class

型が使用可能で、インスタンスがある場合、getClassメソッドを使用して型の名前を取得できます。それ以外の場合は、_.class_構文を使用します

0
triplestone

興味深いことに、上記の例で述べたパフォーマンスの違いは、他の理由に関連しているようです。 3つの異なるクラスを使用すると、平均してパフォーマンスはほぼ同じになります。

_import Java.util.LinkedHashMap;
public class PerfomanceClass {

public static void main(String[] args) {

    long time = System.nanoTime();
    Class class1 = "String".getClass();
    Class class11 = "Integer".getClass();
    Class class111 = "LinkedHashMap".getClass();

    System.out.println("time (getClass()) :" + (System.nanoTime() - time) + " ns");

    long time2 = System.nanoTime();
    Class class2 = String.class;
    Class class22 = Integer.class;
    Class class222 = LinkedHashMap.class;

    System.out.println("time (.class):" + (System.nanoTime() - time2) + " ns");
} }
_

出力は次のようになります。

_time (getClass()) :23506 ns 
time (.class):23838 ns
_

また、呼び出しの順序を切り替えると、getClass()が高速になります。

_import Java.util.LinkedHashMap;

public class PerfomanceClass {

public static void main(String[] args) {
    long time2 = System.nanoTime();
    Class class2 = LinkedHashMap.class;

    System.out.println("time (.class):" + (System.nanoTime() - time2) + " ns");

    long time = System.nanoTime();
    Class class1 = "LinkedHashMap".getClass();

    System.out.println("time (getClass()) :" + (System.nanoTime() - time) + " ns");
}}
_

出力:

_time (.class):33108 ns
time (getClass()) :6622 ns
_
0
user4287932