在Java中访问静态字段的正确方法是什么?

时间:2011-04-06 06:35:14

标签: java class variables static

我刚刚开始学习Java,我写了一个类来测试使用静态字段。一切正常但在Eclipse中我看到一个图标,当它悬停时出现:“来自CarCounter类型的静态方法getCounter应该以静态方式访问。”什么是正确的方式呢?

这是班级:

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 个答案:

答案 0 :(得分:16)

使用CarCounter.getCounter()。这清楚地表明它与a变量的值所引用的对象无关 - 计数器与类型本身相关联,而不是与该类型的任何特定实例相关联。

以下是一个为什么它非常重要的例子:

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

该代码正在做什么看起来?看起来它正在开始一个新线程,然后以某种方式“暂停” - 将其发送到睡眠状态一秒钟。

实际上,它正在启动一个新线程并暂停当前线程,因为Thread.sleep是一个静态方法,总是使当前线程休眠。它不能使任何其他线程睡眠。当它明确时,它会更加清晰:

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

基本上,第一段代码编译的能力是语言设计者的错误:(

答案 1 :(得分:11)

静态字段和方法不属于特定对象,而属于某个类,因此您应该从类中访问它们,而不是从对象访问它们:

CarCounter.getCounter()

而不是

a.getCounter()

答案 2 :(得分:8)

那将是:

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

答案 3 :(得分:1)

尽管非常气馁,但甚至有可能写下:

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

这是因为静态访问会查看变量的声明类型,并且从不实际取消引用它。

答案 4 :(得分:0)

静态元素属于该类。因此,访问它们的最佳方式是通过课程。 因此,在您的情况下,打印输出应该是。

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());
    }
}

希望这能解释。

NawaMan :-D

答案 5 :(得分:0)

应静态访问静态成员,即ClassName.memberName。 但是,允许非静态访问(objectName.memberName),但不鼓励。