#java
#java
Вопрос:
Раньше мой код был:
class Dog
{
public static int i=6;
}
public class Cat
{
public static void main(String[] arg)
{
System.out.println(Dog.i);
}
}
Он выполнялся хорошо, но когда я удалил класс «Dog» из своего кода, перекомпилировал его и запустил, он дал тот же ответ: 6.
Итак, мой вопрос: несмотря на то, что у меня нет Dog
class в моем коде, откуда берется переменная Dog.i
и почему?
Комментарии:
1. Если вы удалите
Dog.
из этойSystem.out.println
строки, код больше не компилируется.2. Я думаю, вы забыли сохранить
3. Пожалуйста, используйте курсив и жирный шрифт только для фактического выделения, а не для случайного применения их ко всем абзацам.
4. Связь с
static
ключевым словом ускользает от меня. Неясно, о чем вы спрашиваете.
Ответ №1:
Вы не удалили Dog.class досье. В противном случае компиляция была бы невозможна.
Комментарии:
1. Я подозреваю, что OP просто перезапускается
javac
. ПосколькуCat.class
оно было новее,Cat.java
оно может не быть перекомпилировано.2. @PeterLawrey Меня не очень интересуют спекуляции, но
javac
всегда перекомпилирует файлы, специально названные open the command line,
Ответ №2:
Одна из немногих оптимизаций javac
, выполняемых компилятором, — это постоянная вставка. Это означает, что любая примитивная константа, известная во время компиляции, может быть вставлена на место. Это означает, что ваш код такой же, как
public class Cat
{
public static void main(String[] arg)
{
System.out.println(6 /*Dog.i*/);
}
}
Вы можете удалить Dog.*
, и при условии, что вы не перекомпилируете Cat
его, он будет работать правильно. Примечание: повторный запуск javac
не означает, что все будет скомпилировано заново, javac
проверяется, не является ли .class
файл никогда .java
файлом.
Также, если вы удалите Dog.java
это, это не приведет к удалению Dog.class
, и вам понадобится только позже, чтобы повторно скомпилировать этот класс.
Комментарии:
1. Это не соответствует описанию «когда я удалил класс «Dog» из своего кода» . Неспособность заметить, что он не компилировался во второй раз, делает (ваш комментарий к ответу EJP), и наличие
extends Dog
делает, но не это.2. @T.J.Crowder Я не понимаю, как having
extends Dog
имеет какое-либо значение, поскольку константа содержит имя класса, включенноеDog.i
, когда ОП говорит, что он удалил класс «Dog», неясно, где это означает, что простоDog.java
nor былCat.class
удален, чтобы убедиться, что он был перекомпилирован.3. Под «удаленной собакой» я понял, что он имел в виду из
System.out.println
строки, учитывая контекст остальной части вопроса и то, как он говорит о том, что интересно, откудаi
берется. Но, по сути, этот вопрос не стоит вашего времени, моего или EJP, пока / пока он не прояснится. 🙂4. Эта оптимизация применяется только к
final
значениям. В этой ситуации этого не происходит.
Ответ №3:
Если вы удалите Dog.
из этой System.out.println
строки, код больше не компилируется. Я предполагаю, что вы отказались extends Dog
от своего Cat
класса:
class Dog
{
public static int i=6;
}
public class Cat extends Dog // <===== Note
{
public static void main(String[] arg)
{
System.out.println(Dog.i);
}
}
Если это так, причина i
заключается в том, что Cat
это a Dog
, и в коде в Dog
классе или его подклассах, таких как Cat
(для public
или protected
членов), статические идентификаторы, определенные в Dog
, находятся в области видимости. Вам не нужно их уточнять (хотя это может помочь внести ясность).
Комментарии:
1. Я не уверен, что это ответ, возможно, предположение «что автор имеет в виду»
2. @JacekCz: Это то, что соответствует симптому, описанному в OP, поэтому я уверен. Я удалю его, если окажется, что я ошибаюсь.
3. Да, ваша программа профессионально корректна (возможно, неестественное наследие), я сомневаюсь только на «дидактическом» уровне
4. @JacekCz: «возможно, неестественное наследование» Я также прокомментировал это выше. 😀
5. Если вы удалили Dog.class и Dog.java код не будет компилироваться независимо от того, расширил Cat Dog или нет.