4

谁能向我解释为什么 java 允许您从实例访问静态方法和成员?一个不好的例子,如果我有一个名为 RedShape 的类,并且它有一个名为 getColor() 的静态方法,它返回“red”,为什么 java 允许您从 RedShape 的实例调用静态方法?在我看来,这似乎违反了 OO 语言设计的一些核心概念。至少,它应该带有编译器警告。

提前致谢。

编辑:

特别是,我问你什么时候有类似的东西

RedShape test = new RedShape();
test.getColor();

其中 getColor 是 RedShape 类的静态方法。这没有任何意义,它被允许并且不会通过 javac 在命令行上发出编译器警告。我看到它“非常不鼓励”,但很好奇在“因为 C++ 允许它”之外允许它是否有技术或合理的原因。

4

5 回答 5

9

我认为实例调用静态方法没有任何问题。那有什么问题?特别是,经常有一些方法在类的逻辑中很有用,但实际上并不需要操作实例本身。

我反对通过实例引用调用静态方法经典例子:

Thread thread = new Thread(...);
thread.sleep(5000); // Doesn't do what it looks like

这在某些 IDE 中带有编译器警告——当然在 Eclipse 中,假设您打开它。(Java / 编译器 / 错误和警告 / 代码样式 / 对静态成员的非静态访问。)我个人认为是 Java 设计中的一个错误。(这是 C# 设法避免复制的错误之一。)

于 2009-09-17T16:16:02.300 回答
3

你真的没有理由真正做到这一点。

我唯一的猜测是它允许你覆盖静态方法,但你不能

如果您尝试以下场景:

Banana 有一个名为“test”的静态方法(这会打印出“banana”)Apple 扩展了 Banana 并“覆盖”了名为“test”的静态方法(这会打印出“apple”)

你做这样的事情:

public static void main(String[] args) {
    Apple apple = new Apple();
    Banana banana = new Banana();
    Banana base = new Apple();

    apple.test();
    banana.test();
    base.test();
}

结果输出是:

apple
banana
banana

如此有效,它几乎没用。

于 2009-09-17T16:26:47.653 回答
0
public class MyClass {
    public static String myString;
}


public class AnotherClass {
   public void doSomething() {
       doAnotherThing();
   }
   public static doAnotherThing() {
       MyClass.myString = "something";
   }

在这里,我们通过从非静态方法调用静态方法(间接)从非静态方法访问静态变量。

于 2012-10-22T09:48:14.553 回答
0

对静态方法的访问允许您在同一类的实例之间共享值,甚至无需创建类实例即可获取值。

在某些情况下,它很方便并且不违反 OO 语言。

于 2009-09-17T16:16:08.837 回答
0

我敢打赌,这是因为最初的设计者是从 C++ 移植功能,到 20/20 事后诸葛亮时,这是一个向后兼容性问题。

那,或者因为当您在类中调用方法时,即使您不必为所有内容添加前缀,this.编译器也会插入它(或等效项),包括静态方法。如果不能从实例中调用静态方法,那么this.在前面添加可能是一个问题(或者会迫使编码人员在他们想在实际实例中使用静态方法时将类名添加到静态方法的前面)。

无论如何,除非我们让早期的语言开发人员之一来回答,否则答案都是推测性的。

于 2009-09-17T19:23:54.083 回答