通过对象“坏forms”调用静态方法? 为什么?
在最近的一个问题中,有人询问静态方法,其中一个答案表明你通常称之为:
MyClassName.myStaticMethod();
对此的评论还表明你也可以通过一个对象来调用它:
MyClassName myVar; myVar.myStaticMethod();
但它被认为是不好的forms。
现在在我看来,这样做实际上可以让我的生活更轻松,所以我不必担心什么是静态的(a) 。
通过对象调用静态函数有问题吗? 显然你不想创建一个全新的对象来调用它:
Integer xyzzy; int plugh = xyzzy.parseInt ("42", 10);
但是,如果您已经有一个所需类型的对象, 使用它是否有问题?
(a)显然,我不能用以下方法调用非静态方法:
MyClassName.myNonStaticMethod();
但这不是我在这里问的问题。
糟糕的表单评论来自Java编码约定
请参阅http://www.oracle.com/technetwork/java/codeconventions-137265.html#587
如果你考虑它,它的原因是该方法是静态的,不属于任何特定的对象。 因为它属于类,为什么要将特定对象提升到看起来拥有方法的特殊状态?
在您的特定示例中,您可以使用现有的整数来调用parseInt
(也就是说,它在Java中是合法的),但这会将读者的注意力集中在该特定的整数对象上。 它可能会让读者感到困惑,因此指导就是避免这种风格。
关于这一点,程序员可以让生活更轻松,转过身来询问是什么让读者的生活更轻松? 有两种方法:实例和静态。 当你看到表达式Cm
并且你知道C
是一个类时,你知道m
必须是一个静态方法。 当你看到xm
(其中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"); } }
答案是它打印“超级”,因为静态方法不是虚拟的。 即使instance
是一个Sub
,编译器也只能继续使用Super
变量的类型。 但是,通过instance
而不是Super
调用方法,您巧妙地暗示它将是虚拟的。
实际上,读取instance.method()
的开发人员必须查看方法的声明(其签名)以了解它实际被调用的方法。 你提到
在我看来,这样做实际上可以让我的生活更轻松,所以我不必担心什么是静态的
但在上述情况下,上下文实际上非常重要!
我可以相当自信地说语言设计者首先允许这样做是错误的。 远离。
这是一个沟通的问题。 在一个实例上调用一个方法意味着你要对该特定实例进行操作,而不是对实例的类进行操作。
当您有一个从另一个对象inheritance的对象时,它可能会变得非常混乱,从而覆盖其静态方法。 特别是如果你将对象称为其祖先类的一种类型。 你正在运行哪种方法并不明显。