手记

java 反射使用 Class.getMethod 应注意

java 反射使用 Class.getMethod 应注意  记录下

Method method= clazz.getMethod(setMethodName,propertiesClass);
如果使用该方法 会不能获取以多态方式传入的参数  
会抛异常 java.lang.NoSuchMethodException
比如:

public class Student {

private String name;private int age;private List list = new ArrayList();public String getName() {    return name;}public void setName(String name) {    this.name = name;}public int getAge() {    return age;}public void setAge(int age) {    this.age = age;}public List<Object> getList() {    return list;}public void setList(List<Object> list) {    this.list = list;}

}

 public static void main(String[] args) {    try {        Class<?> clazz= Class.forName(Student.class.getTypeName());        List list = new ArrayList();        clazz.getMethod("setList",list.getClass());    } catch (ClassNotFoundException | NoSuchMethodException e) {        e.printStackTrace();    }}    此时会抛异常:    java.lang.NoSuchMethodException: com.jcb.xml.model.Student.setList(java.util.ArrayList)    解决方案:    /** * 获取只有一个参数的对应方法 * @param className * @param methodName * @return */private Method getMethod(String className,String methodName,Class<?> propertiesClass){    Method[] methods=getMethods(className);    for (Method method : methods) {        if(method.getName().equals(methodName)){            if(method.getParameterCount() == 1){                //该函数的参数类型和传入参数类型相同                if(method.getParameterTypes()[0].getTypeName().equals(propertiesClass.getTypeName())){                    return method;                    //该函数的参数类型是传入参数类型的父类                }else if(method.getParameterTypes()[0].getTypeName().equals(propertiesClass.getSuperclass().getTypeName())){                    return method;                }else                {                    Set<String> superClassAndSuperInterfaceList= this.getAllSuperClassAndSuperInterface(propertiesClass);                    //如果传入参数类型是参数类型的子类 也返回改函数                    if(superClassAndSuperInterfaceList.contains(method.getParameterTypes()[0].getTypeName()))                        return method;                }            }        }    }    return  null;}    /** * 获取所有父类类型和父类接口类型 * @param clazz * @return */private Set<String> getAllSuperClassAndSuperInterface(Class<?> clazz){    Set<String> superClassAndSuperInterfaceList = new HashSet<>();    getAllSupersClasss(superClassAndSuperInterfaceList,clazz);    getAllSuperInterfaces(superClassAndSuperInterfaceList,clazz);    return superClassAndSuperInterfaceList;}/** * 递归获取所父类 类型 * @param parentClassList * @param clazz */private Set<String> getAllSupersClasss(Set<String> parentClassList,Class<?> clazz){    parentClassList.add(clazz.getSuperclass().getName());    if(Object.class.getTypeName()!=clazz.getSuperclass().getTypeName()){        //父类也可能实现接口        getAllSuperInterfaces(parentClassList,clazz.getSuperclass());        //递归查询父类        getAllSupersClasss(parentClassList,clazz.getSuperclass());    }    return parentClassList;}/** * 递归获取父类接口 * @param parentInterfaceList * @param clazz */private Set<String> getAllSuperInterfaces(Set<String> parentInterfaceList,Class<?> clazz){    for (Class<?> aClass : clazz.getInterfaces()) {        parentInterfaceList.add(aClass.getTypeName());        //递归查询实现接口        getAllSuperInterfaces(parentInterfaceList,aClass);    }    return parentInterfaceList;}    使用该getMethod 代替反射 Class.getMethod 方法 就可以      多参数函数类似

第二种方法  更清晰  包含多参数函数
/**

  • 获取参数所对应的函数

  • @param className

  • @param argsClass

  • @return
    */
    private Method getMethod(String className, String methodName,Class<?>[] argsClass){
    Method[] methods=getMethods(className);
    for (Method method : methods) {
    if(method.getName().equals(methodName)) {
    if (method.getParameterTypes().length == argsClass.length) {
    if (checkArgsType(method.getParameterTypes(), argsClass)) {
    return method;
    }
    } else {
    continue;
    }
    }
    }

    return null;

    }

    /**


  • @param sourceArgsClass 函数的参数类型

  • @param argsClass 传入函数的参数类型

  • @return
    */
    private boolean checkArgsType(Class<?>[] sourceArgsClass,Class<?>[] argsClass){

    for (int i =0;i< sourceArgsClass.length;i++) {    //aClass.isAssignableFrom(bClass)  判断a是否是b的父类或则父接口    if(!sourceArgsClass[i].isAssignableFrom(argsClass[i]))        return false;}return true;

    }

0人推荐
随时随地看视频
慕课网APP