可以使用对象实例访问Java中的静态方法

时间:2011-02-12 12:15:00

标签: java methods static

在Java中,创建静态方法以在没有任何对象实例的情况下访问它。这对我来说很有意义。但最近我遇到了一个奇怪的事情,Java中的静态方法也可以通过其对象实例访问。这对我来说非常奇怪。你们有谁知道为什么这个功能是由Java提供的?什么是允许静态方法被访问以及没有实例的重要性?

5 个答案:

答案 0 :(得分:19)

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

答案 1 :(得分:8)

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

看看this question for more details。正如他们所说,这可能会产生误导,这就是为什么IDE会给你一个警告。

答案 2 :(得分:3)

这是规范允许的,但不建议这样做。此外,像Eclipse这样的IDE标记了对带有警告的对象实例上的静态方法。

答案 3 :(得分:1)

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

o.f();

所以我们需要在f的范围内找到名为o的方法。有人可能认为静态f当然也在o的范围内,即使f实际上是为更大的范围(o的类)定义的< / p>

答案 4 :(得分:-2)

它给你的另一个不错的(虽然有些黑客)功能是能够以对象的形式传递类引用。例如,假设你有以下内容:

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提供了一种形式的一流函数。您可以使用抽象基类定义函数“type”,然后通过覆盖子类中的静态方法来实例化任何正确类型的函数。然后,您可以将对象用作相关静态方法的容器。

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

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());