Java 访问封闭类或父类的方法的一般方法

Java 访问封闭类或父类的方法的一般方法,java,class,inheritance,reflection,methods,Java,Class,Inheritance,Reflection,Methods,如何访问父类中定义的方法?在这里,我继承了以下遗产: BaseDTO | SortableDTO<T> | BaseSearchArticleDTO | SearchNeedsYearPlus2ArticleDTO 我得到: java.lang.NoSuchMethodException: com.mhis.posm.web.dto.article.search.SearchNeedsYearPlus2ArticleDTO.setSortCriteria1(com.mhis.pos

如何访问父类中定义的方法?在这里,我继承了以下遗产:

BaseDTO
|
SortableDTO<T>
|
BaseSearchArticleDTO
|
SearchNeedsYearPlus2ArticleDTO
我得到:

java.lang.NoSuchMethodException: com.mhis.posm.web.dto.article.search.SearchNeedsYearPlus2ArticleDTO.setSortCriteria1(com.mhis.posm.transversal.bean.sort.SortDataBean)
但如果我这样做:

Method setSortCriteria1 = dto.getClass().getSuperclass().getSuperclass().getDeclaredMethod("setSortCriteria1",SortDataBean.class);
它正在工作。然后我发现了我所做的错误

:

返回一个Method对象,该对象反映 此类对象表示的类或接口。名字 参数是一个字符串,指定所需对象的简单名称 方法,而parameterTypes参数是类对象的数组 以声明的顺序标识方法的形式参数类型。 如果在一个实例中声明了多个具有相同参数类型的方法 类,其中一个方法的返回类型比 该方法比任何其他方法都要具体,返回该方法;否则 其中一种方法是任意选择的。如果名称为“”或 “”引发了NoSuchMethodException

返回反映指定公共成员的方法对象 此类对象表示的类或接口的方法。这个 name参数是一个字符串,指定所需对象的简单名称 方法。parameterTypes参数是 按照声明的顺序标识方法的形式参数类型。如果 parameterTypes为null,将其视为空数组

如果名称为“”或“”,则引发NoSuchMethodException。 否则,将由算法确定要反映的方法 接下来就是。设C为该对象表示的类:

  • 在C中搜索任何匹配方法。如果没有找到匹配方法,则在C的超类上递归调用步骤1的算法

  • 如果在上面的步骤1中没有找到任何方法,则会在C的超级接口中搜索匹配的方法。如有的话 方法被发现,它被反映

在类C中查找匹配的方法:如果C声明了一个具有指定名称和完全相同的形式参数类型的公共方法,则该方法为 反射。如果在C中找到多个这样的方法,并且 这些方法的返回类型比任何 其他人则反映了这种方法;否则,其中一种方法是 任意选择

请注意,一个类中可能有多个匹配方法,因为Java 语言禁止类声明具有相同签名的多个方法,但 不同的返回类型,Java虚拟机不会。这增加了灵活性 在虚拟机中可以实现各种语言功能。例如 协变返回可以用桥接方法实现;桥梁法及其应用 被重写的方法将具有相同的签名,但返回类型不同

因此,我需要为我的案例调用
getMethod
,这就解决了问题

现在我有一个实用程序类:

public class ReflectionUtils{

    private ReflectionUtils() {

    }

    public static <T> Method getMethod(Class<T> instanceClass, String name, Class<?>... parameterTypes) {   
        Method method = null;
        try {
            method = instanceClass.getDeclaredMethod(name,parameterTypes);
        }catch (Exception e) {
        }

        return method;
    }

    public static Object invokeOnMethod(Method method, Object obj, Object... args) {
        try {
            method.setAccessible(true);
            return method.invoke(obj,args);
        }catch (Exception e) {
            return null;
        }
    }
}
公共类ReflectionUtils{
私有单元(){
}
公共静态方法getMethod(类instanceClass、字符串名称、类…参数类型){
方法=null;
试一试{
方法=instanceClass.getDeclaredMethod(名称、参数类型);
}捕获(例外e){
}
返回法;
}
公共静态对象调用方法(方法方法、对象对象、对象…参数){
试一试{
方法setAccessible(true);
返回方法.invoke(obj,args);
}捕获(例外e){
返回null;
}
}
}

如果我想更改方法
公共静态方法getMethod(Class instanceClass、String name、Class…parameterTypes)
,使其捕获任何访问修饰符的方法,并属于封闭类、其超类或接口中的任何位置,我该如何做

根据继承原则,
private
方法不会被Dervied类继承。因此,在您的示例中,
SearchNeedsYearPlus2ArticleDTO
实例无法访问
BaseSearchArticleDTO
中声明的私有方法

因此,使用
SearchNeedsYearPlus2ArticleDTO的
对象
,您可以访问

  • 搜索的所有方法都需要将耳机2插入到
    私有、受保护、公共
  • 层次结构中超类的所有继承方法(
    protected,public
在我看来,你可以有这样的后备机制

try {
        Method m = instanceClass.getMethod(name); // try to get inherited method
        m.setAccessible(true); // if protected setAccessible
        m.invoke(instanceClass.newInstance());
    } catch(NoSuchMethodException ne) {
        try {
            Method m = instanceClass.getDeclaredMethod(name); // try to get declared method in the same class
            m.setAccessible(true); // if private setAccessible
            m.invoke(instanceClass.newInstance());
        } catch (Exception e) {
            e.printStackTrace();
        } 
    } catch (Exception e) {
        e.printStackTrace();
    }

好的。这是我提出的
ReflectionUtils#getMethod

public static Method getMethod(Class<?> instanceClass, String name, Class<?>... parameterTypes) {
    if(ObjectUtils.notEqual(instanceClass,null) && StringUtils.isNotEmpty(name)) {
        Class<?> searchType = instanceClass;

        while (searchType != null) {
            Method[] methods = (searchType.isInterface() ? searchType.getMethods() : searchType.getDeclaredMethods());

            for (Method method : methods) {
                if (name.equals(method.getName()) && (parameterTypes == null || Arrays.equals(parameterTypes, method.getParameterTypes()))) {                           
                    return method;
                }
            }

            searchType = searchType.getSuperclass();
        }
    }       

    return null;
}
瞧。它起作用了。注:为简洁起见,省略了方法
ReflectionUtils#makeAccessible
ReflectionUtils#invokeMethod
的定义。:-)

以下是输出:

public static Method getMethod(Class<?> instanceClass, String name, Class<?>... parameterTypes) {
    if(ObjectUtils.notEqual(instanceClass,null) && StringUtils.isNotEmpty(name)) {
        Class<?> searchType = instanceClass;

        while (searchType != null) {
            Method[] methods = (searchType.isInterface() ? searchType.getMethods() : searchType.getDeclaredMethods());

            for (Method method : methods) {
                if (name.equals(method.getName()) && (parameterTypes == null || Arrays.equals(parameterTypes, method.getParameterTypes()))) {                           
                    return method;
                }
            }

            searchType = searchType.getSuperclass();
        }
    }       

    return null;
}
SearchNeedsYearPlus2ArticleDTO dto = new SearchNeedsYearPlus2ArticleDTO();
Method test = ReflectionUtils.getMethod(dto.getClass(),"test",String.class);
System.out.println("Modifier of the method is private? : " + Modifier.isPrivate(test.getModifiers()));
ReflectionUtils.makeAccessible(test);
ReflectionUtils.invokeMethod(test,dto,"JYM");