The Java Object.getClass()
method javadoc says:
Returns the runtime class of this
Object
. The returnedClass
object is the object that is locked bystatic synchronized
methods of the represented class. The actual result type isClass<? extends |X|>
where|X|
is the erasure of the static type of the expression on whichgetClass
is called. For example, no cast is required in this code fragment:Number n = 0; Class<? extends Number> c = n.getClass();
Returns: The
Class
object that represents the runtime class of this object.
What is the runtime class?
What does "returned Class
object ... is locked by static synchronized
methods" mean?
getClass
gives you the Class
instance for the object's actual class at runtime, rather than the type of the reference that you have to it.
A simple example will probably clarify. Say we have a method that accepts anything that implements List
and dumps out its class name;
static void foo(List l) {
System.out.println(l.getClass().getName());
}
We can call it with various different types of lists:
foo(new LinkedList()); // Outputs "java.util.LinkedList"
foo(new ArrayList()); // Outputs "java.util.ArrayList"
Since foo
can be called with any List
, in the rare (!) situations where it's unavoidable, it can use getClass
to figure out the actual class of the instance it's been given.
How to understand returned Class object is locked by static synchronized methods?
static synchronized
methods synchronize on the instance of Class
that represents the loaded class at runtime, so that calls to such methods can't overlap. Say I have a class, Foo
, with a static method notThreadSafe
, and I have two threads that need to call it:
// On thread 1
Foo.notThreadSafe();
// On thread 2
Foo.notThreadSafe();
Because it's not thread safe, notThreadSafe
would be declared synchronized
:
public static synchronized void notThreadSafe() {
/* ... */
}
Which is effectively the same as
public static void notThreadSafe() {
synchronized (Foo.class) {
/* ... */
}
}
(Foo.class
is the Class
instance for the loaded Foo
class.)
So when thread 1 enters the synchronized block, if thread 2 tries to enter that block (or anything else synchronized on Foo.class
), it has to wait.
It doesn't have to be two calls to the same method; I could have two static synchronized
methods (m1
and m2
), where thread 1 is calling m1
and thread 2 is calling m2
, and the call to m2
would have to wait for the call to m1
to complete, because they're both synchronizing on the same instance (the Class
instance for Foo
).
How does this relate to getClass()
? Because that same Class
instance is what getClass
on Foo
instances returns:
System.out.println(Foo.class == (new Foo()).getClass()); // true
"Runtime class" is the Class object associated with the effective type of the object. It means if you do :
Object o = new String();
System.out.println(o.getClass());
You will get class java.lang.String
, because the actual, runtime class of o
is String
. You can't predict this at compile time.
As for the "locked by synchronized static methods", it really means that, for a method declared inside class ThisClass
:
public static synchronized foo() {
...
}
... is equivalent to :
public static foo() {
synchronized(ThisClass.class) {
...
}
}
That is, the Class object is used as the lock for all synchronized static methods. More on synchronized blocks and locks here.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With