Точное поведение статического ключевого слова в java

#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 или нет.