java反射
- 正在运行,动态获取这个类的所有信息
- 反编译:.class–>.java
- 通过反射机制访问java对象的属性,方法,构造方法
应用场景
- jdbc加载驱动
- spring ioc
- 框架
反射使用
第一种无参构造器使用
- 类文件创建
package zx.lol.reflaction1;
public class UserEntity {
private String name;
private int id ;
public UserEntity() {
System.out.println("无参构造器");
}
public UserEntity(int id ) {
System.out.println("you参构造器id:"+id);
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
}
- 使用反射创建对象
package zx.lol.reflaction1;
public class classform {
public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
//1.实例对象的方法1,除了new,可以使用反射机制创建对象
//2.Class.forName("zx.lol.reflaction1.UserEntity");传入完整的类路劲
Class<?> forname = Class.forName("zx.lol.reflaction1.UserEntity");
//3newinstance,使用无参构造器,创建对象
Object newinstance = forname.newInstance();
//4 强转object为userentity
UserEntity user = (UserEntity) newinstance;
System.out.println("user: "+user);
user.setId(9667);
System.out.println(user.getId());
}
}
- 输出结果
无参构造器
user: zx.lol.reflaction1.UserEntity@15db9742
9667
在将类文件中无参构造器注释之后,报错
Exception in thread "main" java.lang.InstantiationException: zx.lol.reflaction1.UserEntity
at java.lang.Class.newInstance(Unknown Source)
at zx.lol.reflaction1.classform.main(classform.java:10)
Caused by: java.lang.NoSuchMethodException: zx.lol.reflaction1.UserEntity.<init>()
at java.lang.Class.getConstructor0(Unknown Source)
... 2 more
可知,newinstance使用的是无参构造器,创建对象new。
第二种有参构造器
Class<?> forname = Class.forName("zx.lol.reflaction1.UserEntity");
//3newinstance,使用无参构造器,创建对象
Constructor<?> constructor = forname.getConstructor(int.class);
Object newinstance = constructor.newInstance(9567);
//4 强转object为userentity
UserEntity user = (UserEntity) newinstance;
- 运行结果
you参构造器id:9567
与无参构造器区别在与获得class后,获得使用Constractor获得构造器,注意.getConstructor(int.class);传入参数类型,与类文件中有参构造器中参数类型相同,之后使用constructor调用newInstance,得到对象。
使用反射获取类中的所有方法
Class<?> forname = Class.forName("zx.lol.reflaction1.UserEntity");
//获取所有方法
Method[] method = forname.getDeclaredMethods();
for (Method method2 : method) {
System.out.println(method2.getName());
- 运行结果
getName
getId
setName
setId
- 为什么继承的父类中的方法没有打印出来
因为调用的api,过滤。如果将getDeclaredMethods替换为getMethods,即可将object中的方法一并打印出来。- 打印结果如下
getName
getId
setName
setId
wait
wait
wait
equals
toString
hashCode
getClass
notify
notifyAll
获取所有的成员属
forname.getDeclaredFields();
使用反射获取类中私有属性
Class<?> forname = Class.forName("zx.lol.reflaction1.UserEntity");
Object oj= forname.newInstance();
Field field = forname.getDeclaredField("id");
field.setAccessible(true);
field.set(oj, 111233);
UserEntity user = (UserEntity) oj;
System.out.println(user.getId());
- 运行结果
无参构造器
111233
springIOC
- spring : 将每个bean与bean之间的关系,交于第三方容器(spring)去管理。
- spring原理就是使用反射+dom4j。
- 具体实现代码
package com.itmayiedu.classFrorm;
import java.lang.reflect.Field;
import java.util.List;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import com.itmayiedu.entity.UserEntity;
public class ClassPathXmlApplicationContext {
private String xmlPath;
public ClassPathXmlApplicationContext(String xmlPath) {
this.xmlPath = xmlPath;
}
public Object getBean(String beanId) throws DocumentException, ClassNotFoundException, NoSuchFieldException,
SecurityException, IllegalArgumentException, IllegalAccessException, InstantiationException {
// spring加载过程,spring ioc实现原理
// 1.获取xml文件,解析
SAXReader saxReader = new SAXReader();
// this.getClass().getClassLoader().getResourceAsStream("xmlPath")获得当前项目路径
Document read = saxReader.read(this.getClass().getClassLoader().getResourceAsStream(xmlPath));
//获取节点对象
Element rootElement = read.getRootElement();
List<Element> elements = rootElement.elements();
Object obj = null;
for (Element sonEle : elements) {
// 2.获取每个bean的配置,获取class地址
String sonBeanId = sonEle.attributeValue("id");
if (!beanId.equals(sonBeanId)) {
continue;
}
String beanClassPath = sonEle.attributeValue("class");
// 3.拿到class地址,反射实例化对象,使用反射api,为私有属性赋值
Class<?> forName = Class.forName(beanClassPath);
obj = forName.newInstance();
//拿到成员属性
List<Element> sonSoneleme = sonEle.elements();
for (Element element : sonSoneleme) {
String name = element.attributeValue("name");
String value = element.attributeValue("value");
// 通过反射技术对私有属性赋值
Field declaredField = forName.getDeclaredField(name);
//允许访问私有成员变量
declaredField.setAccessible(true);
declaredField.set(obj, value);
}
}
return obj;
}
public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, SecurityException,
IllegalArgumentException, IllegalAccessException, InstantiationException, DocumentException {
ClassPathXmlApplicationContext appLication = new ClassPathXmlApplicationContext("user.xml");
Object bean = appLication.getBean("user1");
UserEntity user = (UserEntity) bean;
System.out.println(user.getUserId() + "----" + user.getUserName());
}
}