java - 在不同的对象上做同样的事情

标签 java reflection

我目前正在制作一个库,它是一个实用程序,可以让我处理与问题无关的事情(我隐含地没有说主题,因为它并不重要),但它确实使用了反射。

我正在从一个类中检索所有已声明和继承的方法,该类目前工作正常并且不是问题所在。但问题是,我也需要为子类执行此操作,因为子类继承了类似的方法(但是您不能覆盖那些类似的方法)。

我面临的问题是它将使用相同的算法但会有差异,而不是调用 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 对象。

但是我如何检测是否需要调用 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());
}

从技术上讲,您不需要接口(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.forClassesDeclExtractor.forMethods:

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

关于java - 在不同的对象上做同样的事情,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29823815/

相关文章:

java - 我们真的需要一个 REST Java 客户端吗?或者我们可以直接从 HTML 页面触发 REST 请求

reflection - 如何从另一个(开发时)程序访问 TypeScript 中的类型信息?

java - IntelliJ无法在Scala中识别TypeTag

java - java中的语句级反射

java - 使用 class.getDeclaredMethod 反射(reflect)方法时不存在注释

java - 涉及 JOIN 查询的 DAO

java - 我的自定义 JDialog 最小化并且 JScrollPane 的滚动消失

java - JSP 应重定向到新窗口或选项卡中的动态 URL

java - 反转有向图

c# - 在使用属性之前动态查找使用过的属性