Ответ 1
Сначала взгляните на таблицу модификатора доступа к классам и свойствам из спецификаций JVM.
Обратите внимание на флаг ACC_SYNTHETIC
, интерпретация которого указывает, что он отсутствует в исходном коде (в более простых словах он будет добавлен, когда класс будет сгенерирован компилятором).
Посмотрим на байт-код EnclosingClass$1.class
(обратите внимание, что я вложу только ту часть, которая имеет значение).
javap -v EnclosingClass$1.class
выведите следующий результат
Classfile /C:/Users/jfrancoiss/Desktop/Nouveau dossier/EnclosingClass$1.class
Last modified 2015-03-31; size 190 bytes
MD5 checksum 5875440f1e7f5ea9a519d02fbec6dc8f
Compiled from "EnclosingClass.java"
class EnclosingClass$1
minor version: 0
major version: 52
flags: ACC_SUPER, ACC_SYNTHETIC
Обратите внимание, что флаги доступа класса содержат ACC_SYNTHETIC
.
Флаг ACC_SYNTHETIC указывает, что этот класс или интерфейс был созданный компилятором и не отображающийся в исходном коде.
Другой способ убедиться, что сгенерированный класс является синтетическим, заключается в компиляции как
javac -XD-printflat EnclosingClass.java
который произведет
/*synthetic*/ class EnclosingClass$1 {
}
Отлично, но зачем генерировать синтетический класс?
Учебник по отражению Java поможет нам понять это. Взгляните на комментарии в SyntheticConstructor
class
public class SyntheticConstructor {
private SyntheticConstructor() {}
class Inner {
// Compiler will generate a synthetic constructor since
// SyntheticConstructor() is private.
Inner() { new SyntheticConstructor(); }
}
}
Итак, согласно комментарию, синтетический класс EnclosingClass$1.class
был создан, потому что IBiLink
был закрытым.
Еще раз, java reflection tutorial укажите в этот момент
Так как внутренний конструктор классов ссылается на частный конструктор охватывающего класса компилятор должен сгенерировать пакет-частный конструктор.
В нашем случае мы не видим явно никакого вызова конструктора, но мы имеем эту строку
public static class BiNode extends Sub.IBiLink { }
Попробуйте выполнить компиляцию этого кода и посмотреть, что произойдет
class EnclosingClass
{
//public static class BiNode extends Sub.IBiLink { }
private static class Sub
{
private static class IBiLink
{
}
}
}
Нет EnclosingClass$1.class
.
Подробнее при отладке
Измените
private static class IBiLink
к
protected static class IBiLink
обратите внимание, что при компиляции EnclosingClass$1.class
не создается.
Почему защита класса не создала синтетический класс?
Просто потому, что при защите класса вы неявно получаете доступ к каждому из суперклассов.
Почему компилятор eclipse не генерирует синтетический класс?
Eclipse использует встроенный компилятор, который вы можете настроить его уровень серьезности.
По умолчанию доступ к незанятому члену закрывающего типа устанавливается как игнорируемое, как вы можете видеть на этом изображении.
Измените его, например, на предупреждение, и вы получите следующее сообщение.
которые позволяют мне полагать, что затмение, altought не создает другого класса, будет эмулировать его для имитации синтетического элемента.