基本上,我相信Java设计师在他们设计语言时犯了一个错误,由于涉及的兼容性问题,它太晚了,以解决它。是的,它可以导致非常误导的代码。是的,你应该避免。是的,你应该确保你的IDE被配置为把它当作一个错误,IMO。如果你自己设计一种语言,请记住它作为避免的事情的例子:)
只是为了回应DJClayworth的观点,这里是允许在C#:
public class Foo
{
public static void Bar()
{
}
}
public class Abc
{
public void Test()
{
// Static methods in the same class and base classes
// (and outer classes) are available, with no
// qualification
Def();
// Static methods in other classes are available via
// the class name
Foo.Bar();
Abc abc = new Abc();
// This would *not* be legal. It being legal has no benefit,
// and just allows misleading code
// abc.Def();
}
public static void Def()
{
}
}
为什么我认为这是误导?因为如果我看代码someVariable.SomeMethod()我期望它使用someVariable的值。如果SomeMethod()是一个静态方法,那么期望是无效的;代码欺骗我。这怎么可能是一件好事?
奇怪的是,Java不会让你使用一个可能未初始化的变量来调用静态方法,尽管事实上,它将使用的唯一信息是变量的声明类型。这是一个不一致和无益的混乱。为什么允许呢?
编辑:这个编辑是响应克莱顿的答案,声称它允许静态方法的继承。它不。静态方法不是多态的。这是一个简短但完整的程序,以证明:
class Base
{
static void foo()
{
System.out.println("Base.foo()");
}
}
class Derived extends Base
{
static void foo()
{
System.out.println("Derived.foo()");
}
}
public class Test
{
public static void main(String[] args)
{
Base b = new Derived();
b.foo(); // Prints "Base.foo()"
b = null;
b.foo(); // Still prints "Base.foo()"
}
}
正如你所看到的,b的执行时间值被完全忽略。