java - Java反射错误Java.lang.NoSuchMethodException,但方法存在
问题描述
我无法在 Spring Boot 中使用 Controller 和 JdbcTemplate 进行 Java 反射。
默认控制器如下所示:
public class DefaultController {
private static final Logger logger = LoggerFactory.getLogger(DefaultController.class);
public JsonResponseDataModel selectOneAuto(Long id, Class<?> repository, HttpServletResponse response){
final JsonResponseDataModel result = new JsonResponseDataModel();
System.out.println("The name of class is " + repository.getName());
Method[] methods = repository.getMethods();
for (Method method : methods) {
System.out.println("Method: " + method.getName());
}
try {
//Method method = repository.getClass().getMethod("selectOne", Long.class);
Method method = repository.getClass().getDeclaredMethod("selectOne", Long.class);
method.invoke(repository, id);
logger.info("selectOneAuto : id={} ", id);
} catch (EmptyResultDataAccessException e) {
result.setEmptyResultDataAccessException("id", id.toString());
} catch (DataAccessException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
return result;
}
}
在 CompanyRepository 类中定义了带有 Long 输入的 selectOne 方法:
@Transactional(readOnly=true)
public CompanyModel selectOne(Long id) {
CompanyModel result = null;
final String sql = "SELECT * FROM company WHERE id=?";
return jdbcTemplate.queryForObject(sql, new Object[]{id}, new CompanyRowMapper());
}
当我创建一个新类“CompanyController extends DefaultController”并调用方法 selectOneAuto 时:
selectOneAuto(id, new CompanyRepository().getClass(), response);
然后它以“Method method = repository.getClass().getDeclaredMethod("selectOne", Long.class);" 行错误结束
"Java.lang.NoSuchMethodException: java.lang.Class.selectOne(java.lang.Long)"
但是“selectOneAuto”方法中的 for 循环输出名为“selectOne”的方法。这里有什么问题?
解决方案
您的代码尝试在Class
.
方法.invoke(存储库,id);
存储库对象是一个实例,Class
因为您new CompanyRepository().getClass()
作为参数传递。
要注意的第二点是存储库已经是 Class 的实例,因此无需在此对象上调用 getClass()。
您应该使用以下代码获取方法对象:
Method method = repository.getDeclaredMethod("selectOne", Long.class);
然后这应该工作:
CompanyRepository repsitoryObj = new CompanyRepository();
method.invoke(repsitoryObj, id);
或者更好更简洁的方法是简单地更改repository
参数的类型,因为CompanyRepository
您的方法如下所示:
public JsonResponseDataModel selectOneAuto(Long id, CompanyRepository repository, HttpServletResponse response){
final JsonResponseDataModel result = new JsonResponseDataModel();
System.out.println("The name of class is " + repository.getClass().getName());
Method[] methods = repository.getClass().getMethods();
for (Method method : methods) {
System.out.println("Method: " + method.getName());
}
try {
//Method method = repository.getClass().getMethod("selectOne", Long.class);
Method method = repository.getClass().getDeclaredMethod("selectOne", Long.class);
method.invoke(repository, id);
logger.info("selectOneAuto : id={} ", id);
} catch (EmptyResultDataAccessException e) {
result.setEmptyResultDataAccessException("id", id.toString());
} catch (DataAccessException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
return result;
}
推荐阅读
- big-o - e^x 与 e^(2x) 的增长顺序相同吗?
- css - JavaFX中关于CSS的三个问题
- ios - 表单中的选取器在 SwiftUI 中留下领先空间
- c++ - c 和 c++ 中的隐式转换问题
- c++ - 堆释放分析
- c# - 当 JsonConstructor 参数名称与 JSON 不匹配时如何抛出异常?
- oracle - Unicode 字符在 Codeignter 中变成问号
- bluetooth - 适用于 Windows 或 android 的蓝牙设备模拟器
- javascript - 延迟 Node JS 中的 foreach 循环
- python - 如何集成pygame和Flask?