通过对象“坏形式”调用静态方法?为什么?

时间:2011-10-25 02:19:51

标签: java methods static instance

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

MyClassName.myStaticMethod();

对此的评论还表明,您也可以通过以下对象来调用它:

MyClassName myVar;
myVar.myStaticMethod();

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

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

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

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

但是,如果您已经有一个所需类型的对象,那么使用会有问题吗?


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

MyClassName.myNonStaticMethod();

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

4 个答案:

答案 0 :(得分:31)

在我看来,使这个如此难以理解的真实用例是这样的。下面的代码是什么打印的?

//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");
    }
}

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

事实上,阅读instance.method()的开发人员必须查看方法的声明(其签名),以了解它实际被调用的方法。你提到

  

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

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

我可以相当自信地说语言设计者首先允许这样做是错误的。远离。

答案 1 :(得分:17)

糟糕的表单评论来自Java编码约定

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

如果你考虑的话,它的原因是这个方法是静态的,不会属于任何特定的对象。因为它属于类,为什么要将特定对象提升到看似拥有方法的特殊状态?

在您的特定示例中,可以使用现有的整数来调用parseInt(也就是说,它在Java中是合法的),但这会使读者关注该特定整数宾语。它可能让读者感到困惑,因此指导就是避免这种风格。

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

答案 2 :(得分:5)

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

答案 3 :(得分:4)

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