【问题标题】:Is calling static methods via an object "bad form"? Why?通过对象“坏形式”调用静态方法吗?为什么?
【发布时间】:2026-02-08 15:55:02
【问题描述】:

在最近的一个问题中,有人问及静态方法,其中一个答案说您通常用以下方式称呼它们:

MyClassName.myStaticMethod();

上面的 cmets 还指出,您也可以通过以下对象调用它:

MyClassName myVar;
myVar.myStaticMethod();

但它被认为是不好的形式。

现在在我看来,这样做实际上可以让我的生活更轻松,所以我不必担心什么是静态的或不是(a)

通过对象调用静态函数有问题吗?显然你不想创建一个全新的对象只是为了调用它:

Integer xyzzy;
int plugh = xyzzy.parseInt ("42", 10);

但是,如果你已经有了想要的类型的对象,那么使用会不会有问题?


(a) 显然,我不能调用非静态方法:

MyClassName.myNonStaticMethod();

但这不是我在这里要问的问题。

【问题讨论】:

  • 查看此 SO 答案以获取信息 *.com/questions/610458/…
  • 当我阅读代码并且有对方法的调用时,对我而言,能够立即告知该调用无法读取或修改它所属的对象。有了MyClassName.myStaticMethod();,你甚至不需要怀疑它。使用myVar.myStaticMethod();,您需要查看方法的代码,对于all 调用,您将始终存在疑问。当然,不同的 IDE 可能会使这些信息易于检索(Javadoc 工具提示、语法突出显示等),但我不会依赖它来决定如何编写代码。

标签: java methods static instance


【解决方案1】:

这是一个沟通的问题。在实例上调用方法暗示您是在/与该特定实例进行操作,而不是在/与该实例的类进行操作。

【讨论】:

    【解决方案2】:

    在我看来,让这变得如此难以理解的真正用例是这样的。下面的代码打印了什么?

    //in a main method somewhere
    Super instance = new Sub();
    instance.method();
    
    //...
    public class Super {
        public static void method() {
            System.out.println("Super");
        }
    }
    
    public class Sub extends Super {
        public static void method() {
            System.out.println("Sub");
        }
    }
    

    答案是它打印“Super”,因为静态方法不是虚拟的。即使instance is-a Sub,编译器也只能继续Super的变量类型。但是,通过instance 而不是Super 调用该方法,您是在巧妙地暗示它将是虚拟的。

    事实上,阅读instance.method() 的开发人员必须查看方法的声明(其签名)才能知道实际调用的是哪个方法。你提到

    在我看来,这样做实际上可以让我的生活更轻松,所以我不必担心什么是静态的

    但在上述情况下,上下文其实很重要!

    我可以相当自信地说,语言设计者一开始就允许这样做是一个错误。远离。

    【讨论】:

      【解决方案3】:

      错误的表单注释来自 Java 编码约定

      http://www.oracle.com/technetwork/java/codeconventions-137265.html#587

      如果您考虑一下,原因在于该方法是静态的,不属于任何特定对象。因为它属于类,为什么要将特定对象提升到如此特殊的状态,以至于它似乎拥有一个方法?

      在您的特定示例中,您可以使用现有整数来调用parseInt(也就是说,它在Java 中是合法的),但这会将读者的注意力放在那个特定的整数对象上。这可能会让读者感到困惑,因此建议避免这种风格。

      关于这让程序员的生活更轻松,请转过头来问一下是什么让阅读器的生活更轻松?有两种方法:实例和静态。当您看到表达式C.m 并且您知道C 是一个类时,您知道m 必须是一个静态方法。当您看到x.m(其中x 是一个实例)时,您无法分辨,但它看起来像一个实例方法,因此大多数人只为实例方法保留此语法。

      【讨论】:

        【解决方案4】:

        当你有一个从另一个对象继承的对象,覆盖它的静态方法时,它可能会变得非常混乱。特别是如果您将对象称为其祖先类的类型。您正在运行哪种方法并不明显。

        【讨论】:

        • 如果那个“超级混乱”是双关语,我将不得不过来打你一巴掌:-)