文章目录
- 前言
- 一、回顾反射机制之反射调用方法
- 1、编写一个方法类SomeService
- 2、通过反射机制调用SomeService类中的方法
- 二、反射机制之Spring-DI核心实现
前言
调用一个方法当中含有几个要素?
1、调用哪个对象
2、调用哪个方法
3、调用方法的时候传什么参数
4、方法执行结束之后的返回结果
调用哪个对象的哪个方法,传什么参数,返回什么值
即使是使用反射机制调用方法,也同样需要具备这四个要素
一、回顾反射机制之反射调用方法
使用反射机制怎么调用方法
1、编写一个方法类SomeService
public class SomeService {
public void doSome(){
System.out.println("public void doSome()执行。");
}
public String doSome(String s){
System.out.println("public String doSome(String s)执行。");
return s;
}
public String doSome(String s,int i){
System.out.println("public String doSome(String s,int i)执行");
return s+i;
}
}
2、通过反射机制调用SomeService类中的方法
1、获取类:
Class<?> clazz = Class.forName("com.bjpowernode.spring.reflect.SomeService");
2、获取方法:
getDeclaredMethod:
第一个参数:方法名
第二个参数:方法中的参数
在一个类当中,方法名是可以一样的。Java语法中允许方法重载,因此只通过方法名是获取不到方法的,需要借助第二个参数。告诉Java程序到底是哪个doSome方法。通过参数来区分方法。
Method doSomeMethod = clazz.getDeclaredMethod("doSome", String.class, int.class);
3、调用方法:
四要素:调用哪个对象的哪个方法,传什么参数,返回什么值
获取对象的两种方法:
Object obj = clazz.newInstance();
如果觉得该方法已经过时,还可以通过获取类的无参数构造方法创建对象:
//获取无参数构造方法创建对象
Constructor<?> con = clazz.getDeclaredConstructor();
Object obj2 = con.newInstance();
四要素:
//obj:哪个对象
//doSomeMethod:哪个方法
//"小白", 23:传什么参数
//retValue:返回什么值
Object retValue = doSomeMethod.invoke(obj, "小白", 23);
执行结果:
完整代码:
public class Test {
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException {
//获取类
Class<?> clazz = Class.forName("com.bjpowernode.spring.reflect.SomeService");
//获取方法 (参数:方法名,可变长)
Method doSomeMethod = clazz.getDeclaredMethod("doSome", String.class, int.class);
//调用方法
//四要素:调用哪个对象的哪个方法,传什么参数,返回什么值
Object obj = clazz.newInstance();
//获取无参数构造方法创建对象
//Constructor<?> con = clazz.getDeclaredConstructor();
//Object obj2 = con.newInstance();
Object retValue = doSomeMethod.invoke(obj, "小白", 23);
System.out.println(retValue);
}
}
二、反射机制之Spring-DI核心实现
需求:
假设现在已知以下信息:1、有这样一个类,类名叫做:com.bjpowernode.spring.reflect.User
2、这个类符合javabean规范。属性私有化,对外提供公开的setter和getter方法
3、知道这个类当中有一个属性,age
4、并且还知道age属性的类型是int类型
通过反射机制调用相关方法,给User对象的age属性赋值
关键在于
1、通过已知的属性名拼接出方法名:
String setMethodName = "set"+propertyName.toUpperCase().charAt(0)+propertyName.substring(1);
2、根据属性名获取属性类型:
//根据属性名获取属性类型
Field field = clazz.getDeclaredField("age");
然后直接 field.getType() 就是属性类型=int.Class
完整代码:
public class Test4 {
public static void main(String[] args) throws Exception {
//已知类名:
String className = "com.bjpowernode.spring.reflect.User";
//已知属性名:
String propertyName = "age";
//通过反射机制调用setAge(int)方法
Class<?> clazz = Class.forName(className);
//拼接set方法名
String setMethodName = "set"+propertyName.toUpperCase().charAt(0)+propertyName.substring(1);
//根据属性名获取属性类型
Field field = clazz.getDeclaredField("age");
Method setAgeMethod = clazz.getDeclaredMethod(setMethodName, field.getType());
Object o = clazz.newInstance();
//给属性赋值
setAgeMethod.invoke(o, 23);
System.out.println(o);
}
}
执行结果: