1. 分析方法四要素 59
* 第一要素:调用哪个对象
* 第二要素:调用哪个方法
* 第三要素:调用方法的时候传什么参数
* 第四要素:方法执行结束之后的返回结果
* 调用哪个对象的哪个方法,传什么参数,返回什么值。
* 即使是使用反射机制调用方法,也同样需要具备这四个要素。
我们先来看一下,不使用反射机制调用一个方法需要几个要素的参与。
有一个这样的类:
package com.powernode.reflect;
/**
* 回顾反射机制 59
**/
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;
}
}
package com.powernode.reflect;
//回顾反射机制 59
public class Test {
public static void main(String[] args) {
// 不使用反射机制调用这些方法
SomeService someService = new SomeService();
someService.doSome();
/**
* 分析:调用一个方法,当中含有几个要素?四要素。
* 第一要素:调用哪个对象
* 第二要素:调用哪个方法
* 第三要素:调用方法的时候传什么参数
* 第四要素:方法执行结束之后的返回结果
*
* 调用哪个对象的哪个方法,传什么参数,返回什么值。
*
* 即使是使用反射机制调用方法,也同样需要具备这四个要素。
*/
String s1 = someService.doSome("张三");
System.out.println(s1);
String s2 = someService.doSome("李四", 250);
System.out.println(s2);
}
}
2. 反射步骤 60
2.1 获取Method
要获取方法Method,首先你需要获取这个类Class
Class<?> clazz=Class.forName("com.powernode.reflect.SomeService");
当拿到Class之后,调用getDeclaredMethod()方法可以获取到方法。
假如你要获取这个方法:doSome(String s, int i)
Method doSomeMethod = clazz.getDeclaredMethod("doSome", String.class, int.class);
获取一个方法,需要告诉Java程序,你要获取的方法的名字是什么,这个方法上每个形参的类型是什么。这样Java程序才能给你拿到对应的方法。
这样的设计也非常合理,因为在同一个类当中,方法是支持重载的,也就是说方法名可以一样,但参数列表一定是不一样的,所以获取一个方法需要提供方法名以及每个形参的类型。
2.2 调用Method 60
要让一个方法调用的话,就关联到四要素了:
● 调用哪个对象的
● 哪个方法
● 传什么参数
● 返回什么值
第一步:创建对象(四要素之首:调用哪个对象的)
Class<?> clazz = Class.forName("com.powernode.reflect.SomeService");
Object obj = clazz.newInstance();
第二步:获取方法
Method doSomeMethod = clazz.getDeclaredMethod("doSome", String.class, int.class);
第三步:调用方法
Object retValue = doSomeMethod.invoke(obj, "李四", 250);
四要素:调用哪个对象、哪个方法、传什么参数、返回什么值。
obj 要素:哪个对象
doSomeMethod 要素:哪个方法
"李四", 250 要素:传什么参数
retValue 要素:返回什么值。
2.3 演示调用doSome(String s, int i)
package com.powernode.reflect;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
//使用反射机制调用方法 60
public class Test2 {
public static void main(String[] args) throws Exception{
// 使用反射机制怎么调用方法。
// 获取类
Class<?> clazz = Class.forName("com.powernode.reflect.SomeService");
// 获取方法
Method doSomeMethod = clazz.getDeclaredMethod("doSome", String.class, int.class);
// 调用方法
// 四要素:调用哪个对象、哪个方法、传什么参数、返回什么值。
// obj 要素:哪个对象
// doSomeMethod 要素:哪个方法
// "李四", 250 要素:传什么参数
// retValue 要素:返回什么值。
//因为我们的clazz.newInstance()方法已经过时了,
// 还可以采用先获调用无参数构造方法然后在调用newInstance()方法
// Constructor<?> con = clazz.getDeclaredConstructor();
// Object o = con.newInstance();
//过时了没关系,不影响使用
Object obj = clazz.newInstance();
Object retValue = doSomeMethod.invoke(obj, "李四", 250);
System.out.println(retValue);
}
}
2.4 演示调用doSome()
package com.powernode.reflect;
import java.lang.reflect.Method;
/**
* 使用反射机制调用方法 60
**/
public class Test3 {
public static void main(String[] args) throws Exception{
// 获取类
Class<?> clazz = Class.forName("com.powernode.reflect.SomeService");
// 获取方法
Method doSomeMethod = clazz.getDeclaredMethod("doSome");
// 调用方法
//创建对象
Object obj = clazz.newInstance();
doSomeMethod.invoke(obj);
}
}
3. SpringDI的核心实现 61
3.1 需求: 61
假设你现在已知以下信息:
1. 有这样一个类,类名叫做:com.powernode.reflect.User
2. 这个类符合javabean规范。属性私有化,对外提供公开的setter和getter方法。
3. 你还知道这个类当中有一个属性,属性的名字叫做 age
4. 并且你还知道age属性的类型是int类型。
请使用反射机制调用set方法,给User对象的age属性赋值。
package com.powernode.reflect;
/**
* SpringDI的核心实现 61
**/
public class User {
private String name;
private int age;
public User() {
}
public User(String name, int age) {
this.name = name;
this.age = age;
}
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;
}
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
package com.powernode.reflect;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
/**
* SpringDI的核心实现 61
**/
public class Test4 {
public static void main(String[] args) throws Exception {
/*
需求:
假设你现在已知以下信息:
1. 有这样一个类,类名叫做:com.powernode.reflect.User
2. 这个类符合javabean规范。属性私有化,对外提供公开的setter和getter方法。
3. 你还知道这个类当中有一个属性,属性的名字叫做 age
4. 并且你还知道age属性的类型是int类型。
请使用反射机制调用set方法,给User对象的age属性赋值。
*/
String className = "com.powernode.reflect.User";
String propertyName = "age";
// 通过反射机制调用setAge(int)方法
// 获取类
Class<?> clazz = Class.forName(className);
// 获取方法名
String setMethodName = "set" + propertyName.toUpperCase().charAt(0) + propertyName.substring(1);
// 根据属性名获取属性类型
Field field = clazz.getDeclaredField(propertyName);
// 获取方法
Method setMethod = clazz.getDeclaredMethod(setMethodName, field.getType());
// 准备对象
Object obj = clazz.newInstance();
// 调用方法
setMethod.invoke(obj, 30);
System.out.println(obj);
}
}