简体   繁体   中英

How to understand the Object.getClass() method?

The Java Object.getClass() method javadoc says:

Returns the runtime class of this Object . The returned Class object is the object that is locked by static synchronized methods of the represented class. The actual result type is Class<? extends |X|> Class<? extends |X|> where |X| is the erasure of the static type of the expression on which getClass 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 .

For your second question that means that with:

class A {}
class B extends A {
  public static synchronized void f() {}
}
...
A a = new B();
Class <? extends A> c = a.getClass();

a call to f() on c (only possible via reflection) will effectively use the same lock as Bf() . The lock will be the class object itself.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM