109

a.getClass()在 Java 中,围绕使用or的选择存在哪些优点/缺点A.class?两者都可以在任何Class<?>预期的地方使用,但我想在不同的情况下使用两者都会有性能或其他微妙的好处(就像有Class.forName()ClassLoader.loadClass().

4

7 回答 7

171

我不会比较它们的优缺点,因为它们有不同的目的,而且很少在两者之间做出“选择”。

  • a.getClass()返回 的运行时类型a即,如果你有A a = new B();然后a.getClass()将返回B类。

  • A.class静态评估A类,并用于通常与反射相关的其他目的。

在性能方面,可能存在衡量的差异,但我不会说什么,因为最终它取决于 JVM 和/或编译器。


这篇文章在这里被改写为一篇文章。

于 2012-06-08T11:16:02.110 回答
34

它们在您可以使用它们的位置方面实际上是不同的。A.class在编译时工作,而a.getClass()需要类型的实例A并在运行时工作。

也可能存在性能差异。虽然A.class可以由编译器解析,因为它知道 的实际类型Aa.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。

于 2012-06-08T11:16:40.127 回答
8

看看下面的例子

a.getClass()!= A.class,即 a 不是 A 的实例,而是 A 的匿名子类

a.getClass()需要类型 A 的实例

于 2012-06-08T11:17:46.760 回答
7

a.getClass当你有一个类/类型的实例并且你想得到它的确切类型时使用。当a.classtype有空并且你想创建它的实例时使用。
在编译时评估时还getClass()返回实例的运行时类型。 考虑和的性能,比 具有更好的性能 。例子 :.class
getClass().class.classgetClass()

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
于 2014-06-20T07:09:27.870 回答
1

我想补充一个区别。假设您有一个如下所示的构造函数类,其中包含一个接受 Class 对象的超类。您希望每当创建子类对象时,应将子类的类对象传递给超类。下面的代码将无法编译,因为您不能在构造函数中调用实例方法。在这种情况下,如果您替换myObject.getClass()MyClass.class. 它会完美运行。

Class MyClass
{
    private MyClass myObject = new MyClass();
    public MyClass()
    {
        super(myObject.getClass()); //error line compile time error
    }
}
于 2012-06-08T15:54:49.933 回答
1

有趣的是,上面示例中提到的性能差异似乎与其他原因有关。使用 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
于 2014-11-24T14:37:07.753 回答
1

p.getClass(),其中p是对象的实例,返回此对象的运行时类pp不能是会导致编译时错误的类型,它应该是对象的实例。

// 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语法

于 2019-08-11T07:04:09.237 回答