Вопрос по java, class, reflection – В чем разница между a.getClass () и A.class в Java?

94

В Java какие плюсы / минусы существуют вокруг выбора использованияa.getClass() или жеA.class? Любой может быть использован везде, гдеClass<?> ожидается, но я предполагаю, что производительность и другие тонкие преимущества могут быть использованы при разных обстоятельствах (как в случае сClass.forName() а такжеClassLoader.loadClass().

Ваш Ответ

6   ответов
1

Есть одно отличие, которое я хотел бы добавить. Допустим, у вас есть класс конструктор, как показано ниже, с суперклассом, который принимает объект Class. Вы хотите, чтобы при создании объекта подкласса subClass & apos; Объект класса должен быть передан суперклассу. Код ниже не скомпилируется, так как вы не можете вызвать метод экземпляра в конструкторе. В этом случае, если вы заменитеmyObject.getClass() сMyClass.class, Это будет работать отлично.

Class MyClass
{
    private MyClass myObject = new MyClass();
    public MyClass()
    {
        super(myObject.getClass()); //error line compile time error
    }
}
Имея экземпляр того же класса, что и переменные экземпляра того же класса .... Вам не хватит места в куче, так как вы рекурсивно создаете объекты.
152

Я бы не сравнивал их с точки зрения плюсов / минусов, поскольку они имеют разные цели и редко бывают «выбором». сделать между двумя.

a.getClass() returns the runtime type of a. I.e., if you have A a = new B(); then a.getClass() will return the B class.

A.class evaluates to the A class statically, and is used for other purposes often related to reflection.

С точки зрения производительности, естьmay будет ощутимой разницей, но я ничего не скажу об этом, потому что в конечном итоге это зависит от JVM и / или компилятора.

Этот пост был переписан как статьяВот.

Как насчетA.class.getClass() ?
Это дало бы вамClass объект класса, представляющегоA.class объект, который снова является экземпляромjava.lang.Class.
6

взгляните на примеры ниже

a.getClass()!= A.classто есть не экземпляр A, а анонимный подкласс из

a.getClass() требуется экземпляр типа A

32

Они на самом деле разные в отношении того, где вы можете их использовать.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.

[1] технически Спецификация языка Java вообще не упоминает какой-либо постоянный пул ...
@aioobe: Думаю, вы правы, поэтому я проверил байт-код, сгенерированный Sun JDK.
... что с технической точки зрения также не дает авторитетного ответа, поскольку в спецификации языка Java даже не упоминается байт-код, когда речь идет о семантике.
Откатитесь, если вам это не нравится ;-)
@aioobe: Я понял вашу точку зрения. Я никогда не упоминал JLS, просто эмпирически проверил, как он работает, как я не был уверен. ОП спрашивает о производительности, и проверка байт-кода казалась хорошей идеей. Не стесняйтесь редактировать мой пост или удалять неоднозначные заявления
0

Интересно, что различия в производительности, упомянутые в приведенном выше примере, по-видимому, связаны с другими причинами. При использовании 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
& quot; Использование 3 разных классов & quot; , Но в разделе getClass () вы не используете 3 разных класса. Все это String, и поэтому getClass вернет java.lang.String для всех экземпляров.
4

использованиеa.getClass когда у вас есть экземпляр класса / типа, и вы хотите получить его точный тип. в то время какa.class используется, когда у вас естьtype доступны, и вы хотите создать экземпляр этого.
ТакжеgetClass() возвращает тип времени выполнения экземпляра.class оценивается во время компиляции.
Учитывая производительностьgetClass() а также.class ,.class имеет лучшую производительность, чемgetClass() .
Example :

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

Похожие вопросы