如何理解Object.getClass()方法?

时间:2015-06-18 14:57:12

标签: java

The Java Object.getClass() method javadoc说:

  

返回此Object的运行时类。返回的Class对象是   由static synchronized方法锁定的对象   代表班级。实际结果类型为Class<? extends |X|>   其中|X|是表达式的静态类型的擦除   调用getClass。例如,此代码中不需要强制转换   片段:

Number n = 0; 
Class<? extends Number> c = n.getClass();
     

返回:表示此运行时类的Class对象   对象

什么是运行时类?

&#34;返回Class对象...被static synchronized方法&#34;锁定了什么?意思?

3 个答案:

答案 0 :(得分:6)

getClass为您提供运行时实际类Class实例,而不是您拥有的引用类型。

一个简单的例子可能会澄清。假设我们有一个方法接受任何实现List并转储其类名的内容;

static void foo(List l) {
    System.out.println(l.getClass().getName());
}

我们可以使用各种不同类型的列表来调用它:

foo(new LinkedList()); // Outputs "java.util.LinkedList"
foo(new ArrayList());  // Outputs "java.util.ArrayList"

由于可以使用任何foo调用List,因此在罕见的(!)情况下,它是不可避免的,它可以使用getClass来确定实例的实际类别给出。

  

如何理解返回的Class对象是否被静态同步方法锁定?

static synchronized方法在Class的实例上同步,该实例表示在运行时加载的类,因此对这些方法的调用不能重叠。假设我有一个类Foo,使用静态方法notThreadSafe,我有两个线程需要调用它:

// On thread 1
Foo.notThreadSafe();

// On thread 2
Foo.notThreadSafe();

因为它不是线程安全的,notThreadSafe将被声明为synchronized

public static synchronized void notThreadSafe() { 
    /* ... */
}

实际上与

相同
public static void notThreadSafe() { 
    synchronized (Foo.class) {
        /* ... */
    }
}

Foo.class是加载的Class类的Foo实例。)

因此,当线程1进入同步块时,如果线程2尝试进入该块(或Foo.class上同步的任何其他块),则必须等待。

它不必是对同一方法的两次调用;我可以有两个static synchronized方法(m1m2),其中线程1正在调用m1而线程2正在调用m2,并且调用{ {1}}必须等待m2的调用完成,因为它们都在同一个实例(m1的{​​{1}}实例)上进行同步。

这与Class有何关系?因为同一个Foo实例是getClass()实例上Class返回的内容:

getClass

答案 1 :(得分:1)

&#34;运行时类&#34;是与对象的有效类型关联的Class对象。这意味着如果你这样做:

Object o = new String();
System.out.println(o.getClass());

您将获得class java.lang.String,因为o的实际运行时类为String。你无法在编译时预测这一点。

对于&#34;由同步静态方法&#34;锁定,它实际上意味着,对于在类ThisClass内声明的方法:

public static synchronized foo() {
    ...
}

......相当于:

public static foo() {
    synchronized(ThisClass.class) {
        ...
    }
}

也就是说,Class对象用作所有同步静态方法的锁。有关同步块和锁here的更多信息。

答案 2 :(得分:0)

对于你的第二个问题意味着:

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

f()上调用c(仅可通过反射)将有效地使用与B.f()相同的锁定。锁将是类对象本身。