Java基础_13_反射机制

13 篇文章 0 订阅

__________反射机制__________

反射的基石:Class类

概述

反射就是把Java类中的各种成分映射成相应的Java类。

Java程序中所有的类也是一类事物,Class类就是用于描述Java类的。Method类就是用于描述Java类中方法的。所有类在加载进去内存时都会生成一段唯一的字节码,创建对象的实例就是复制这份字节码生成新的对象。

Class对象为内存当中的一份字节码。在Java虚拟机启动的时候会预先加载8个预定义的Class实例对象(字节码):8个基本数据类型和关键字void。包装类型的TYPE就是基本数据类型的字节码

获取字节码的方式

1、通过类名获得

String.class

2、通过类的对象获取

String str = "s";
s.getClass();

3、通过Class类加载类文件,并返回这份字节码

Class.forName(java.lang.String);

Constructor类

得到某个类所有的构造方法:

Constructor[] cons = Class.forName(java.lang.String).getConstructors();

得到某个类的某个构造方法:

//依靠参数类型,如获取String(StringBuilder builder):
Constructor con = Class.forName(java.lang.String).getConstructor(StringBuilder.class);

通过反射创建一个对象:

1.通过Class对象获取Constructor对象,调用对象的newInstance方法创建
Constructor con = String.class.getConstructor(StringBuilder.class);
String str = (String)con.newInstance(new StringBuilder("abc"));
2.通过Class对象的newInstance:
/*
创建时调用的是无参数构造方法对象的newInstance方法。
此方法第一次调用后会将不带参数的构造方法Constructor对象缓存起来方便下次使用。
*/
String.class.newInstance();


Field类

概述:

用于描述类中成员变量的类。

简单操作演示:

public class Demo {
	public static void main(String[] args) throws Exception {
		ReflectPoint rp = new ReflectPoint(1,2);
		//此方法只能得到可见的成员变量
		Field fieldY = rp.getClass().getField("y");
		System.out.println(fieldY.get(rp));
		/** 
		 * 注意这里能取得结果的原因是y是public变量 
		 * 对于x为private,getField只能取得可访问的变量,getDeclaredField可取的不可见的变量 
		 * 对于不可访问变量的值调用get时会抛异常,当然也可以这样取得(不推荐)-->取消访问检查 
		 */  
		Field fieldX = rp.getClass().getDeclaredField("x");
		//取消Java语言访问检查
		fieldX.setAccessible(true);
		System.out.println(fieldX.get(rp));
		//修改rp对象成员变量x的值
		fieldX.set(rp, 3);
		System.out.println(fieldX.get(rp));
	}
}
class ReflectPoint {
	private int x;
	public int y;
	public ReflectPoint(int x, int y) {
		super();
		this.x = x;
		this.y = y;
	}
}

Method类

概述:

用于描述类中方法的类。

简单操作演示:

public static void main(String[] args) throws Exception {
	String str = "abc";
	Method methodCharAt = String.class.getMethod("charAt", int.class);
	//当方法为静态方法时,传入对象为null就可以了
	char c = (char) methodCharAt.invoke(str, 1);
	/*
	 * JDK1.5版本以前的invoke方法传递的参数是对象+Object[]数组
	 * JDK1.5以后将数组替换成了可变参数,但是为了兼容老版本,所以兼容了数组的方式
	 * 所以当传入一个数组参数的时候,会被拆才当成多个参数,对此有两个解决方案,我们以foo方法为例
	 */
	Method method = Demo.class.getMethod("foo", String[].class);
	//此方法传入的数组会被拆分成两个参数,报错
	//method.invoke(null, new String[]{"cc","dd"});
	//下面两种方式都可以:1.使用的是老版本的方法。2,使用的是新版的可变参数方法
	method.invoke(null, new Object[]{new String[]{"cc","dd"}});
	method.invoke(null, (Object)new String[]{"aa","bb"});
}
public static void foo(String[] args){
	for(String s : args)
		System.out.println(s);
}

Array类

概述:

Array 类提供了动态创建和访问 Java 数组的方法。

简单操作演示:

//打印方法,如果是数组就打印数组中的元素
//支持基本数据类型数组
public static void printObject(Object obj) {
	Class clazz = obj.getClass();
	if(clazz.isArray()) {
		//Array类可以直接获取数组对象的长度
		int len = Array.getLength(obj);
		for(int i=0; i<len; i++) {
			//通过Array可以直接获取数组元素
			System.out.println(Array.get(obj, i));
		}
	} else
		System.out.println(obj);
}

反射实现框架原理

概述:

框架与工具类不一样,框架就是调用用户提供的类,工具类是被用户类调用。前者在编译的时候是不知道用户会提供什么类的,后者却清楚。

原理:

从配置文件中读取用户提供的类名,利用反射加载并且创建类对象。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值