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

查看:26
本文介绍了为什么通过实例调用静态方法不是 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?

需要明确的是:问题与线程无关.我意识到在讨论这个问题时经常会给出 Thread 的例子,因为它们有可能把事情弄得一团糟.但真正的问题是,这样的用法总是 胡说八道,你不能(称职地)写这样一个电话并且是认真的.这种类型的方法调用的任何例子都会很糟糕.这是另一个:

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 的值.如果 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天全站免登陆