反射基础

最近在学习框架,而为了更好的理解框架底层的原理,需要对反射有着足够的理解,这几天利用课余时间又复习了下反射,所以总结成博客与大家分享也方便以后的复习,不足之处,请批评指正。

一.反射是什么:

Java反射是Java被视为动态(或准动态)语言的一个关键性质。这个机制允许程序在运行时取得任何一个已知名称的class的内

信息,包括其modifiers(诸如public, static 等)、superclass(例如Object)、实现之interfaces(例如Cloneable),也包括fields

methods的所有信息,并可于运行时改变fields内容或唤起methods。Java反射机制容许程序在运行时加载、探知、使用编译期间完

全未知的classes。换言之,Java可以加载一个运行时才得知名称的class,获得其完整结构。

翻了好多书和博客,大佬们基本都是这么写的,我理解,简单的认为就是在程序运行期间,动态的取得一个类中的所有信息,

field内容,调用method等。具体底层原理,如果了解jvm类加载机制,会对反射有着更好的理解,这里简单来说,就是jvm在

一个类是,会为这个生成一个class对象,这个对象包含此类的诸多信息,反射也是通过这个对象完成的。

二,反射基础知识

我建议先浏览一下api文档,对reflect这个包有个总体的把握,其中Method field Constructor Modifier Proxy 等都是常用的类

1. 取得class对象:

   1.对象.getClass();

   2.类.class

   3.Class.forName(name)  常用

2.获得实例化对象

Public T newInstance() throws InstantiationException,IllegalAcessException

3. 获得方法

构造方法:

Public Constructor<?>[] getConstructors() throws SecurityException

Public Constructor<T> getConstructor(Class<?>... parameterTypes)

利用构造函数获得对象实例:(T)constructor.newInstance(Object obj...);

普通方法:

Public Method[] getMethods()

Public Method getMethod(String name ,Class<?>...parameterTypes) 取得指定参数的方法

 

利用反射调用方法:

Public Object invoke(Object obj,Object params...) 第一个参数为调用对象,后面为参数

 

4. 获得成员:

 

Public Field[] getDeclaredField()

Public Field getDeclaredField(String name) 获得指定的成员

 

Public Field[] getFields()

Public Field getField(String name)

 

这里说一下:对于getFields() 取到的是包括父类中全部public的属性,而getDeclaredfields()取得的是不包括父类的全部范围的属

,即包括private等,其实,对于方法来说,也有此类的方法,道理也是一样,这里只给出最常用的方法

 

Field类常用方法:

Public void set(Object obj,Object value) 相当于对象.属性=内容

Public Object get(Object obj) 相当于对象.属性

Public void setAccessible(boolean flag) 解除封装

注意:如果要调用Field类中的get set方法,必须解除封装

 

5. 其他常用方法

getName()  

Class<?> getSuperClass()

Class<?>[] getInterfaces()

Class<?> type = field.getType() 获得属性类型

Int mo = field.getModifiers(); 获得属性权限修饰符

String modifier = Modifier.toString(mo);

其他的方法,可参考API文档


三.测试代码

下面是我自己实现的一个测试代码,知识熟悉反射的方法,没有实际含义


public class Person {
	private String name;
	private int age;
	
	
	public Person() {
		super();
	}
	public Person(String name, int age) {
		super();
		this.name = name;
		this.age = age;
	}
	
   
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	public String toString(){
		return name +" "+ age;
	}
	
	public void say(String lag){
		System.out.println(lag);
	}
	private void eat(){
			
	}
}


public class ReflectTest {
	public static void main(String[] args){
		try {
			
			Class cls = Class.forName("Reflect.Person");//取得class对象
			System.out.println(cls.getName());   //输出类名
			
			Object obj = (Person)cls.newInstance();  //获取对象实例
			System.out.println(obj.toString());
			
			Method[] methods = cls.getMethods();  //取得所有方法
			System.out.println(methods.length);
			
			Constructor[] cons = cls.getConstructors();  //取得所有构造方法
			System.out.println(cons.length);
			
			Method method = cls.getMethod("setName",String.class);//取得指定参数的方法
			System.out.println(method.toString());
			
			Constructor con = cls.getConstructor(String.class,int.class);//取得指定参数的构造方法
			Person linda = (Person) con.newInstance("Linda",20);//根据构造方法生成实例
			System.out.println(linda.toString());
			
			Method method2 = cls.getMethod("say",String.class);//得到给定方法名的方法
			method2.invoke(linda, "hello"); //运用反射执行方法
			
			
			Field[] fields = cls.getFields(); //获取所有公有属性
			System.out.println(fields.length);
			Field[] pfields = cls.getDeclaredFields();//获取仅此类中全部属性
			System.out.println(pfields.length);
			
			Object bob = (Person)cls.newInstance();
			pfields[0].setAccessible(true);//解除封装
			pfields[0].set(bob, "Bob");
			pfields[1].setAccessible(true);
			pfields[1].set(bob, 25);
			System.out.println(bob.toString());
			
			
			
			
		} catch (ClassNotFoundException e) {
			
			e.printStackTrace();
		} catch (InstantiationException e) {
			
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			
			e.printStackTrace();
		} catch (NoSuchMethodException e) {
			
			e.printStackTrace();
		} catch (SecurityException e) {
			
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			
			e.printStackTrace();
		}
	}
}
控制台输出:

Reflect.Person
null 0
14
2
public void Reflect.Person.setName(java.lang.String)
Linda 20
hello
0
2
Bob 25

四 反射应用

反射在框架中有着广泛的应用,为了更好的学习框架的原理,我们要先学习一些设计模式,下面具体讨论一下反射在工厂模式及

动态代理中的应用,关于设计模式的详细总结,我会在后续的博客中更新。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值