我相信你们都知道我的意思 - 代码如下:
Thread thread = new Thread(); int activeCount = thread.activeCount();
引发编译器警告.为什么不是错误?
编辑:
要明确:问题与Threads无关.我意识到在讨论这个问题时经常给出Thread示例,因为它们可能真的搞砸了它们.但问题确实是这样的使用总是无稽之谈,你不能(胜任地)写出这样的电话并且意味着它.这种类型的方法调用的任何例子都是barmy.这是另一个:
String hello = "hello"; String number123AsString = hello.valueOf(123);
这使得它看起来好像每个String实例都带有"String valueOf(int i)"方法.
基本上我认为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不会让你使用一个潜在的未初始化的变量来调用静态方法,尽管事实上它将使用的唯一信息是变量的声明类型.这是一个不一致和无益的混乱.为什么允许呢?
编辑:此编辑是对Clayton的回答的回应,声称它允许继承静态方法.它没有.静态方法不是多态的.这是一个简短但完整的程序来证明:
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
完全被忽略.
为什么会出错呢?该实例可以访问所有静态方法.静态方法不能改变实例的状态(努力是一个编译错误).
您提供的众所周知的示例的问题非常特定于线程,而不是静态方法调用.它看起来好像你正在获取所activeCount()
引用的线程thread
,但你真的得到了调用线程的计数.这是程序员正在制作的逻辑错误.在这种情况下,编译器发出警告是适当的.由您来注意警告并修复您的代码.
编辑:我意识到语言的语法是允许你编写误导性代码的,但请记住,编译器及其警告也是语言的一部分.该语言允许您执行编译器认为可疑的操作,但它会向您发出警告,以确保您意识到它可能会导致问题.
它们不再是一个错误,因为已经存在的所有代码.
我和你在一起,这应该是一个错误.也许应该有一个选项/配置文件供编译器将某些警告升级为错误.
更新:当他们在1.4中引入assert关键字时,它与旧代码具有类似的潜在兼容性问题,只有在您明确将源模式设置为"1.4"时才使其可用.我想在新的源模式"java 7"中可能会出现错误.但我怀疑他们会这样做,考虑到它会造成的所有麻烦.正如其他人所指出的那样,并不是必须阻止您编写令人困惑的代码.Java的语言更改应限制在此时严格必要.
简短的回答 - 语言允许它,所以它不是一个错误.