1.8 反射

基本的反射

String name = "Huanglinqing";
Class c1 = name.getClass();
System.out.println(c1.getName());
打印结果如下:
java.lang.String

 Type属性

    基本类型都有type属性,可以得到这个基本类型的类型,比如:

Class c1 = Boolean.TYPE;
Class c2 = Byte.TYPE;
Class c3 = Float.TYPE;
Class c4 = Double.TYPE;

获取类成员

当类中方法定义为私有的时候我们能调用?不能!当变量是私有的时候我们能获取吗?不能!但是反射可以,比如源码中有你需要用到的方法,但是那个方法是私有的,这个时候你就可以通过反射去执行这个私有方法,并且获取私有变量。

1、获取类的构造函数

public class Test {
 
    private int age;
    private String name;
    private int testint;
 
    public Test(int age) {
        this.age = age;
    }
 
    public Test(int age, String name) {
        this.age = age;
        this.name = name;
    }
 
    private Test(String name) {
        this.name = name;
    }
 
    public Test() {
    }
}

下面我们通过反射获取这些构造方法

 获取类的所有构造方法

 Test test = new Test();
 Class c4 = test.getClass();
 Constructor[] constructors ;
 constructors = c4.getDeclaredConstructors();

通过getDeclaredConstructors可以返回类的所有构造方法,返回的是一个数组因为构造方法可能不止一个。

调用构造方法

public Test(int age, String name) {
        this.age = age;
        this.name = name;
        System.out.println("hello" + name + "i am" + age);
    }

我们先来调用public的方法,如下所示:
Class[] p = {int.class,String.class};
constructors = c4.getDeclaredConstructor(p);
constructors.newInstance(24,"HuangLinqing");

那么调用私有构造方法呢,和上面一样,只是我们要设置constructors.setAccessible(true);代码如下:

     private Test(String name) {
        this.name = name;
        System.out.println("My Name is" +
                name);
    }

    Class[] p = {String.class};
    constructors = c4.getDeclaredConstructor(p);
    constructors.setAccessible(true);
    constructors.newInstance("HuangLinqing");

调用类的私有方法

  如何调用类中的私有方法呢,我们先在测试类中编写一个测试的私有方法 如下:

  private void welcome(String tips){
        System.out.println(tips);
    }

我们知道如果我们要正常的调用类的方法都是通过类.方法调用,所以我们调用私有方法也需要得到类的实例,而我们上面newInstace已经得到了类的实例,这样就好办了。

   Class[] p4 = {String.class};
   Method method = c4.getDeclaredMethod("welcome",p4);
   method.setAccessible(true);

我们首先通过 getDeclaredMethod方法获取到这个私有方法,第一个参数是方法名,第二个参数是参数类型

然后通过invoke方法执行,invoke需要两个参数一个是类的实例,一个是方法参数。

     Class[] p4 = {String.class};
     Method method = c4.getDeclaredMethod("welcome",p4);
     method.setAccessible(true);
     Object arg1s[] = {"欢迎关注代码男人技术公众号"};
     method.invoke(test,arg1s);

获取类的私有字段并修改值

  看到这里你可能会说,有了set方法,什么私有不私有,test.set不就可以了,但是这里要注意我们是没有办法得到这个类的实例的,要不然都可以得到实例就没有反射一说了。我们在通过反射得到类的实例之后先获取字段:

Field field = c4.getDeclaredField("name");
field.setAccessible(true);
field.set(o,"代码男人");

 o是我们上面通过反射构造方法获取的实例,  打印field.get(o).toString()的值如下:

代码男人

不过要注意的是我们修改了name的值只对当前的实例对象有效。

参考博客:https://blog.csdn.net/huangliniqng/article/details/88554510

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值