Java:如何查找某个方法是否被基类重写?
如何确定一个方法是否被子类覆盖?
例如,
public class Test {
static public class B {
public String m() {return "From B";};
}
static public class B1 extends B {
}
static public class B2 extends B {
public String m() {return "from B2";};
}
/**
* @param args
* @throws FileNotFoundException
*/
public static void main(String[] args) {
B b1 = new B1();
System.out.println("b1 = " + b1.m());
B b2 = new B2();
System.out.println("b1 = " + b2.m());
}
}
给定 B 的实例,我如何知道是否有任何派生类像 B2 一样重写了方法 m() ?
更新:我的问题不清楚。实际上,我想问的是,这是否可以在不诉诸反思的情况下实现。此检查是在紧密循环中完成的,并用于性能黑客以节省一些 CPU 周期。
How to find out if a method is overridden by child classes?
For example,
public class Test {
static public class B {
public String m() {return "From B";};
}
static public class B1 extends B {
}
static public class B2 extends B {
public String m() {return "from B2";};
}
/**
* @param args
* @throws FileNotFoundException
*/
public static void main(String[] args) {
B b1 = new B1();
System.out.println("b1 = " + b1.m());
B b2 = new B2();
System.out.println("b1 = " + b2.m());
}
}
Given an instance of B, how do I know if any derived classes have overridden method m() like B2?
Update: My question wasn't clear. Actually, I was trying to ask if this is possible without resorting to reflection. This check is done in a tight loop and it's used in a performance hack to save a few CPU cycles.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
这个问题有助于演示如何获取该方法属于哪个类的信息:
Java中如何快速判断一个方法是否被重写
This question helps demonstrate how to get the information of which class that method belongs to:
How to quickly determine if a method is overridden in Java
我认为到目前为止的答案是假设您有一个方法,并试图确定该方法是否在类中被重写。
然而,实际提出的问题是“给定 B 的一个实例,我如何知道是否有任何派生类像 B2 一样重写了方法 m() ?”
使用标准 Java 方法无法做到这一点,因为 Java 在引用类之前不会加载类。例如,假设您有一个从网络上的一个 jar(或多个 jar)加载的 URL 类加载器。 Java 不知道这些网络 jar 文件中包含哪些类,更不用说它们是否碰巧覆盖了特定方法。
我认为我已经在 Apache commons 中看到过实用程序,它们会尝试彻底搜索类加载器的层次结构以组装所有可用类的列表,但这对我来说听起来是一个非常糟糕的主意。一方面,它将触发 JVM 中每个类的每个静态初始化块。
有一些工具(例如服务提供者接口)可以在 jar 的 META-INF 目录中列出实现特定接口的类名称,也许您应该查看该路由。
I think the answers so far are assuming that you have a method and are trying to determine whether that method is overridden in a class.
However, the actual question asked was "Given an instance of B, how do I know if any derived classes have overridden method m() like B2?"
This is not possible to do using standard Java methodology, because Java does not load classes until they are referenced. For example, assume you have a URL classloader loading from a jar (or many jars) on the network. Java has no idea what classes are contained in those networked jar files, let alone whether they happen to override a particular method.
I think that I've seen utilities in Apache commons that will try to exhaustively search the hierarchy of classloaders to assemble a list of all available classes, but this sounds like a pretty bad idea to me. For one thing, it will trigger every single static initializer block for every class in the JVM.
There are some facilities like the Service Provider Interface to list class names in the jar's META-INF directory that implement a certain interface, maybe you should look at that route.
改进 Pavel Savara 的帖子,这是我的方法版本,也适用于接口:
Improving the post by Pavel Savara, here's my version of the method that works for interfaces too:
这是我的解决方案,它是用 Kotlin (JVM 语言)编写的。
它与 Java 100% 兼容,所以我想它可以很容易地翻译。理论上它应该处理所有棘手的覆盖情况,例如泛型、范围、不兼容的签名等。我希望这会有所帮助!
Here is my solution, it's written in Kotlin (JVM language).
It's 100% compatible with Java so I guess it can be easily translated. It should theoretically handle every tricky cases of overriding such as generics, scopes, incompatible signatures etc. I hope this will help!
Java 的反射 API 有一个
Method
类,该类有一个名为getDeclaringClass()
的方法。这可能适合你的需要。这是 API:http://download.oracle.com/javase/6/docs/api/java/lang/reflect/Method.html#getDeclaringClass()
Java's reflection API has a
Method
class which has a method calledgetDeclaringClass()
. That might work for what you need. Here is the API:http://download.oracle.com/javase/6/docs/api/java/lang/reflect/Method.html#getDeclaringClass()
java 支持注释。
如果您不确定实现的方法是否被基类覆盖。
只需在子类中的方法开始之前使用 @Override 关键字即可。
如果该方法确实可以重写方法,那么它会编译得很好。
否则会报错。
简单的 :)
java supports Annotations.
If you are not sure if method implemented is overridden from base class.
Just use @Override keyword before your method start in child class.
If that method really can a overridden method then it would compile fine.
otherwise it will give give error.
Simple :)