在不同的对象上做同样的事情的方法

时间:2015-04-23 12:42:51

标签: java reflection

我目前正在创建一个库,这是一个实用程序,可以处理与问题无关的内容(我暗示不会说主题,因为它不是很重要),但它确实使用了反射。

我正在从类中检索所有已声明和继承的方法,这种方法目前工作正常并且不是问题。但问题是,我需要为子类做这个,因为那些继承了类似的方法(但你不能覆盖那些像方法)。

我面临的问题是它会使用相同的算法,但会有所不同,而不是调用clazz.getDeclaredMethods()我需要调用clazz.getMethods。什么是最好的方法,我也需要在方法签名中返回Class []和Method []。

通常我会寻找一个共享的超类,但在这种情况下,我更喜欢有相应的Class []和Method []。对于初学者,我做了一些研究并找到了一些共享的超类:

  • GenericDeclaration
  • AnnotatedElement中
  

因为我需要Class []和Method []数组,所以我在想   像泛型,所以方法看起来像:

public static <T extends GenericDecleration> T[] getT () {

}

正如dasblinkenlight所提到的,这不起作用,因为该方法不会采用任何参数,也无法检查是否检索Class或Method对象。

但我如何检测是否需要拨打getDeclaredMethodsgetDeclaredClasses

如何在不重复大量代码的情况下执行此操作的最佳方法是什么?我真的试图在这里解释自己,但如果还不清楚我在做什么,请随时提出要求!

非常感谢您提前!

在搞乱了这个之后,我找到了一个完全符合我需求的解决方案。这是泛型和@ 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的灵感!

1 个答案:

答案 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.forClassesDeclExtractor.forMethods

GenericDecleration[] c = getT(DeclExtractor.forClasses);
GenericDecleration[] m = getT(DeclExtractor.forMethods);