java反射机制

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());
	}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值