分析方法四要素
//SystemService.java
package com.powernode.reflect;
public class SystemService {
public void logout(){
System.out.println("退出系统");
}
public boolean login(String username, String password){
if ("admin".equals(username) && "admin123".equals(password)) {
return true;
}
return false;
}
}
//ReflectTest01.java
package com.powernode.reflect;
public class ReflectTest01 {
public static void main(String[] args) {
// 创建对象
SystemService systemService = new SystemService();
// 调用方法并接收方法的返回值
boolean success = systemService.login("admin", "admin123");
System.out.println(success ? "登录成功" : "登录失败");
}
}
调用一个方法一般涉及到四个要素:
- 调用哪个对象的(systemService)
- 哪个方法(login)
- 传什么参数(“admin”,“admin123”)
- 返回什么值(success)
获取Method
要使用反射机制调用一个方法,首先你要获取到这个方法
在反射机制中Method实力代表的是一个方法。那么怎么获取Method实例呢?
//SystemService.java
package com.powernode.reflect;
public class SystemService {
public void logout(){
System.out.println("退出系统");
}
public boolean login(String username, String password){
if ("admin".equals(username) && "admin123".equals(password)) {
return true;
}
return false;
}
public boolean login(String password){
if("110".equals(password)){
return true;
}
return false;
}
}
那么该如何获取到logout()、login(String,String)、login(String)这三个方法
要获取方法Method,首先要获取这个类Class
Class clazz = Class.forName("com.powernode.reflect.SystemService");
当拿到Class之后,调用getDeclaredMethod()方法可以获取到方法。
//获取login(String username,String password)
Method loginMethod = clazz.getDeclaredMethod("login", String.class, String.class);
//获取login(String password)
Method loginMethod = clazz.getDeclaredMethod("login", String.class);
获取一个方法,需要告诉Java程序,你要获取的方法的名字是什么,这个方法上每个形参的类型是什么。这样的Java程序才能给你拿到对应的方法。
这样的设计非常核理,因为在同一个类中,方法是支持重载的,也就是说方法名可以一样,但参数列表一定是不一样的,所以获取一个方法需要提供方法名以及每个形参的类型。
//方法
public void setAge(int age){
this.age = age;
}
//获取方法
Method setAgeMethod = clazz.getDeclaredMethod("setAge", int.class);
如果方法形式参数的个数是0个,那就只需要提供方法名
调用Method
要让一个方法调用的话,就关联到四要素了。
- 调用哪个对象
- 哪个方法
- 传什么参数
- 返回什么值
//SystemService.java
package com.powernode.reflect;
public class SystemService {
public void logout(){
System.out.println("退出系统");
}
public boolean login(String username, String password){
if ("admin".equals(username) && "admin123".equals(password)) {
return true;
}
return false;
}
public boolean login(String password){
if("110".equals(password)){
return true;
}
return false;
}
}
调用方法:
- 创建对象(四要素之首:调用哪个对象的)
Class clazz = Class.forName("com.powernode.reflect.SystemService");
Object obj = clazz.newInstance();
- 获取方法
Method loginMethod = clazz.getDeclaredMethod("login", String.class, String.class);
- 调用方法
Object retValue = loginMethod.invoke(obj, "admin", "admin123");
解说四要素:
- 哪个对象:obj
- 哪个方法:loginMethod
- 传什么参数:“admin”,“admin123”
- 返回什么值:retValue
//test
public class ReflectTest02 {
public static void main(String[] args) throws Exception{
Class clazz = Class.forName("com.powernode.reflect.SystemService");
Object obj = clazz.newInstance();
Method loginMethod = clazz.getDeclaredMethod("login", String.class, String.class);
Object retValue = loginMethod.invoke(obj, "admin", "admin123");
System.out.println(retValue);
}
}
如果调用没有参数,也没有返回值的话
package com.powernode.reflect;
import java.lang.reflect.Method;
/**
* @author 动力节点
* @version 1.0
* @className ReflectTest03
* @since 1.0
**/
public class ReflectTest03 {
public static void main(String[] args) throws Exception{
Class clazz = Class.forName("com.powernode.reflect.SystemService");
Object obj = clazz.newInstance();
Method logoutMethod = clazz.getDeclaredMethod("logout");
logoutMethod.invoke(obj);
}
}
如果知道属性名
package com.powernode.reflect;
/**
* @author 动力节点
* @version 1.0
* @className User
* @since 1.0
**/
public class User {
private String name;
private int 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 +
'}';
}
}
已知:
- 类名为:com.powernode.reflect.User
- 该类中有String类型的name属性和int类型的age属性。
- 并且已知该类的设计符合javabean规范(也就是说属性私有化,对外提供setter和getter方法)
求解:如何通过反射机制给User对象的name属性赋值zhangsan,给age属性赋值20岁
答:
package com.powernode.reflect;
import java.lang.reflect.Method;
public class UserTest {
public static void main(String[] args) throws Exception{
// 已知类名
String className = "com.powernode.reflect.User";
// 已知属性名
String propertyName = "age";
// 通过反射机制给User对象的age属性赋值20岁
Class<?> clazz = Class.forName(className);
Object obj = clazz.newInstance(); // 创建对象
// 根据属性名获取setter方法名
String setMethodName = "set" + propertyName.toUpperCase().charAt(0) + propertyName.substring(1);
// 获取Method
Method setMethod = clazz.getDeclaredMethod(setMethodName, int.class);
// 调用Method
setMethod.invoke(obj, 20);
System.out.println(obj);
}
}