【问题标题】:Reference Static Methods/Variables in Java from an Instance从实例引用 Java 中的静态方法/变量
【发布时间】:2009-09-17 16:14:12
【问题描述】:

谁能向我解释为什么 java 允许您从实例访问静态方法和成员?一个不好的例子,如果我有一个名为 RedShape 的类,并且它有一个名为 getColor() 的静态方法,它返回“red”,为什么 java 允许您从 RedShape 的实例调用静态方法?在我看来,这似乎违反了 OO 语言设计的一些核心概念。至少,它应该带有编译器警告。

提前致谢。

编辑:

特别是,我问的是你什么时候有类似的东西

RedShape test = new RedShape();
test.getColor();

其中 getColor 是 RedShape 类的静态方法。这没有任何意义,它被允许并且不会通过 javac 在命令行上发出编译器警告。我看到它“非常不鼓励”,但很好奇在“因为 C++ 允许它”之外允许它是否有技术或合理的原因。

【问题讨论】:

    标签: java static instance


    【解决方案1】:

    我认为从实例调用静态方法 没有任何问题。那有什么问题?特别是,经常有一些方法在类的逻辑中很有用,但实际上并不需要操作实例本身。

    对象来调用一个静态方法通过一个实例引用。经典例子:

    Thread thread = new Thread(...);
    thread.sleep(5000); // Doesn't do what it looks like
    

    这在某些 IDE 中带有编译器警告 - 当然在 Eclipse 中,假设您打开它。 (Java / 编译器 / 错误和警告 / 代码样式 / 对静态成员的非静态访问。)我个人认为 是 Java 设计中的一个错误。 (这是 C# 设法避免复制的错误之一。)

    【讨论】:

    • 我认为 Brian 指的是严格意义上的后一种滥用行为。
    • 幸运的是,我相信 sleep 通常是在当前线程上调用的。 google.com/codesearch?as_q=currentThread()\.sleep&btnG=搜索+代码&hl=en&as_lang=&as_license_restrict=i&as_license=&as_package=&as_filename=&as_case=
    • @Tom Hawtin:没错。代码并没有做它看起来会做的事情。
    • @erickson:你是对的。我指的是从包含静态方法的类的实例中引用静态方法的能力。我已经修改了我的问题以澄清。
    【解决方案2】:

    你真的没有理由这样做。

    我唯一的猜测是它允许你覆盖静态方法,但你不能

    如果您尝试以下场景:

    Banana 有一个名为“test”的静态方法(这会打印“banana”) Apple 扩展 Banana 并“覆盖”名为 'test' 的静态方法(这将打印 'apple')

    然后你做这样的事情:

    public static void main(String[] args) {
        Apple apple = new Apple();
        Banana banana = new Banana();
        Banana base = new Apple();
    
        apple.test();
        banana.test();
        base.test();
    }
    

    结果输出是:

    apple
    banana
    banana
    

    如此有效,它几乎没用。

    【讨论】:

      【解决方案3】:

      对静态方法的访问允许您在同一类的实例之间共享值,甚至无需创建类实例即可获取值。

      在某些情况下它很方便并且不违反OO语言。

      【讨论】:

        【解决方案4】:

        我敢打赌,这是因为最初的设计者是从 C++ 移植功能,到 20/20 事后看来,这是一个向后兼容性问题。

        那,或者因为当你在一个类中调用一个方法时,即使你不必在所有东西前面加上this.,编译器也会插入它(或等效的),包括静态方法。如果静态方法不能从实例中调用,那么在前面加上this. 可能是个问题(或者会迫使编码人员在他们想在实际实例中使用静态方法时在静态方法前面加上类名)。

        无论如何,除非我们让早期的语言开发人员之一来回答,否则答案都是推测性的。

        【讨论】:

          【解决方案5】:
          public class MyClass {
              public static String myString;
          }
          
          
          public class AnotherClass {
             public void doSomething() {
                 doAnotherThing();
             }
             public static doAnotherThing() {
                 MyClass.myString = "something";
             }
          

          在这里,我们通过从非静态方法调用静态方法(间接)从非静态方法访问静态变量。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2011-01-10
            • 1970-01-01
            • 2019-03-10
            • 2018-09-11
            • 2011-01-12
            • 1970-01-01
            • 1970-01-01
            • 2021-01-22
            相关资源
            最近更新 更多