Java地基 (十一)----反射(最重要的是理解何为反射)


在这里插入图片描述

定义:

反射是java中提供的一种机制,它允许我们在程序运行的时候,动态获取一个类中的基本信息,并且可以调用类中的属性、方法、构造器

理解:

对Java中的类(八大基本类型+三个引用类型(类,接口,数组))进行抽象,将类中的属性,方法,构造器,注释等抽象出来成为一个叫做Class的类

使用对象表示:

//这个对象c就代表java中的int类型
Class c = int.class;
//判断对象c所代表的类型是否是基本类型
System.out.println(c.isPrimitive());
//获取对象c所代表的类型的名字
System.out.println(c.getName());

三种获取Class对象的方式:按需选择

使用类型名称直接获取
使用Class类中的静态方法forName获取
使用对象调用getClass方法获取

  • Class c1 = Student.class;
  • Class c2 = Class.forName("com.briup.demo.Student");
  • Student stu = new Student(); Class c3 = stu.getClass();

获取类基本信息

//获取类的修饰符
System.out.println(Modifier.toString(c.getModifiers()));
//获取类的名字,全限定名
System.out.println(c.getName());
//获取类的名字,简单类名
System.out.println(c.getSimpleName());
//获取类所属包的名字
System.out.println(c.getPackage().getName());
//获取类的修饰符
System.out.println(Modifier.toString(c.getModifiers()));
//获取类的父类型的名字
System.out.println(c.getSuperclass().getName());
//获取类实现的所有接口
System.out.println(Arrays.toString(c.getInterfaces()));
Class c2 = Object.class;
Class c3 = Action.class;
Class c4 = Mark.class;
Class c5 = String.class;
//判断c2代表的类型是不是c代表类型 的父类型
System.out.println(c2.isAssignableFrom(c));
//判断c3代表的类型是不是c代表类型 的父类型
System.out.println(c3.isAssignableFrom(c));
//判断c4代表的类型是不是c代表类型 的父类型
System.out.println(c4.isAssignableFrom(c));
//判断c5代表的类型是不是c代表类型 的父类型
System.out.println(c5.isAssignableFrom(c));

先获取再调用

获取:

获取类中的public修饰的属性,也包含从父类中继承过来的public属性

  • Field[] getFields()
  • Field getField(String name)

获取类中声明的属性(包含私有的),但是不能获取从父类中继承过来的属性

  • Field[] getDeclaredFields()
  • Field getDeclaredField(String name)
Class c = Class.forName("com.briup.demo.Student");
Field[] fields = c.getDeclaredFields();
for(Field f : fields){
	System.out.println("属性的修饰符:"+Modifier.toString(f.getModifiers()));
	System.out.println("属性的类型:"+f.getType().getName());
	System.out.println("属性的名称:"+f.getName());
	System.out.println("---------------------");
}

调用:

调用属性

Student stu = new Student();
Class c = stu.getClass();
//获取类中名字叫name的属性
Field f1 = c.getDeclaredField("name");
//设置私有属性可以被访问,否则报错
f1.setAccessible(true);
//用反射的方式,给指定对象的name属性赋值
//相当于之前的stu.name = "tom";
f1.set(stu,"tom");
//用反射的方式,获取这个属性的值
//相当于之前的stu.name
System.out.println(f1.get(stu));
System.out.println("----------------------");
//获取类中名字叫age的属性
Field f2 = c.getDeclaredField("age");
//用反射的方式,给指定对象的age属性赋值
//相当于之前的stu.age = 20;
f2.set(stu,20);
//用反射的方式,获取这个属性的值
//相当于之前的stu.age
System.out.println(f2.get(stu));
System.out.println("----------------------");
//获取类中名字叫num的属性
Field f3 = c.getDeclaredField("num");
//用反射的方式,给静态属性num赋值,不需要对象
//相当于之前的Student.num = 99;
f3.set(null,99);
//用反射的方式,获取这个静态属性的值,不需要对象
//相当于之前的Student.num
System.out.println(f3.get(null));

调用方法

注意, public Object invoke(Object obj, Object… args)

  • obj,表示要调用哪个对象的方法,如果是静态方法,可以传null
  • args,可变参数,表示要调用的方法的参数列表
  • m.invoke(obj,null) 中的m,就是通过Class对象获取到的类中的某一个指定的方法

思考一下

Spring中XML文件中传入全限定类名,传入参数自动创建对象

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值