我目前正在创建一个库,这是一个实用程序,可以处理与问题无关的内容(我暗示不会说主题,因为它不是很重要),但它确实使用了反射。
我正在从类中检索所有已声明和继承的方法,这种方法目前工作正常并且不是问题。但问题是,我需要为子类做这个,因为那些继承了类似的方法(但你不能覆盖那些像方法)。
我面临的问题是它会使用相同的算法,但会有所不同,而不是调用clazz.getDeclaredMethods()
我需要调用clazz.getMethods
。什么是最好的方法,我也需要在方法签名中返回Class []和Method []。
通常我会寻找一个共享的超类,但在这种情况下,我更喜欢有相应的Class []和Method []。对于初学者,我做了一些研究并找到了一些共享的超类:
因为我需要Class []和Method []数组,所以我在想 像泛型,所以方法看起来像:
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());
}
从技术上讲,你不需要界面中的getGenericClass
方法,但是我在循环中直接使用extract
所以我不能拉那个类,但是,你可以。
希望这有助于未来的人:)再次感谢@dasblinkenlight的灵感!
答案 0 :(得分:1)
您的getT
需要获得一些输入才能决定做什么。
如何使用
enum
作为参数来确定是否需要获取类或方法? (来自评论)
有一种更好的方法:定义一个执行适当提取的接口,并创建它的两个实例 - 一个用于提取类,另一个用于提取方法:
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);