首页 课程 师资 教程 报名

Java反射调用方法及java反射获取方法

  • 2019-08-21 11:38:57
  • 2472次 动力节点



动力节点java学院小编今天为大家介绍Java反射获取方法以及调用方法。希望看完此文后对大家有帮助,下面就随小编一起来看看Java反射获取方法以及调用方法吧。


  java反射获取方法


  1、先找到方法所在类的字节码


  2、找到需要被获取的方法


  Class类中获取方法:


  public Method[] getMethods();//获取包括自身和继承(实现)过来的所有的public方法——Method不支持泛型<>,即后面不接<>


  public Method[] getDeclaredMethods();//获取自身所有的方法(private、public、protected,和访问权限无关),不包括继承的


  public Method[] getMethod(String methodName, Class...parameterTypes);//表示获取指定的一个公共的方法,包括继承的


  参数: 


methodName:表示获取的方法的名字


  parameterTypes:表示获取的方法的参数的Class类型


  public Method[] getDeclaredMethod(String methodName, Class...parameterTypes);//表示获取本类中的一个指定的方法(private、protected、public,与访问权限无关),不包括继承的方法


  通过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){....}


Classclz=User.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:


Classclz=User.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:


Classclz=User.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);//执行还钱方法,有参传参

 

 

    }

}

选你想看

你适合学Java吗?4大专业测评方法

代码逻辑 吸收能力 技术学习能力 综合素质

先测评确定适合在学习

在线申请免费测试名额
价值1998元实验班免费学
姓名
手机
提交