In Java what pros/cons exist surrounding the choice to use a.getClass()
or A.class
? Either can be used wherever a Class<?>
is expected, but I imagine that there would be performance or other subtle benefits to using both in different circumstances (just like there are with Class.forName()
and ClassLoader.loadClass()
.

- 46,221
- 15
- 164
- 151

- 55,468
- 181
- 466
- 756
7 Answers
I wouldn't compare them in terms of pros/cons since they have different purposes and there's seldom a "choice" to make between the two.
a.getClass()
returns the runtime type ofa
. I.e., if you haveA a = new B();
thena.getClass()
will return theB
class.A.class
evaluates to theA
class statically, and is used for other purposes often related to reflection.
In terms of performance, there may be a measurable difference, but I won't say anything about it because in the end it is JVM and/or compiler dependent.
This post has been rewritten as an article here.

- 413,195
- 112
- 811
- 826
-
4How about `A.class.getClass()` ? – user1870400 Jun 24 '17 at 11:55
-
7That would give you the `Class` object of the class representing the `A.class` object which is again an instance of `java.lang.Class`. – aioobe Jun 24 '17 at 12:32
-
How about `A.getClass().class`? – Shikhar Mainalee Apr 02 '19 at 01:44
-
@ShikharMainalee, that doesn't really make sense if `A` is a class. There's no static `getClass` method on classes. – aioobe Apr 02 '19 at 12:26
-
how does this relate to the suggestion [here](https://stackoverflow.com/a/16571046/231821) that they also point to different class loaders. This might also be a significant difference between the two? – Jim Jul 09 '19 at 06:47
-
What does SomeClass::class returns and it is different than that o SomeClass.class? – Irfan Ul Haq Oct 11 '19 at 08:03
-
@IrfanUlHaq, `SomeClass::class` isn't valid Java code. That won't compile so it won't return anything. – aioobe Oct 11 '19 at 15:10
-
@aioobe Thank you. I really thought `class` was a static variable. This clears things up. – John Strood Dec 10 '20 at 13:43
They are actually different with regards to where you can use them. A.class
works at compile time while a.getClass()
requires an instance of type A
and works at runtime.
There may be a performance difference as well. While A.class
can be resolved by the compiler because it knows the actual type of A
, a.getClass()
is a virtual method call happening at runtime.
For reference, a compiler targeting bytecode typically emits the following instructions for Integer.getClass()
:
aload_1
invokevirtual #3; //Method java/lang/Object.getClass:()Ljava/lang/Class;
and the following for Integer.class
:
//const #3 = class #16; // java/lang/Integer
ldc_w #3; //class java/lang/Integer
The former would typically involve a virtual method dispatch and therefore presumably take longer time to execute. That is in the end JVM-dependent however.

- 413,195
- 112
- 811
- 826

- 334,321
- 69
- 703
- 674
-
1[1] technically the Java Language Specification doesn't mention any constant pool at all... – aioobe Jun 08 '12 at 11:33
-
@aioobe: I guess you are right, that's why I checked the bytecode generated by Sun JDK. – Tomasz Nurkiewicz Jun 08 '12 at 11:35
-
1...which technically speaking does not provide an authoritative answer either, since the Java Language Specification doesn't even mention bytecode when it comes to semantics. – aioobe Jun 08 '12 at 11:37
-
@aioobe: I get your point. I have never mentioned JLS, just empirically checked how it works, as I wasn't sure. The OP asks about performance and examining bytecode seemed like a good idea. Feel free to edit my post or remove ambiguous statements – Tomasz Nurkiewicz Jun 08 '12 at 12:11
-
1
have a look at the examples below
a.getClass()!= A.class
, i.e. a is not an instance of A but of an anonymous sub class
of A
a.getClass()
requires an instance of type A

- 26,379
- 6
- 61
- 70
Use a.getClass
when you have an instance of class/type and you want to get exact type of it. while a.class
is used when you have type
available and you want to create instance of it.
Also getClass()
returns runtime type of instance while .class
is evaluated at compile time.
Considering performance of getClass()
and.class
,.class
has better performance than 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");
}
}
Output :
time (getClass()) : 79410 ns
time (.class) : 8032 ns

- 3,068
- 1
- 20
- 26
There is one difference i would like to add. Let us say you have a class a constructor as shown below with a super class which takes a Class object. You want that whenever a subclass object is created the subClass' class object should be passed to the super class. Below code will not compile as you cannot call an instance method in a constructor. In that case if you replace myObject.getClass()
with MyClass.class
. It will run perfectly.
Class MyClass
{
private MyClass myObject = new MyClass();
public MyClass()
{
super(myObject.getClass()); //error line compile time error
}
}

- 10,519
- 8
- 40
- 45

- 1,382
- 1
- 13
- 19
-
2Having instance of the same class as instance variables of the same class.... You will run out of heap space as you are recursively creating objects. – Aniket Thakur Aug 20 '13 at 09:27
Interestingly the differences in performance mentioned in the example above, seem to be related to other reasons. Using 3 different Classes, in average the performance will be nearly the same :
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");
} }
The Output will be something like :
time (getClass()) :23506 ns
time (.class):23838 ns
And switching the order of the calls will even result in getClass()
being faster.
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");
}}
Output:
time (.class):33108 ns
time (getClass()) :6622 ns

- 27
- 1
-
"Using 3 different Classes" . But in the getClass() section you are not using 3 different classes. These are all String and therefore getClass will return java.lang.String for all instances. – Kilian Jan 20 '18 at 09:29
p.getClass()
, where the p
is an instance of an object, returns the runtime class of this object p
. p
cannot be a type which will cause a compile-time error, it should be an instance of an object.
// B extends A
A a = new B();
System.out.println(a.getClass());
//output: class B
p.class
is an expression. The .class
is called the class syntax. p
is a type. It can be the name of a class, interface or array and even a primitive type.
a.getClass() == B.class
.
If a type is available and there is an instance then it is possible to use getClass
method to get the name of the type. Otherwise, use the .class
syntax

- 11
- 1