反射java.lang.Reflect

反射

Java的动态机制, 用于在运行期间检查对象的类型, 检查对象的类结构(属性,方法等), 还可以动态加载类, 动态创建对象, 动态访问属性和方法, 等.

反射是 Java 的API.

public void print(Object obj){
	//利用反射API,动态检查obj引用的对象类型
	Class cls = obj.getClass();
	System.out.println(obj); 
}

经典面试题目:

Eclipse 中快捷菜单采用了什么技术实现的? 
答案: 反射技术, 反射API

反射的功能

  1. 动态加载类
  2. 动态创建对象
  3. 动态调用属性和方法

静态调用

如下程序编译后就已经确定了执行次序, 执行期间按照编译时候确定的执行顺序执行, 这个情况称为静态执行.

Foo foo = new Foo();
foo.test();

动态执行

Java 反射API提供了动态执行机制

  1. 动态加载类
  2. 动态创建对象
  3. 动态调用属性和方法

动态加载类

在程序运行之前不知道类名, 在运行期间动态根据类名加载类到内存(方法区)

Class cls = Class.forName(类名);

动态创建对象

如下方法可以动态创建类的一个实例

Object obj = cls.newInstance();

使用前提: cls代表的类必须存在无参数构造器! 如果没有无参数构造器则抛出异常.
反射中可以调用有参数构造器

必须使用反射实现的案例:

执行一个类中的全部以test为开头的方法, 这些方法都是非静态方法, 方法没有返回值,没有参数.

如上案例必须使用反射实现!

实现过程:

  1. 动态输入一个类名
  2. 动态加载类型
  3. 动态创建对象
  4. 利用反射查找全部方法信息
  5. 找到以test为开头方法
  6. 利用反射动态执行对象的方法

访问不可见方法

Java中的访问修饰词用于控制 方法和属性的可见范围. 称为封装特性.

反射API可以打破如上封装,实现访问不可见的方法和属性!

method.setAccessible(true); 

动态调用有参数的方法

//找到方法
method=cls.getDeclaredMethod(方法名, 参数类型1, 参数类型2...)
//创建对象
obj=cls.newInstance();
//准备参数
Object method.invoke(obj, 参数1, 参数2, 参数3...)

素材:

class Goo{
	public int test(int a){
		return a+1;
	}	
	public String demo(String s){
		return s + "1";
	}
	public double demo(double d){
		return d+1;
	}
}

案例:

解耦

解除耦合性: 减低/解除 两段代码(两个组件)之间的耦合关系.

public void test(){
	Foo foo = new Foo();
	foo.test();		
}

利用反射API, 可以实现一个组件与未来的一个组件的松散耦合. 甚至可以不在不知道类名不知道方法名的情况下实现调用关系.

动态访问对象的属性

Field 代表类中的属性信息

//读取对象obj的指定属性, 返回属性的值
Object Field.get(obj) 
//设置属性的值
void Field.set(obj, value);

案例: 反射读取对象的一个属性

String className = in.nextLine();	
String name = in.nextLine();	
//动态加载类
Class cls = Class.forName(className);
//动态创建一个对象
Object obj = cls.newInstance();
//获取类的一个属性信息
fld = cls.getDeclaredField(name); 
Object val = fld.get(obj);
System.out.println(val);

修改属性

//obj = foo(age=5, name=Tom)
//fld = age
//value = 10
//检查属性 age=10
String className = in.nextLine();	
String name = in.nextLine();
String value = in.nextLine();	
//动态加载类
Class cls = Class.forName(className);
//动态创建一个对象
Object obj = cls.newInstance();
//获取类的一个属性信息
fld = cls.getDeclaredField(name);

fld.set(obj, value);
System.out.println(obj);

经典案例

需求: 检查一个类是否包含 service(Request req, Response res)方法, 如果包含这个方法, 就执行这个方法. 不包含就抛出异常.
提示: 类名, Request对象, Response对象作为参数输入.

设计:

public void execute(String className, Request req, 
	Response res) throw Exception{
	//动态加载类
	//根据方法签名查找方法 "service" Request Response
	//创建对象, 执行方法
}

这个设计的好处: 解耦

很多框架使用反射

框架为了解决对未来未知组件进行管理, 所有经常使用反射API

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值