反射(Reflection)的学习笔记Day01

一、反射是什么?

反射是动态语言的关键,反射机制运行java在执行期间,借助Reflection提供的API取得任何类的内部信息,
并能直接操作任意对象的内部属性与方法。

二、反射机制:动态代理的关键

1.主要API:

  • java.lang.Class:代表一个类:用来描述类的类,个人视其为反射的源头,因为涉及反射都要先使用Class
  • java.lang.reflect.Method:代表类的方法
  • java.lang.reflect.Field:代表类的成员变量
  • java.lang.reflect.Constructor;代表类的构造器*
    号外:几个不熟悉的单词:
    Declare:声明,属性
  • invoke:调用

2.疑问

反射机制与面向对象中的封装性是否矛盾?

答:不矛盾,二者各有各自的使用环境

两者的使用时机:

  •           1.一般情况下建议使用直接new的方式
    
  •           2.使用反射方式的时机:
    
  •                 1> 编译时无法确定到底要造哪个类的对象,可以使用反射的方式
    
  •                 2> 根据实际情况动态的使用
    

二、反射的简易实例和基础方法:

@Test
public void Test2() throws Exception {
//反射的操作
//通过反射造类的对象
Class clazz =Person.class;
//通过反射获取构造器
Constructor cons = clazz.getConstructor(String.class, int.class);//获取构造器
Object tom = cons.newInstance(“Tom”, 12);//造Person类的对象
Person p = (Person) tom;
System.out.println(p.toString());

    //通过反射获取对象的属性方法
    Field age = clazz.getDeclaredField("age");//创造属性的对象
    age.set(p,10);
    System.out.println(p.toString());
    //获取类中的方法
    Method show = clazz.getDeclaredMethod("show");
    show.invoke(p);//调用对象p的show方法

    System.out.println("************************");
    //通过反射,可以调用Person类的私有结构,比如私有的构造器,私有的方法

    Constructor con1 = clazz.getDeclaredConstructor(String.class);
    con1.setAccessible(true);
    //构建p1的对象
    Person p1 =(Person) con1.newInstance("Jerry");
    //私有属性age = 0
    System.out.println(p1);

    //调用私有方法
    Field name = clazz.getDeclaredField("name");
    name.setAccessible(true);
    //修改p1对象的属性
    name.set(p1,"HanMeiMei");
    System.out.println(p1);

    //调用私有的方法
    Method showNation = clazz.getDeclaredMethod("showNation", String.class);
    showNation.setAccessible(true);
    //调用p1的私有方法,填入参数
    String nation = (String) showNation.invoke(p1, "中国");//私有方法的返回值类型就是该方法的类型
    System.out.println(nation);
}

三、Class类实例创建方式:

//Class的实例的获取
@Test
public void Test1() throws ClassNotFoundException {
//获取Class实例的方式:四种
//方式一:调用运行时类的属性
Class clazz1 = Person.class;
System.out.println(clazz1);
//方式二:通过运行时类的对象:调用getclass方法
Person person1 = new Person();
Class<? extends Person> clazz2 = person1.getClass();
System.out.println(clazz2);
//方式三:调用Class的静态方法,需要输入包在内的类的全类名
//此方法可以更好的展现java反射API的动态性
Class<?> Clazz3 = Class.forName(“ReflectionTest.Person”);
Class<?> Clazz4 = Class.forName(“java.lang.String”);
System.out.println(Clazz3);
System.out.println(Clazz4);
//判断地址值是否指向同一对象:true
//表明几种方式只是不同的获取方式,并非不同的创建方式
//只要数组的元素类型和维度一样,就是同一个class
System.out.println(clazz1 == clazz2);//true
System.out.println(clazz1 == Clazz3);//true
//方式四:使用类的加载器;ClassLoader
//通过当前测试类.class获取ClassLoader
ClassLoader classLoader = Reflections.class.getClassLoader();
//使用classloader的loadclass方法,输入全类名来获取Class类的实例
Class<?> clazz5 = classLoader.loadClass(“ReflectionTest.Person”);
System.out.println(clazz5);

}

哪些类可以拥有Class类的实例对象?

1.class:外部类,成员(成员内部类,静态内部类),局部内部类,匿名内部类
* 2.interface:接口
* 3.enum:枚举
* 4.[]数组
* 5.annotation:注解
* 6.primitive type:基本数据类型
* 7.void:void也可以视作一种void类

总结

反射是之后动态代理的关键,反射的引用让java有了一定的动态性。加载完类之后,在堆内的方法区中就产生了一个Class类型的对象,
这个对象就包含了完整的类的结构信息,我们可以通过这个对象看到类的结构,这个对象就像一面镜子,透过这个镜子看到类的结构,所以
将其称之为反射

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值