java深化——反射机制详解

1.1 反射机制介绍

程序在运行的过程中加载一些“只知道相关名字”的类,以下代码,在程序运行时加载 User 类。

            Class c=Class.forName("com.hmq.reflect.User");

一个类被加载后,JVM 会创建一个对应类的 Class 对象,类的整个结构信息会被放到 Class 对象中。

这个 Class 对象就像镜子一样,通过这面镜子,可以得到对应类的全部信息。

1.2 反射机制的常见作用

1) 动态的加载类、动态的获取类的信息(属性,方法,构造器)

2) 动态构造对象

3) 动态调用类和对象的任意方法、构造器

4) 动态调用和处理属性

5) 获取泛型信息

6) 处理注解

1.3 获取 Class 对象的方式

1) 通过字节码文件,类名.class

2) 对象的 getClass()方法

3) Class 类的静态方法 forName(….)

1.4 反射机制的动态操作

获取类的属性:
    Field  getField(String fieldName)    得到公共的属性对象
    Field  getDeclareField(String  fieldName)    得到指定名称的属性对象
    Field [] c.getDeclaredFields()        得到所有的属性对象

获得类的方法:
    Method [] getDeclaredMethods()    得到公共的方法对象
    Method [] c.getMethods        得到父类 及 本类中的公共的方法对象
    Method  getDeclaredMethod(String methodName,Class...type)    得到指定名称的本类中公共的方法
    Method  getMethod(String methodName,Class type)    得到本类 或 父类中公共的方法对象

获得构造方法:
    Constructor [] getDeclaredConstructors()    得到公共的构造方法的对象
    Constructor [] getConstructors()        得到公共的构造方法对象
    Constructor  getDeclaredConstructor(Class...type)    得到指定参数的公共的构造方法对象

下面的例子省略了写User类,只要快捷获得共有的取值、赋值方法,带参构造,无参构造就行。

下面的代码是利用反射获得类的信息

public class TestGetClass {
	public static void main(String[] args) throws Exception {
		User u1=new User();
		Class c = u1.getClass();
		
//		(1) getName()获得完整名字(包名+类名)
		String name = c.getName();
			//getSimpleName()获得简单名字(类名)
		String simpleName = c.getSimpleName(); 
		System.out.println(name);
		System.out.println(simpleName+"\n-----------------\n");
		
//		(2) getField()只能获得公共的属性
		Field field = c.getField("score");
		System.out.println(field);
			//getFields()也只能获得公共的属性
		Field[] fields = c.getFields();
		for(Field f:fields) {
			System.out.println(f);
			System.out.println(f.getModifiers()+"\t"+f.getType()+"\t"+f.getName());
		}
		System.out.println("------------------------");
		
		Class superclass = c.getSuperclass();
//		(3)获取父类全名
		System.out.println(superclass.getName());
			//获取父类类名
		System.out.println(superclass.getSimpleName());
		System.out.println("------------------------");
		
//		(4)获取类的方法信息
			//获得公共的方法对象
		Method[] method = c.getDeclaredMethods();
		for(Method m:method) {
			System.out.println("访问权限"+m.getModifiers());
			System.out.println("方法的名称:"+m.getName());
			System.out.println("方法返回类型:"+m.getReturnType());
			
			Class[] parameterTypes = m.getParameterTypes();
			for(Class pt:parameterTypes) {
				System.out.println("获得方法的参数类型:"+pt.getTypeName());
			}
			System.out.println("---------------------");
		}
		
//		(5)获得类的构造器
		System.out.println("======================================");
		Constructor[] constructors = c.getConstructors();
		for(Constructor cons:constructors) {
			System.out.println(cons);
		}
			//获取指定的构造方法
		Constructor con1=c.getConstructor(null);
		System.out.println(con1);
		Constructor con2=c.getConstructor(String.class,int.class);
		System.out.println(con2);
	}
}

下面的代码是利用反射操作类的信息

public class TestSetClass {
	public static void main(String[] args) throws Exception {
	
		Class c = Class.forName("cn.hmq.entity.User");//获得类对象
		
		//(1)动态操作无参构造的对象
		Constructor con = c.getConstructor(null); //获得User类无参构造方法的对象
		User user = (User) con.newInstance();//用无参构造方法的对象创建User类对象
		
		//(2)动态操作属性
		Field df = c.getDeclaredField("name");
		df.setAccessible(true);//表示这个属性不需要做安全检查了,可以直接访问
		df.set(user, "张三");
		System.out.println("取出name这个属性的值:"+df.get(user));
		
		//(3)动态操作方法
		Method m = c.getDeclaredMethod("setAge", int.class);
		m.invoke(user, 15);
		Method m2 = c.getDeclaredMethod("getAge",null);
		System.out.println(m2.invoke(user));
	}
}

1.5 提高反射效率
    通过setAccessible提高性能:
          a)  setAccessible  是启用和禁止访问安全检查的开关
                 值为true则指示反射的对象在使用时应 取消 java语言访问检查
                 值为false则指示反射的对象 不实施 java语言访问检查
                 并不是为true就能访问  为false就不能访问
          b)  禁止安全检查,可以提高反射的运行速度

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值