我目前正在制作一个库,它是一个实用程序,可以让我处理与问题无关的事情(我隐含地没有说主题,因为它并不重要),但它确实使用了反射。
我正在从一个类中检索所有已声明和继承的方法,该类目前工作正常并且不是问题所在。但问题是,我也需要为子类执行此操作,因为子类继承了类似的方法(但是您不能覆盖那些类似的方法)。
我面临的问题是它将使用相同的算法但会有差异,而不是调用 clazz.getDeclaredMethods()
我需要调用 clazz.getMethods
。解决这个问题的最佳方法是什么,我还需要在方法签名中返回 Class[] 和 Method[]。
通常我会寻找一个共享的父类(super class),但在这种情况下,我更喜欢相应地拥有 Class[] 和 Method[]。对于初学者,我做了一些研究并发现了一些共享的父类(super class):
- 通用声明
- 注释元素
Since I need both Class[] and Method[] arrays I am thinking something like generics, so the method would look like:
public static <T extends GenericDecleration> T[] getT () { }
正如 dasblinkenlight 所提到的,这将不起作用,因为该方法不接受任何参数并且无法检查是否检索 Class 或 Method 对象。
但是我如何检测是否需要调用 getDeclaredMethods
或 getDeclaredClasses
?
在不重复大量代码的情况下如何做到这一点的最佳方法是什么?我真的试图在这里解释自己,但如果仍然不清楚我在做什么,请随时提问!
非常感谢您!
经过一番折腾,我找到了一个完全符合我需求的解决方案。这是泛型和@dasblinkenlight 解决方案的组合,如下所示:
public interface DeclExtractor<T extends GenericDecleration> {
public T[] extract (Class clazz);
public Class<? extends T[]) getGenericClass ();
DeclExtractor<Method> methodExtractor = new DeclExtractor<Method>() {
@Override
public Method[] extract (Class clazz) {
return clazz.getDeclaredMethods();
}
@Override
public Class<? extends Method[]> getGenericClass () {
return Method[].class;
}
}
// Same for Class
}
现在该方法也将返回正确的类型,因此您不必手动将所有 GenericDeclaration 转换为原始对象类型。我的问题是我为它使用了一个集合而不是正确的数组:
public <T> T[] getAll (final DeclExtractor<T> extractor, Class<?> clazz) {
T[] declaration = extractor.extract (clazz);
//.. The algorithm..
// Return an instance of a collection as array (I use a set in my implementation)
final Object[] objects = myCollection.toArray();
return Arrays.copyOf(objects, objects.length, extractor.getGenericClass());
}
从技术上讲,您不需要接口(interface)中的 getGenericClass
方法,但是我在循环中直接使用 extract
所以我无法提取它的类,但是,您能。
希望这对以后的人有帮助 :) 再次感谢@dasblinkenlight 的启发!
最佳答案
您的 getT
需要获得一些输入才能决定要做什么。
What about a method which can takes an
enum
as argument to determine whether it needs to get classes or methods? (from a comment)
有一个更好的方法:定义一个执行适当提取的接口(interface),并创建它的两个实例——一个用于提取类,一个用于提取方法:
public interface DeclExtractor {
GenericDecleration[] extract(Class cl);
final DeclExtractor forClasses = new DeclExtractor() {
public GenericDecleration[] extract(Class cl) {
// make an array of GenericDecleration from extracted classes
}
};
final DeclExtractor forMethods = new DeclExtractor() {
public GenericDecleration[] extract(Class cl) {
// make an array of GenericDecleration from extracted methods
}
};
}
现在您可以重写您的 getT
以获取“提取器”,如下所示:
public static GenericDecleration[] getT (DeclExtractor extractor, Class cl) {
...
// When it's time to get components of the class, make this call:
GenericDecleration[] components = extractor.extract(cl);
...
}
要启动对 getT
的调用,请传递 DeclExtractor.forClasses
或 DeclExtractor.forMethods
:
GenericDecleration[] c = getT(DeclExtractor.forClasses);
GenericDecleration[] m = getT(DeclExtractor.forMethods);
关于java - 在不同的对象上做同样的事情,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29823815/