java 反射使用 Class.getMethod 应注意
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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 方法 就可以
暂时想到的就是这一个解决方案
多参数函数类似
以上是关于java 反射使用 Class.getMethod 应注意的主要内容,如果未能解决你的问题,请参考以下文章