java反射技术学习

概述

java的反射技术允许我们在程序运行时动态创建一个指定的类,并访问这个类中声明的字段和方法以及注解,这种动态获取类的信息以及动态调用对象的方法的功能称为java语言的反射机制。

JDK提供的用于java反射技术的几个主要类有:ClassLoader、Class、Method、Field、Constructor等,通过这些反射类就可以间接调用目标Class的各项功能。

下面以一个简单实例进行演示:

要通过反射来访问的类:TestVo

package cn.qing.reflect;

public class TestVo {
	private String name;
	private Integer age;	
	
	/**
	 * 一个无参的构造方法
	 */
	public TestVo(){}
	
	/**
	 * 一个带有参数的构造方法
	 * @param name
	 * @param age
	 */
	public TestVo(String name,Integer age)
	{
		this.name = name;
		this.age = age;
	}
	
	public String otherMethod(String info)
	{
		System.out.println("message:"+info);
		return "test\t"+ info;
	}	
	@Override
	public String toString() {
		return "TestVo [age=" + age + ", name=" + name + "]";
	}	
	
	/**************set/get*****************/
	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public Integer getAge() {
		return age;
	}

	public void setAge(Integer age) {
		this.age = age;
	}	
}
通过反射技术访问TestVo的测试类:TestReflect

package cn.qing.reflect;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

public class TestReflect {
	public static void main(String[] args)  {
		TestReflect reflect = new TestReflect();		
		try {
			TestVo testVo = reflect.getTestVo();
			testVo.otherMethod("info");
			System.out.println(testVo.toString());
		} catch (Exception e) {
			e.printStackTrace();
		}
	}	
	public TestVo getTestVo()throws Exception
	{
		//使用当前线程来获取ClassLoader
		ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
		
		//使用装载器来装载指定的Class,此处为类的全路径
		Class clazz = classLoader.loadClass("cn.qing.reflect.TestVo");
		
		//获取类的带有参数的构造器,并实例它,也可以获取无参的构造器
		Constructor constructor =  clazz.getConstructor(String.class,Integer.class);
		TestVo testVo = (TestVo)constructor.newInstance("dog",20);
		
		//获取类声明的方法
		Method method = clazz.getDeclaredMethod("toString", null);
		System.out.println(method.invoke(testVo, null));
		
		//获取类声明的字段
		Field field = clazz.getDeclaredField("name");
		//如果想访问私有属性或方法,可以设置setAccessible为true
		field.setAccessible(true);
		field.set(testVo, "cat");
		
		return testVo;
	}
}

程序输出的结果为:

TestVo [age=20, name=dog]
message:info
TestVo [age=20, name=cat]
 
第一句输出是使用method.invoke()方法来执行TestVo中的toString() 

第二个是通过反射构造的实体TestVo类进行调用otherMethod()方法输出

第三个是在得到成员变量name的反射类Field后重新设置其值为"cat",最后在调用toString()方法输出的


上面的示例可以看出,我们可以通过发射来得到类的构造器,并且通过构造器实例化一个类,也可以得到类中申明的方法,并通过Method.invoke()来回调方法,还可以获得类的成员变量,并为成员变量负值。

java反射的主要类描述:

通过Java反射技术可以从Class对象中获取构造函数、成员变量、成员方法等类元素的反射对象,并以编程的方式通过这些反射对象对反射类进行操作。

这些反射对象类在java.reflect包中定义,下面是最主要的三个反射类:

Constructor:类的构造函数反射类,通过Class#getConstructors()方法可以获得类的所有构造函数反射对象组。可以使用getConstructor(Class<?>... parameterTypes)来获取指定参数的构造器,使用Constructor类的newInstance(Object... initargs)方法来实例化一个对象。

Method:类方法的反射类。通过Class#getMethod(String name,Class<?> .... parameterType)来得到指定的类成员方法,第一个参数name对应的是方法名,第二个参数对应的方法的多个入参的参数类型,通过这种方式只能访问的是类的公共成员方法(public),不能访问其它privateprotected的方法。

通过Class#getDeclaredMethod(String name,Class<?> .... parameterType)可以访问该类中任何已经申明的方法,但是如果想访问privateprotected的方法,需要在得到该Method以后,设置MethodsetAccessible(true),这样才能够正常访问私有方法。

在得到Method对象以后可使用该类的invoke(Object obj, Object... args)方法来执行该Method

Method中还有很多用于获取类方法更多信息的方法:

1、Class<?> getReturnType() 返回该Method的返回值类型

2、getAnnotation(Class<T> annotationClass)  返回该Method方法上申明的annotationClass注解。

3、getDeclaredAnnotations()  得到该Method上申明的所有注解。

4、TypeVariable<Method>[] getTypeParameters() 得到该方法的入参类型数组

5、 Class<?>[] getExceptionTypes() 得到该方法的异常数组。

Field:类的成员变量的反射类。通过Class#getDeclaredFields()方法可以获取该Class中已申明的所有成员变量(包括publicprivate的),使用Class#getDeclaredField(String name)来返回指定名称的成员变量,如果想访问私有的成员变量,可以在得到Field类以后设置setAccessible(ture),这样就可以正常访问私有成员变量。也可以通过Class#getFields()以及Class#getField(String name)来获取Class中已申明的公共成员变量。




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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值