我刚刚开始学习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
}
}
答案 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),但不鼓励。