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