更新时间:2019-08-21 11:38:57 来源:极悦 浏览2342次
极悦java学院小编今天为大家介绍Java反射获取方法以及调用方法。希望看完此文后对大家有帮助,下面就随小编一起来看看Java反射获取方法以及调用方法吧。
java反射获取方法
1、先找到方法所在类的字节码
2、找到需要被获取的方法
Class类中获取方法:
public Method[] getMethods();//获取包括自身和继承(实现)过来的所有的public方法——Method不支持泛型<>,即后面不接<>
public Method[] getDeclaredMethods();//获取自身所有的方法(private、public、protected,和访问权限无关),不包括继承的
public Method[] getMethod(String methodName,
Class
参数:
methodName:表示获取的方法的名字
parameterTypes:表示获取的方法的参数的Class类型
public Method[] getDeclaredMethod(String methodName,
Class
通过java反射调用方法:
1、先找到方法所在类的字节码
2、找到需要被获取的方法
3、调用该方法
class User{
public void sayHello(){...}
public void sayHi(String naem){...}
private void sayGoodBye(String name, int age){...}
}
如何使用java反射调用一个方法?
在Method类中有一个方法:
public Object invoke(Object obj, Object... args);//表示调用当前Method所表示的方法
参数:
obj: 表示被调用方法底层所属对象
args: 表示调用方法时传递的实际参数
返回:方法调用后,底层方法的返回结果
Eg: public String sayYa(String name){....}
Class
Method mt=clz.getMethod(“sayYa”, String.class);
Object obj=clz.newInstance();
Object ret=mt.invoke(obj, “wili”);//要调用实例方法,必须有一个对象,方法的底层对象就是指当前Method所在的类的实例对象,sayHi方法具有返回值,调用该方法后的返回结果使用Object接收
java反射调用私有方法:
Method mt=clz.getDeclaredMethod(“sayGoodBye”, String.class, int.class);
在调用私有方法之前,需设置该方法为可访问的权限:——否则会报错
mt.setAccessible(true);
mt.invoke(clz.newInstance(), “limi”, 17);
java反射调用静态方法
class User{
public static void staticMethod(){
System.out.println(“static mthod invoke.”);
}
}
Eg:
Class
Method staticMethod=clz.getMethod(“staticMthod”);
两种方式调用静态方法:
1、因为静态方法属于所有实例对象公共的,可以创建该类的一个任意对象,通过该对象调用
staticMethod.invoke(clz.newInstance());//staticMethod无参,故参数列表类型不填
2、如果底层方法是静态的,那么可以忽略指定的obj参数,将obj参数设置为null即可
staticMethod.invoke(null);
使用java反射调用可变参数的方法
class User{
public static int sum(int... ages){
System.out.println(args);//打印结果可看出:可变参数底层就是一个数组
Int sum=0;
for(int i : args){
Sum+=i;
}
return sum;
}
public static void show(String... args){...}
}
Eg:
Class
Method m=clz.getMethod(“sum”, int[].class);//可变参数底层就是一个数组
M.invoke(null, new int[]{1,2,3});
Method m=clz.getMethod(“show”, String[].class);
M.invoke(null, new String[]{“A”,”B”,”C”});//会报错,可变参数是引用类型时,底层会自动解包,上述调用被解包后变成M.invoke(null,“A”,”B”,”C”);——为了解决该问题,我们再使用一层数组把实际参数包装起来
M.invoke(null, new Object[]{new String[]{“A”,”B”,”C”}});//正确
通用方法:
以后在使用反射调用invoke方法时,在传递实际参数的时候,无论是基本数据类型,还是引用类型,或者是可变参数类型,把实际参数都包装在一维数组中。
m.invoke(方法的底层对象,new Object[]{实际参数});
Eg:
m.invoke(null, new Object[]{17});//方法参数为基本类型,且只有一个参数,解包后变成m.invoke(null,17});
m.invoke(null, new Object[]{“xxx”});//方法参数为String类型,且只有一个参数
m.invoke(null, new Object[]{new int[]{1,2}});//方法参数为int类型,且为可变参数或者数组类型
m.invoke(null, new Object[]{new String[]{“A”,”B”}});//方法参数为String类型,且为可变参数或者数组类型,new String[]{“A”,”B”}为传递的实际参数
示例:
1、用户类
package com.lf.entity;
import com.lf.annotation.SetProperty;
import com.lf.annotation.SetTable;
public class UserEntity {
private String userName;
private int userAge;
private final int money = 10000;
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public int getUserAge() {
return userAge;
}
public void setUserAge(int userAge) {
this.userAge = userAge;
}
//借钱方法
public int getMoney(){
System.out.println("你借了 " + money + "元!");
return money;
}
//还钱方法,单个参数
public void repay(int money){
System.out.println("你还了 " + money + "元!");
}
//还钱方法,多个参数
public void repay(String userName,int money){
System.out.println(userName+ " 还了 " + money + "元!");
}
}
2、测试类
package com.lf.test;
import java.lang.reflect.Method;
import com.lf.entity.UserEntity;
public class Reflection {
//反射调用方法获取返回值
//第一种方法,获取对象,直接通过对象调用方法
//第二种方法,通过方法名获取方法,执行方法
public static void main(String[] args) throws Exception {
Class<?> userClass = Class.forName("com.lf.entity.UserEntity");
UserEntity userEntity = (UserEntity) userClass.newInstance();
//第一种方法
System.out.println("第一次借钱:");
int money = userEntity.getMoney();
System.out.println("实际拿到钱为: " + money);
System.out.println("------------------------分割线------------------------");
//第二种方法,(无参的示例:借钱)
System.out.println("第二次借钱:");
Method getMoney = userClass.getMethod("getMoney");//得到方法对象
Object money2 = getMoney.invoke(userEntity);//调用借钱方法,得到返回值
System.out.println("实际拿到钱为:" + money2);
System.out.println("------------------------分割线------------------------");
//第二种方法,(单个参数的示例:还钱)
System.out.println("第一次还钱:");
Method repay1 = userClass.getMethod("repay",int.class);//得到方法对象,有参的方法需要指定参数类型
repay1.invoke(userEntity,3000);//执行还钱方法,有参传参
System.out.println("------------------------分割线------------------------");
//第二种方法,(单个参数的示例:还钱)
System.out.println("第二次还钱:");
Method repay2 = userClass.getMethod("repay", String.class,int.class);//得到方法对象,有参的方法需要指定参数类型
repay2.invoke(userEntity,"小飞",5000);//执行还钱方法,有参传参
}
}
0基础 0学费 15天面授
Java就业班有基础 直达就业
业余时间 高薪转行
Java在职加薪班工作1~3年,加薪神器
工作3~5年,晋升架构
提交申请后,顾问老师会电话与您沟通安排学习