java 反射

反射

即所有的类全部都存在一个类对象(Class 类),这个类对象用于提供本身的信息,比如几种构造方法,多少属性,普通方法

获取反射对象的方式有三种

  • class.forName() 全限定类名

  • 对象.class

  • 类名.getClass()

 public static void main(String[] args) {
            String className = "charactor.Hero";
            try {
                Class pClass1=Class.forName(className);
                Class pClass2=Hero.class;
                Class pClass3=new Hero().getClass();
                System.out.println(pClass1==pClass2);
                System.out.println(pClass1==pClass3);
            } catch (ClassNotFoundException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
    }
}
//以上代码会打印两个true, 因为一个类只有一个类对象, 所以上面三种方法获取的都是同一个类对象

获取类对象时会导致属性初始化,无论什么途径获取类对象,都会导致静态属性被初始化,而且只会执行一次。(除了直接使用 Class c = Hero.class 这种方式,这种方式不会导致静态属性被初始化)

通过反射获取对象

public class TestReflection {
    public static void main(String[] args) {
        //传统的使用new的方式创建对象
        Hero h1 =new Hero();
        h1.name = "teemo";
        System.out.println(h1);
        try {
            //使用反射的方式创建对象
            String className = "charactor.Hero";
            //类对象
            Class pClass=Class.forName(className);
            //构造器
            Constructor c= pClass.getConstructor();
            //通过构造器实例化
            Hero h2= (Hero) c.newInstance();
            h2.name="gareen";
            System.out.println(h2);
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}
//写成一行
//Hero h2=Class.forName("charactor.Hero").getConstructor().newInstance();
//获取类对象 获取类的构造方法,执行进行实例化操作

通过反射操作属性

 public static void main(String[] args) {
            Hero h =new Hero();
            //使用传统方式修改name的值为garen
            h.name = "garen";
            try {
                //获取类Hero的名字叫做name的字段
                Field f1= h.getClass().getDeclaredField("name");
                //修改这个字段的值
                f1.set(h, "teemo");
                //打印被修改后的值
                System.out.println(h.name);
​
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
    }

getField 和 getDeclaredField 的区别 这两个方法都是用于获取属性字段,getField 只能获取 public 的,包括从父类继承来的字段。getDeclaredField 可以获取本类所有的字段,包括 private 的,但是不能获取继承来的字段,通过 field.setAccessible(true)强行反射

通过反射调用方法

 public static void main(String[] args) {
        Hero h = new Hero();
​
        try {
            // 获取方法名setName,参数类型是String的方法
            Method m = h.getClass().getMethod("setName", String.class);
            // 对h对象,调用这个方法
            m.invoke(h, "盖伦");//调用方法用invoke()
            // 使用传统的方式,调用getName方法
            System.out.println(h.getName());
​
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
​
    }

双亲委派机制

当一个类被加载的时候会通过本身的加载器中加载,如果没有向上查找双亲加载器(这就叫做双亲委派机制)加载成功,生成模板Class,也就是描述了类所有的信息的大Class类

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值