Java是否保证Object.getClass()==Object.getClass()?

Java是否保证Object.getClass()==Object.getClass()?,java,class,jvm,identity,equality,Java,Class,Jvm,Identity,Equality,我真的是指身份平等 例如,以下内容是否总是打印真 System.out.println("foo".getClass() == "fum".getClass()); 对 返回的类对象是由所表示类的静态同步方法锁定的对象 如果可以返回多个实例,那么 public static synchronized void doSomething() {..} 不会是线程安全的。是的,类标记是唯一的(即对于任何给定的类加载器) 也就是说,在同一个类加载器领域中,您将始终获得对同一物理对象的引用。但是,不同

我真的是指身份平等

例如,以下内容是否总是打印

System.out.println("foo".getClass() == "fum".getClass());

返回的类对象是由所表示类的静态同步方法锁定的对象

如果可以返回多个实例,那么

public static synchronized void doSomething() {..}

不会是线程安全的。

是的,类标记是唯一的(即对于任何给定的类加载器)

也就是说,在同一个类加载器领域中,您将始终获得对同一物理对象的引用。但是,不同的类加载器将加载不同的类标记,同时,当由两个不同的类加载器加载时,相同的类定义被认为是不同的


有关这方面的演示,请参阅。

有关类
X
的两个实例

x1.getClass() == x2.getClass()
除非

x1.getClass().getClassLoader() == x2.getClass().getClassLoader()

注意:
Class.getClassLoader()
可能返回null,这意味着引导类加载器。

每个类加载器都有保证,如下所述:

首先,Java虚拟机确定它是否已经记录了L是由N表示的类或接口的初始加载程序。如果是,则此创建尝试无效,加载将抛出LinkageError

也就是说,如果类加载器(L)试图绕过默认的
class
实例缓存,并使JVM为同一类名(N)多次加载
字节[]
定义,JVM将抛出
LinkageError

例如,实现一个类加载器,它在每次调用
loadClass(…)
时调用
defineClass(…)
(绕过默认缓存):


如果一个类(1)没有覆盖equals(Object)方法,那就欢呼吧;和(2)不是重写equals(Object)方法的类的子类,则该类使用根对象类中定义的equals(Object)方法,该方法使用==标识运算符。@emory:我认为您的注释是错误的。此代码段中的
=
始终执行引用比较,并且不能重载运算符以调用
equals
。另外,
java.lang.Class
final
,因此不能覆盖它的
等于
。另一个线索是javadoc说
getClass
返回“表示此对象运行时类的类对象”。。。不是“一个类对象…”很好的表达方式it@McDowell,你的最后一段错了<代码>类加载器。getSystemClassLoader
与引导类加载器不同。如果
.getClassLoader()
返回null,则表示该类由引导类加载器加载<代码>类加载器。getSystemClassLoader
不会返回null。
public class ClassloaderTest {

    private static final byte[] CLASS_DEF = readClassBytes();

    private static byte[] readClassBytes() {
        try {
            InputStream is = ClassloaderTest.class.getResourceAsStream("ClassloaderTest.class");
            ByteArrayOutputStream buffer = new ByteArrayOutputStream();
            int nRead;
            byte[] data = new byte[16384];
            while ((nRead = is.read(data, 0, data.length)) != -1) {
                buffer.write(data, 0, nRead);
            }
            buffer.flush();
            return buffer.toByteArray();
        } catch (IOException ex) {
            throw new AssertionError();
        }
    }

    private static ClassLoader createNonCachingClassloader() {
        return new ClassLoader() {
            @Override
            public Class<?> loadClass(String name) throws ClassNotFoundException {
                if (name.equals("classloader.ClassloaderTest")) {
                    return defineClass(name, CLASS_DEF, 0, CLASS_DEF.length);
                } else {
                    return getParent().loadClass(name);
                }
            }
        };
    }

    public static void main(String[] args) throws Exception {
        ClassLoader cl = createNonCachingClassloader();
        Class<?> cl1 = cl.loadClass("classloader.ClassloaderTest");
        Class<?> cl2 = cl.loadClass("classloader.ClassloaderTest");
        System.out.println(cl1==cl2);
    }
}
Exception in thread "main" java.lang.LinkageError: loader (instance of  classloader/ClassloaderTest$1): attempted  duplicate class definition for name: "classloader/ClassloaderTest"
    at java.lang.ClassLoader.defineClass1(Native Method)
    at java.lang.ClassLoader.defineClass(ClassLoader.java:760)
    at java.lang.ClassLoader.defineClass(ClassLoader.java:642)
    at classloader.ClassloaderTest$1.loadClass(ClassloaderTest.java:53)
    at classloader.ClassloaderTest.main(ClassloaderTest.java:64)