为什么不通过实例调用静态方法作为Java编译器的错误? [英] Why isn't calling a static method by way of an instance an error for the Java compiler?

查看:126
本文介绍了为什么不通过实例调用静态方法作为Java编译器的错误?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我相信你们都知道我的意思 - 代码如:

I'm sure you all know the behaviour I mean - code such as:

Thread thread = new Thread();
int activeCount = thread.activeCount();

引发编译器警告。为什么不是错误?

provokes a compiler warning. Why isn't it an error?

编辑:

要清楚:问题与Threads无关。我意识到在讨论这个问题时经常给出Thread示例,因为它们可能会真正搞乱它们。但问题确实是这样的使用始终无意义,你不能(胜任)写这样的电话并且意味着它。这种方法调用的任何一个例子都是barmy。这是另一个:

To be clear: question has nothing to do with Threads. I realise Thread examples are often given when discussing this because of the potential to really mess things up with them. But really the problem is that such usage is always nonsense and you can't (competently) write such a call and mean it. Any example of this type of method call would be barmy. Here's another:

String hello = "hello";
String number123AsString = hello.valueOf(123);

这使得它看起来好像每个String实例都带有String valueOf(int i)方法。

Which makes it look as if each String instance comes with a "String valueOf(int i)" method.

推荐答案

基本上我认为Java设计师在设计语言时犯了一个错误,因此修复它已经太晚了涉及的兼容性问题。是的,它可能导致非常误导性的代码。是的,你应该避免它。是的,您应该确保您的IDE配置为将其视为错误IMO。如果您自己设计一种语言,请记住这一点作为避免的事情的一个例子:)

Basically I believe the Java designers made a mistake when they designed the language, and it's too late to fix it due to the compatibility issues involved. Yes, it can lead to very misleading code. Yes, you should avoid it. Yes, you should make sure your IDE is configured to treat it as an error, IMO. Should you ever design a language yourself, bear it in mind as an example of the kind of thing to avoid :)

为了回应DJClayworth的观点,这里是允许的C#:

Just to respond to DJClayworth's point, here's what's allowed in 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 <的值/ em>的。如果 SomeMethod()是静态方法,则该期望无效;代码欺骗了我。怎么可能是好的呢?

Why do I think it's misleading? Because if I look at code someVariable.SomeMethod() I expect it to use the value of someVariable. If SomeMethod() is a static method, that expectation is invalid; the code is tricking me. How can that possibly be a good thing?

奇怪的是,Java不会让你使用一个潜在的未初始化的变量来调用静态方法尽管事实上它将使用的唯一信息是变量的声明类型。这是一个不一致和无益的混乱。为什么允许它?

Bizarrely enough, Java won't let you use a potentially uninitialized variable to call a static method, despite the fact that the only information it's going to use is the declared type of the variable. It's an inconsistent and unhelpful mess. Why allow it?

编辑:此编辑是对Clayton答案的回应,声称它允许继承静态方法。它没有。静态方法不是多态的。这是一个简短但完整的程序来证明:

This edit is a response to Clayton's answer, which claims it allows inheritance for static methods. It doesn't. Static methods just aren't polymorphic. Here's a short but complete program to demonstrate that:

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 的执行时间值。

As you can see, the execution-time value of b is completely ignored.

这篇关于为什么不通过实例调用静态方法作为Java编译器的错误?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆