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

问题描述:

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

这里的类:

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 
    } 
} 

静态字段和方法不属于到一个特定的对象,而是一个类,所以你应该从类中访问它们,而不是从一个对象中访问它们:

CarCounter.getCounter() 

,而不是

a.getCounter() 
+1

替换*需要* * *应该*因为两行代码都是正确的,但第二个是不鼓励的 – 2011-04-06 06:46:34

+0

@Andreas_D - 谢谢。 – MByD 2011-04-06 06:50:02

+0

这为我解答了它;你的答案在简短的同时很短。惊人! – enchance 2011-04-06 09:15:52

这将是:

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

使用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); 

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

静态元素的部分错误属于类。因此,要访问他们的最好方式是通过类。 所以你的情况,打印出应该的。

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

这可能会觉得triviaval不必要的,但事实并非如此。 考虑下面的代码

// 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

,甚至有可能,但高度气馁,写:

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

这是因为静态访问一下声明的类型变量,并没有真正解除引用。

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