Java 是通过对象调用静态方法;坏形式;?为什么?

Java 是通过对象调用静态方法;坏形式;?为什么?,java,methods,static,instance,Java,Methods,Static,Instance,在最近的一个问题中,有人问到了静态方法,其中一个答案是,您通常用如下方式称呼它们: MyClassName.myStaticMethod(); 对此的评论还指出,您也可以通过以下对象调用它: MyClassName myVar; myVar.myStaticMethod(); 但这被认为是糟糕的形式 现在在我看来,这样做实际上可以让我的生活更轻松,所以我不必担心什么是静态的或不是静态的(a) 通过对象调用静态函数是否有问题?显然,您不想创建一个全新的对象,而只是将其称为: Integer x

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

MyClassName.myStaticMethod();
对此的评论还指出,您也可以通过以下对象调用它:

MyClassName myVar;
myVar.myStaticMethod();
但这被认为是糟糕的形式

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

通过对象调用静态函数是否有问题?显然,您不想创建一个全新的对象,而只是将其称为:

Integer xyzzy;
int plugh = xyzzy.parseInt ("42", 10);
但是,如果您已经有了所需类型的对象,那么使用它会有问题吗


(a) 显然,我不能使用以下命令调用非静态方法:

MyClassName.myNonStaticMethod();

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

糟糕的形式注释来自Java的编码约定

如果你仔细想想,其原因是该方法是静态的,不属于任何特定对象。因为它属于类,为什么要将特定对象提升到它似乎拥有方法的特殊状态

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


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

当您有一个从另一个对象继承的对象,覆盖其静态方法时,可能会非常混乱。尤其是当您将对象作为其祖先类的一种类型引用时。您运行的方法并不明显。

这是一个沟通问题。对实例调用方法意味着您正在对该实例进行操作,而不是对该实例的类进行操作。

在我看来,使其如此不可读的实际用例是这样的。下面的代码打印什么

//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
是-a
Sub
,编译器也只能继续变量的类型,即
Super
。但是,通过
实例
而不是
超级
调用该方法,您微妙地暗示它将是虚拟的

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

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

但在上述情况下,上下文实际上是非常重要的


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

看到这个,当我阅读代码并且有一个方法调用时,请回答信息。对我来说,能够立即告诉我该调用不能读取或修改它所属对象的状态是非常相关的。使用
MyClassName.myStaticMethod()甚至一秒钟都没有必要对此感到惊讶。使用
myVar.myStaticMethod()
您需要查看该方法的代码,对于所有调用,您都将始终处于这种怀疑状态。当然,不同的IDE可能会使这些信息易于检索(Javadoc工具提示、语法突出显示等),但我不会依靠这些来决定如何编写代码。如果“超级混乱”是一个双关语,我将不得不过来给你一个耳光:-)+1同意这也是一个错误(IMHO)。顺便说一句,这是一个很好的例子。