Как правильно обращаться к статическим полям в Java? - PullRequest
1 голос
/ 06 апреля 2011

Я только начал изучать Java и написал класс для тестирования с использованием статических полей.Все работает нормально, но в Eclipse я вижу значок, который при наведении выглядит так: «Статический метод getCounter из типа CarCounter должен быть доступен статическим способом ».Тогда какой правильный путь?

Вот класс:

public class CarCounter {
    static int counter = 0;

    public CarCounter(){
        counter++;
    }

    public static int getCounter(){
        return counter;
    }
}

И вот где я пытаюсь получить доступ к переменному счетчику:

public class CarCounterTest {
    public static void main( String args[] ){
        CarCounter a = new CarCounter();
        System.out.println(a.getCounter()); //This is where the icon is marked
    }
}

Ответы [ 6 ]

16 голосов
/ 06 апреля 2011

Используйте CarCounter.getCounter().Это дает понять, что это не имеет ничего общего с объектом, на который ссылается значение переменной a - счетчик связан с самим типом, а не с каким-либо конкретным экземпляром типа.

Вот примерпочему это действительно важно:

Thread t = new Thread(runnable);
t.start();
t.sleep(1000);

Что это выглядит как этот код делает?Похоже, что он запускает новый поток, а затем каким-то образом «приостанавливает» его - отправляя в спящий режим на секунду.

Фактически, он запускает новый поток и приостанавливает поток current ,потому что Thread.sleep является статическим методом, который всегда переводит текущий поток в спящий режим.Это не может заставить любой другой поток спать.Это намного яснее, когда это явно:

Thread t = new Thread(runnable);
t.start();
Thread.sleep(1000);

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

11 голосов
/ 06 апреля 2011

Статические поля и методы принадлежат не конкретному объекту, а классу, поэтому вам следует обращаться к ним из класса, а не из объекта:

CarCounter.getCounter()

а не

a.getCounter()
8 голосов
/ 06 апреля 2011

Это было бы:

System.out.println(CarCounter.getCounter());
1 голос
/ 26 апреля 2013

Можно даже написать, хотя и не рекомендуется:

Math m = null;
double d = m.sin(m.PI/4.0);
System.out.println("This should be close to 0.5 " + (d*d));

Это потому, что при статическом доступе просматривается объявленный тип переменной и никогда не разыменовывается.

0 голосов
/ 15 сентября 2013

Статические члены должны быть доступны статически, то есть ClassName.memberName. Нестатический доступ разрешается хотя (objectName.memberName), но не рекомендуется.

0 голосов
/ 06 апреля 2011

Статические элементы принадлежат классу.Поэтому лучший способ получить к ним доступ через класс.Так что в вашем случае распечатка должна быть.

System.out.println(CarCounter.getCounter());

Это может показаться ненужным, но это не так.Рассмотрим следующий код

// VehicleCounter.java
public class VehicleCounter {
    static int counter = 0;

    public VehicleCounter(){
        counter++;
    }

    public static int getCounter(){
        return counter;
    }
}
// CarCounter.java
public class CarCounter extends VehicleCounter {
    static int counter = 0;

    public CarCounter(){
        counter++;
    }

    public static int getCounter(){
        return counter;
    }
}
// CarCounterTest.java
public class CarCounterTest {
    public static void main( String args[] ){
        VehicleCounter vehicle1 = new VehicleCounter();
        VehicleCounter vehicle2 = new CarCounter();
        System.out.println(vehicle1.getCounter());
        System.out.println(vehicle2.getCounter());
    }
}

Что должен печатать вышеуказанный код?

Поведение вышеуказанного кода определить сложно.vehicle1 объявлен как VehicleCounter, а объект на самом деле является VehicleCounter, поэтому он должен напечатать 2 (созданы два автомобиля).

vehicle2 объявлен как VehicleCounter, но объект является действительнымCarCounter.Что должно быть напечатано?

Я действительно не знаю, что будет напечатано, но я вижу, что это легко запутать.Так что для лучшей практики статические элементы всегда должны быть доступны через определенный класс.

Гораздо проще предсказать, что будет напечатано с помощью следующего кода.

// CarCounterTest.java
public class CarCounterTest {
    public static void main( String args[] ){
        VehicleCounter vehicle1 = new VehicleCounter();
        VehicleCounter vehicle2 = new CarCounter();
        System.out.println(VehicleCounter.getCounter());
        System.out.println(CarCounter    .getCounter());
    }
}

Надеюсь, это объясняет.

НаваМан: -D

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...