Javaでは、どのような長所/短所が使用する選択肢を取り巻く存在しますa.getClass()
かA.class
?どちらもa Class<?>
が期待されるところならどこでも使用できますが、(Class.forName()
やと同じように)異なる状況で両方を使用するとパフォーマンスや他の微妙な利点があると思いClassLoader.loadClass()
ます。
Javaでは、どのような長所/短所が使用する選択肢を取り巻く存在しますa.getClass()
かA.class
?どちらもa Class<?>
が期待されるところならどこでも使用できますが、(Class.forName()
やと同じように)異なる状況で両方を使用するとパフォーマンスや他の微妙な利点があると思いClassLoader.loadClass()
ます。
回答:
賛否両論の観点から比較することはしません。なぜなら、目的が異なり、2つの間に「選択」することはほとんどないためです。
a.getClass()
のランタイムタイプを返しますa
。つまり、あなたが持っている場合A a = new B();
、次にa.getClass()
返しますB
クラスを。
A.class
評価A
クラス静的に、しばしば反射に関連する他の目的のために使用されます。
パフォーマンスの点では測定可能な違いがあるかもしれませんが、結局それはJVMやコンパイラーに依存しているのでそれについては何も言わないでしょう。
この投稿は、こちらの記事に書き直されました。
Class
により、A.class
再びのインスタンスであるオブジェクトを表すクラスのオブジェクトが得られますjava.lang.Class
。
A.getClass().class
ですか?
A
クラスである場合、それは本当に意味がありません。getClass
クラスに静的メソッドはありません。
実際に使用できる場所は異なります。タイプのインスタンス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に依存します。
以下の例を見てください
a.getClass()!= A.class
つまり、aはAのインスタンスではなく、Aの匿名サブクラスのインスタンスです。
a.getClass()
タイプAのインスタンスが必要
a.getClass
クラス/タイプのインスタンスがあり、その正確なタイプを取得したい場合に使用します。while 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
追加したい違いが1つあります。Classオブジェクトを受け取るスーパークラスを使用して、以下に示すようなコンストラクターのクラスがあるとします。サブクラスオブジェクトが作成されるたびに、サブクラスのクラスオブジェクトをスーパークラスに渡す必要があります。以下のコードは、コンストラクターでインスタンスメソッドを呼び出すことができないため、コンパイルされません。その場合、あなたは交換した場合myObject.getClass()
にMyClass.class
。それは完全に実行されます。
Class MyClass
{
private MyClass myObject = new MyClass();
public MyClass()
{
super(myObject.getClass()); //error line compile time error
}
}
興味深いことに、上記の例で述べたパフォーマンスの違いは、他の理由に関連しているようです。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
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
構文を使用します
A.class.getClass()
ですか?