【问题标题】:Static method in Java can be accessed using object instance [duplicate]Java中的静态方法可以使用对象实例来访问[重复]
【发布时间】:2011-06-26 01:36:48
【问题描述】:

在 Java 中创建静态方法以在没有任何对象实例的情况下访问它。这对我来说有点道理。但是最近我遇到了一件奇怪的事情,Java中的静态方法也可以通过它的对象实例来访问。这对我来说看起来很奇怪。有谁知道为什么这个特性是由 Java 提供的?允许使用和不使用实例访问静态方法有什么意义?

【问题讨论】:

标签: java methods static


【解决方案1】:

它为您提供的另一个不错的(虽然有点 hack-y)功能是能够以对象的形式传递类引用。例如,假设您有以下内容:

public abstract class Animal {
    public String name() { return "animal"; }
}

public class Dog extends Animal {
    public String name() { return "dog"; }
}

如果您随后运行以下命令:

Animal a = new Dog();
System.out.println(a.name());

...你会得到:

dog

这实际上意味着通过实例化对象调用静态方法为 Java 提供了一种一流的函数形式。您使用抽象基类定义函数“类型”,然后通过覆盖子类中的静态方法来实例化任何适当类型的函数。然后,您可以像使用这些对象一样简单地使用相关静态方法的容器。

为了更具体,假设我们想要一个函数对字符串数组执行某种字符串编码,并且我们希望它接受一个函数作为参数,该函数对单个字符串执行编码。我们希望参数根据所需的编码而变化。没有一流的功能,这是不可能直接做到的。但是,在对象上调用静态方法为我们提供了一种解决方法:

public abstract class EncodingType {
    public String encode(String s) { return s; }
}

public class Base64Encoding extends EncodingType {
    public String encode(String s) { base64Encode(s); } // Assume "base64Encode" is defined
}

public class Rot13Encoding extends EncodingType {
    public String encode(String s) { rot13Encode(s); } // Assume "rot13Encode" is defined
}

public class Encoder {
    public String[] encodeArray(String[] s, EncodingType enc) {
        for (int i = 0; i < s.length; i++) {
            s[i] = enc.encode(s[i]);
        }
        return s;
    }
}

你可以这样称呼它:

Encoder e = new Encoder();
String[] strs = { ... };
strs = e.encodeArray(strs, new Rot13Encoding());

【讨论】:

  • static?不?没有static的静态方法?
【解决方案2】:

这样做的好处是,它允许您采用实例方法并将其转换为静态方法,而无需修改任何现有代码(类除外),从而允许向后兼容。我发现这很有用,因为我多次遇到可以设为静态的实用程序方法 - 我可以添加 static 修饰符并继续我的方式。

【讨论】:

  • 我没有从这个角度思考。是的,正如你所说,它提供了一个极端的兼容性选项。了解 Java 的指定方式是一种冒险和激动人心的体验。再次感谢:)
  • @Nate W 。所以,向后兼容性是......如果你使用引用调用一个方法,被调用的方法可以是静态的还是非静态的?如果使用对象引用和使用类名调用静态方法是相同的,那么如果该方法具有 synchronized 关键字,那么它会锁定一个 'object' 还是 'class.object'?
【解决方案3】:

虽然它很糟糕,但也没有令人信服的理由禁止它。

o.f();

所以我们需要在o的范围内找到一个名为f的方法。有人可能会争辩说,静态的f 当然也在o 的范围内,尽管f 实际上是为更大的范围定义的(o 的类)

【讨论】:

    【解决方案4】:

    规范允许,但不推荐。此外,Eclipse 之类的 IDE 将对对象实例上的静态方法的访问标记为带有警告。

    【讨论】:

      【解决方案5】:

      语义相同。编译器足够聪明,可以知道您的意思(即通过类访问静态方法)。 IDE 会给你一个警告,告诉你这是不礼貌的:)

      看看this question for more details。正如他们所说,这可能会产生误导,这就是 IDE 会给您警告的原因。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-11-10
        • 1970-01-01
        • 2014-02-19
        • 1970-01-01
        • 2018-09-03
        • 1970-01-01
        • 1970-01-01
        • 2012-04-26
        相关资源
        最近更新 更多