【问题标题】:What is the proper way of accessing static fields in Java?在 Java 中访问静态字段的正确方法是什么?
【发布时间】:2011-07-30 13:24:05
【问题描述】:

我刚开始学习 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
    }
}

【问题讨论】:

    标签: java class variables static


    【解决方案1】:

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

    CarCounter.getCounter()
    

    而不是

    a.getCounter()
    

    【讨论】:

    • need 替换为 should 因为两行代码都是正确的,但不鼓励使用第二行
    • 这回答了我;你的回答很简短,同时也很简洁。太棒了!
    • @Binyamin Sharet 我知道这是一个较老的问题,但您的评论帮助我完成了我的项目。谢谢!
    【解决方案2】:

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

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

    【讨论】:

    • c# 设计师修复了这个错误。
    【解决方案3】:

    那就是:

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

    【讨论】:

      【解决方案4】:

      即使非常不鼓励,也可以写:

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

      这是因为静态访问会查看变量的声明类型,而不是真正取消引用它。

      【讨论】:

        【解决方案5】:

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

        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

        【讨论】:

          【解决方案6】:

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

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2010-10-22
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多