Гарантирует ли Java, что Object.getClass () == Object.getClass ()?

Я действительно имею в виду тождество личности.

Например, будет ли всегда отображаться true ?

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

Да, токены classа уникальны (для любого данного загрузчика classов, то есть).

Т.е. вы всегда получите ссылку на один и тот же физический объект в пределах той же самой области loadload . Однако другой загрузчик classов загружает другой токен classа в сочетании с тем фактом, что одно и то же определение classа считается другим при загрузке двумя разными загрузчиками classов.

См. Этот мой предыдущий ответ для демонстрации этого.

Для двух экземпляров classа X ,

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

только если

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

Примечание. Class.getClassLoader() может возвращать значение null, что подразумевает загрузку ClassLoader.

Да.

Возвращаемый объект classа – это объект, который заблокирован статическими синхронизированными методами представленного classа.

Если бы можно было возвращать несколько экземпляров, то

 public static synchronized void doSomething() {..} 

не будет streamобезопасным.

Это гарантировано для каждого загрузчика classов, как указано в спецификации JVM :

Во-первых, виртуальная машина Java определяет, было ли уже записано, что L является инициирующим загрузчиком classа или интерфейса, обозначенного символом N. Если это так, эта попытка создания недействительна и загрузка вызывает ссылку LinkageError.

То есть, если загрузчик classов (L) пытается обойти кэширование LinkageError по умолчанию, а JVM загружает определение byte[] более одного раза для одного и того же имени classа (N), LinkageError будет выбрасываться JVM.

Например, реализуйте загрузчик classов, который вызывает defineClass(...) каждый раз при loadClass(...) (минуя кэширование по умолчанию):

 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) 

ура

Давайте будем гением компьютера.