Comments 10
class Outer$1 {} // в этом классе нет вообще конструктора, даже приватного, его никак не инстанциировать
А как же спецификация?
0
Это спецификация языка Java, а речь о байткоде виртуальной машины Java. Здесь нас интересует в основном Четвёртая глава спецификации JVM. Это не единственный пример того, что можно в байткоде, но нельзя в языке Java (я вот и про вызов конструктора родительского класса написал, скажем).
+3
Что тогда мешает создать инстанс? Не вызываем <_init_> и все.
+1
Отличный вопрос! Если бы в спецификации не было раздела 4.10, можно было бы вытворять и не такие вещи. А так ваш класс не пройдёт верификацию и упадёт с VerifyError при загрузке класса Java-машиной. Детали можно почитать тут: 4.10.1.9.new, 4.10.1.9.invokespecial и 4.10.2.4. Вкратце это происходит так: при вызове new верификатор помещает в стек переменную специального типа uninitialized. Единственное, что с ней можно сделать — это вызвать <init>. Ну ещё можно держать в стеке и даже в локальной переменной, но попытки вызвать на ней метод, получить её поле, записать её в поле, передать в метод или вернуть из текущего метода обернутся ошибкой верификации.
Если честно, я сам не пробовал, только читал, что так нельзя делать. Попробуйте :-)
Если честно, я сам не пробовал, только читал, что так нельзя делать. Попробуйте :-)
+1
Не знаю как сейчас, раньше была еще разница в том как javac и ecj именуют вложенные анонимные классы в анонимные классы т.е
javac создавал классы A$1 и A$1$1, тогда как ecj A$1 и A$2
class A {
public Runnable a(){
return new Runnable(){
public void run(){
Runnable a = new Runnable(){
public void run(){}
}
a.run();
}
}
}
}
javac создавал классы A$1 и A$1$1, тогда как ecj A$1 и A$2
0
Плюсов у статьи почему-то немного, но хочется отметить её крайнюю информативность. Спасибо вам, автор, обязательно пишите ещё про такие вещи!
+2
Sign up to leave a comment.
Компиляция вложенных классов: javac и ecj