本文主要梳理了java反射机制的如下知识点以方便后续做参考:
java反射的基本概念
在运行状态中,对于任意的一个类,只要知道类名,就能获取到这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法;这种动态获取类的信息以及动态调用对象的方法的功能称为Java反射。
简单代码初识java反射
下面展示一些 java反射基础代码片段
。
package Thread;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class ReflectTest {
public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
// TODO Auto-generated method stub
// 根据类名拿到Class类
Class<?> c=Class.forName("Thread.T");
// 根据类创建一个
T t=(T)c.newInstance();
System.out.println("---------");
// 拿到该类里面的属性
//Field[] fields=c.getFields();// 属性为public的可以获取到
Field[] fields=c.getDeclaredFields();// 属性为private的也可以获取到
for(Field f:fields){
System.out.println("T类的属性:"+f.getName());
}
System.out.println("---------");
// 拿到类的所有方法
Method[] methods=c.getMethods();
for(Method method:methods){
System.out.println("T类的方法:"+method.getName());
if(method.getName().equals("setI")){
method.invoke(t, 1);// 反射调用类的setI方法
System.out.println("i的值:"+t.getI()); // 打印出值看是否有设置成功
}
}
System.out.println("---------");
Constructor[] constructors=c.getConstructors();// 拿到构造方法
for(Constructor cst:constructors){
System.out.println("T类的构造方法:"+cst.getName());
}
}
}
class T{
private int i;
private String name;
public int getI() {
return i;
}
public void setI(int i) {
this.i = i;
}
public T(int i,String name){
this.i=i;
this.name=name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public T(){
System.out.println("T Load");
}
static {
System.out.println("T Constructors");
}
}
Class类中还有下面这些常用的方法
获取所有构造器 getDeclaredConstructors()
获取该类对象 newInstance()
获取类名包含包路径 getName()
获取类名不包含包路径 getSimpleName()
获取类公共类型的所有属性 getFields()
获取类的所有属性 getDeclaredFields()
获取类公共类型的指定属性 getField(String name)
获取类全部类型的指定属性 getDeclaredField(String name)
获取类公共类型的方法 getMethods()
获取类的所有方法 getDeclaredMethods()
获得类的特定公共类型方法: getMethod(String name, Class[] parameterTypes)
获取内部类 getDeclaredClasses()
获取外部类 getDeclaringClass()
获取修饰符 getModifiers()
获取所在包 getPackage()
获取所实现的接口 getInterfaces()*
java反射在spring框架中的使用
1、通过读取xml文件配置来实现
通过dom4j来解析xml,从xml文件中拿到bean配置,再通过反射生成实例对象放置到map容器里,map容器就类似于spring中的beanFactory。本例只是仿spring ioc容器,真实的需要去看源码
spring.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans>
<bean id="springReflectDTO" class="reflect.SpringReflectDTO"></bean>
<bean id="date" class="java.util.Date"></bean>
</beans>
SpringReflectDTO.java
package reflect;
public class SpringReflectDTO {
private int i;
private String name;
public SpringReflectDTO(){
System.out.println("SpringReflectDTO类被加载");
}
public int getI() {
return i;
}
public void setI(int i) {
this.i = i;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
SpringReflect.java
。
package reflect;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
public class SpringRelect {
public static Map<String,Object> map=new HashMap<String,Object>();
public static void main(String[] args) {
// TODO Auto-generated method stub
try{
readXmlConvertFactory();// 从配置文件中读取bean配置信息利用反射创建一个beanFactory
}catch(Exception e){
}
// beanFactory的迭代
Set keySet = map.keySet();
Iterator iterator=keySet.iterator();
while(iterator.hasNext()) {
Object key = iterator.next();
Object value = map.get(key);
System.out.println(key+" "+value.getClass().getName());
}
Object obj=getBeanFromFactory("springReflectDTO");
System.out.println(obj.getClass().getName());
SpringReflectDTO dto=(SpringReflectDTO)obj;
dto.setI(1);
dto.setName("张三");
System.out.println("dto:"+dto.getI()+","+dto.getName());
}
public static void readXmlConvertFactory(){
FileInputStream in =null;
try {
in=new FileInputStream("src/reflect/spring.xml");// io读取文件
} catch (FileNotFoundException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
SAXReader saxReader=new SAXReader();// dom4j 解析xml文件
try {
Document doc=saxReader.read(in);//
Element root=doc.getRootElement();//
List<Element> beans=root.elements();//
System.out.println(beans.size());
for(Element element:beans){
String key=element.attributeValue("id");
String className=String.valueOf(element.attributeValue("class"));
Class<?> c = Class.forName(className);
map.put(key, c.newInstance());// 利用反射生成一个dto实例对象
}
} catch (DocumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
// 根据dto别名可以从工厂拿到实例对象
public static Object getBeanFromFactory(String beanId){
Object obj=map.get(beanId);
return obj;
}
}