在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()
这将是:
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)允许非静态访问,但不鼓励。
替换*需要* * *应该*因为两行代码都是正确的,但第二个是不鼓励的 – 2011-04-06 06:46:34
@Andreas_D - 谢谢。 – MByD 2011-04-06 06:50:02
这为我解答了它;你的答案在简短的同时很短。惊人! – enchance 2011-04-06 09:15:52