Я не понимаю, почему содержимое foo зависит от того, из какого класса вы к нему обращаетесь.
По сути, это вопрос инициализации типа. Значение foo
устанавливается на "bar"
при инициализации Sub
. Однако в вашем классе Testing
ссылка на Sub.foo
фактически скомпилирована в ссылку на Super.foo
, поэтому она не заканчивается инициализацией Sub
, поэтому foo
никогда не становится "bar"
.
Если вы измените код тестирования на:
public class Testing {
public static void main (String[] args) {
Sub.main(args);
System.out.println(Super.foo);
System.out.println(Sub.foo);
System.out.println(Super.foo);
}
}
Тогда он напечатал бы "bar" четыре раза, потому что первый оператор заставил бы Sub
быть инициализированным, что изменило бы значение foo
. Вопрос не в том, откуда к нему обращаются.
Обратите внимание, что это не просто класс загрузка - это класс инициализация . Классы могут быть загружены без инициализации. Например:
public class Testing {
public static void main (String[] args) {
System.out.println(Super.foo);
System.out.println(Sub.class);
System.out.println(Super.foo);
}
}
Это все еще печатает «foo» дважды, показывая, что Sub
не инициализирован - но он определенно загружен , и программа завершится ошибкой, если вы удалите файл Sub.class
перед его запуском, для пример.