Статическая переменная в Java

Согласно Java, статические переменные доступны по имени класса, но они также доступны объекту класса, хотя Java не предлагает его, и он дает тот же ответ.

Я знаю, что будет только одна копия переменной, и ее значение будет одинаковым для всех объектов и других вещей. Почему Java предлагает использовать имя класса вместо объекта класса?

Ответ 1

Потому что это может сбить с толку! Динамическая диспетчеризация статических элементов отсутствует.

Взгляните на этот запутанный код: (может быть, синтаксические ошибки, моя Java ржавая)

public abstract class Singer {
    public static void sing() {
        System.out.println("Singing");
    }
}

public class Soprano extends Singer {
    public static void sing() {
        System.out.println("Singing in the range of C4-A5");
    }
}

public class MyDriver {

    public static void main(String[] argv) {
        Singer  mySoprano1 = new Soprano();
        Soprano mySoprano2 = new Soprano();
        mySoprano1.sing();
        mySoprano2.sing();
    }

}

Посмотрев на MyDriver, это запутывает, потому что кажется, что метод sing является полиморфным, поэтому выход должен быть...

Singing in the range of C4-A5
Singing in the range of C4-A5

... потому что оба soprano1 и soprano2 являются экземплярами Soprano - not Singer.

Но, увы, выход на самом деле:

Singing
Singing in the range of C4-A5

Почему? Поскольку динамическая отправка на статические члены отсутствует, поэтому объявленный тип mySoprano1 определяет, какой метод sing вызывается... и объявленный тип soprano1 равен Singer, а не Soprano.

Для получения дополнительной информации, проверьте Puzzle 48 "Все, что я получаю, статично" в книге Java Puzzlers.

Ответ 2

Это более самодокументируемо, если вы пишете MyClass.staticVariable, чем myObject.staticVariable. Он указывает человеку, что код staticVariable является свойством MyClass, а не myObject, который является конкретным экземпляром класса.

Ответ 3

Одна точка, о которой я могу подумать, - это использовать ссылку на класс вместо Object, JVM не нужно вообще создавать объект new для доступа к этой статической переменной. Это хорошая практика программирования для производительности.