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