Я действительно имею в виду тождество-равенство здесь.
Например, всегда ли следующее будет выводить true?
System.out.println("foo".getClass() == "fum".getClass());
Я действительно имею в виду тождество-равенство здесь.
Например, всегда ли следующее будет выводить true?
System.out.println("foo".getClass() == "fum".getClass());
Да, токены класса уникальны (то есть для любого данного загрузчика классов).
т.е. вы всегда будете получать ссылку на один и тот же физический объект в одной и той же области загрузчика классов. Однако другой загрузчик классов загрузит другой токен класса в сочетании с тем фактом, что одно и то же определение класса считается различным при загрузке двумя разными загрузчиками классов.
См. этот мой более ранний ответ для демонстрации этого.
Для двух экземпляров класса X
,
x1.getClass() == x2.getClass()
только если
x1.getClass().getClassLoader() == x2.getClass().getClassLoader()
Примечание. Class.getClassLoader()
может возвращать значение null, что подразумевает загрузку ClassLoader.
ClassLoader.getSystemClassLoader
не совпадает с загрузчиком классов начальной загрузки. Если .getClassLoader()
возвращает значение null, это означает, что класс загружается загрузчиком классов начальной загрузки. ClassLoader.getSystemClassLoader
не вернет значение null.
- person Pacerier; 29.08.2014
да.
Возвращенный объект класса — это объект, заблокированный статическими синхронизированными методами представляемого класса.
Если бы можно было вернуть несколько экземпляров, то
public static synchronized void doSomething() {..}
не будет потокобезопасным.
getClass
возвращает объект класса The, который представляет класс среды выполнения этого объекта... а не объект класса A....
- person Stephen C; 18.09.2010
Это гарантировано для каждого загрузчика классов, как указано в спецификация JVM:
Во-первых, виртуальная машина Java определяет, записано ли уже, что L является инициирующим загрузчиком класса или интерфейса, обозначенного N. Если это так, эта попытка создания недействительна, и загрузка вызывает LinkageError.
То есть, если загрузчик классов (L) попытается обойти кэширование экземпляров Class
по умолчанию и заставить JVM загружать определение byte[]
более одного раза для одного и того же имени класса (N), JVM выдаст LinkageError
.
Например, реализуйте загрузчик классов, который вызывает 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)
Ваше здоровье
==
в этом фрагменте всегда выполняет сравнение ссылок, и оператор не может быть перегружен для вызова вместо негоequals
. Кроме того,java.lang.Class
— этоfinal
, поэтому вы не можете переопределить егоequals
. - person polygenelubricants   schedule 18.09.2010