猴子也能听懂的java反射机制

用一些简单的语言来说明反射机制(但是不一定对,说不定是对的)

反射机制

大概可以理解成所有的类都有一个镜像的Class类,我们可以同过这个class类来正常的访问原来的类我们来看一个例子

package peg;
//这是一个普普通通的类
public class TestClass {
    private int id;
    private  String name;
    public int age=18;

    public TestClass(int id, String name) {
        this.id = id;
        this.name = name;
    }

    public TestClass() {
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        System.out.println(this.name+" "+this.id);
        return null;
    }


    public void f1(int i){
        System.out.println("f1"+i);
    }

    public void f1(){
        System.out.println("f1");
    }


}


public class main {
    public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchFieldException, NoSuchMethodException, InvocationTargetException {

//这是使用反射的方式来创建并调用testclass的f1方法
Class class1 =  Class.forName("peg.TestClass"); //创建对应的class类
Object testclass1 = class1.newInstance();//使用class类来创建testclass对象
Method method = class1.getMethod("f1");//通过Class类来获取testclass类的方法
method.invoke(testClass1);//使用方法(无参数)


//这是我们原来用的方式
TestClass testClass3 = new TestClass();
        testClass.f1();

}

我们发现同样的事情使用反射,代码量活生生增加了一倍,那我们为什么还用反射呢?

1.增加程序的灵活性,避免将程序写死到代码里。

 2.代码简洁,提高代码的复用率,外部调用方便

3.对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法

缺点

反射会让你的程序性能降低

既然优点比缺点多,看来我们非学不可了啊

使用class获取类

Class class1 =  Class.forName("peg.TestClass");
Class class2 = new TestClass().getClass();
Class class3 = TestClass.class;

这三种都是对testclass类获取class类,值得注意的是一个类只能有一个Class东西,所以三个class对象实际上都是同一个对象,因为他们的HashCode print 出来是一样的

使用class创建类

既然我们已经获取并创建了一个class对象,那我们应该用这个Class对象来创建一个我们用来要用的class类了

//有参数构造方法
//使用class对象获取TestClass的有参数构造方法并创建了一个构造器对象constructor
Constructor constructor = class1.getConstructor(int.class,String.class);
//使用这个构造器来创建一个testclass对象
Object testClass2 = constructor.newInstance(99,"大宝");


//无参数构造方法
Object testclass3 = class1.newInstance();//还好,无参数构造方法简单很多

我们甚至还要建一个构造器对象,

使用class获取成员变量

历经险阻我们终于建好了一个testclass对象,那我们先来获取一个变量试一下吧


Field[] fields = class2.getFields();//获取所有public修饰的变量
Field field = class1.getField("age");//获取指定public变量
//这些变量直接print求可以使用了

//下面的方法可以获取指定方法
Field field1 = class1.getDeclaredField("age");

//下面的方法可以获取所有方法
Field[] fields1 = class2.getDeclaredFields();
//"但是如果我们想用private 修饰的变量的话还是报错"
//"废话!本来private变量就要不了"
//"这里就体现出了反射的其中一个优点,就算是private也能访问"

fields1[1].setAccessible(true);//忽略修饰符(暴力访问)
//使用了这个方法后我们发现fields能访问testclass所有的变量了,即使是private也不在话下

field.set(testClass1,20); //设置值
field.get(testClass)//获取值

使用class获取成员方法

现在我们再来用反射的方式来用用testclass的方法吧

Method[] methods = class1.getMethods();//基本同理
Method method = class1.getMethod("f1");//基本同理
//基本上和获取变量是一样的
//使用invoke来使用这些方法
method.invoke(testClass1);//使用方法(无参数)
method.getName();//获取方法名
method1.invoke(testClass1,10);//使用方法有参数

结尾

虽然讲的浅,但是应该还算是好理解吧我讲的,如果想要深入学习还是推荐去B战,CSDN看看,光看我这个肯定是不顶事的,这应该是我的第一篇文章,如果帮助到你了,可以给我点个赞,收个藏,关个注什么的嘛,又不要钱,

个人水平相当有限,如果发现了什么问题也欢迎学习交流

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值