Java反射机制

目录

 

1 反射机制

1.1反射机制的作用

1.3 反射机制的应用场景

1.4 反射机制获取类有三种方法

1.5 反射创建对象的方式

1.6 禁止使用反射机制初始化

1.7 反射创建api

1.8 样例

1.9 手写spring IOC


1 反射机制

就是正在运行动态获取当前类的所有信息,类可以不用new,使用Java反射机制帮你初始化。类的私有属性也可以用Java的反射机制赋值。需要核心当前类的字节码clas文件。

1.1反射机制的作用

1. 反编译:.class-->.java

2. 通过反射机制访问java对象的属性,方法,构造方法等;

3.提高程序的扩展性,封装一些工具、框架

1.3 反射机制的应用场景

Jdbc 加载驱动,Spring ioc框架

1.4 反射机制获取类有三种方法

  //第一种方式: 

        Classc1 = Class.forName("Employee"); 

        //第二种方式: 

        //java中每个类型都有class 属性

        Classc2 = Employee.class

          

        //第三种方式: 

        //java语言中任何一个java对象都有getClass 方法 

        Employeee = new Employee(); 

        Classc3 = e.getClass(); //c3是运行时类 (e的运行时类是Employee) 

1.5 反射创建对象的方式

  Class<?> forName = Class.forName("...User");

        // 创建此Class 对象所表示的类的一个新实例 调用了User的无参数构造方法.

        Object newInstance = forName.newInstance();

实例化有参构造函数

      Class<?> forName = Class.forName("...User");

        Constructor<?> constructor = forName.getConstructor(String.class, String.class);

        User newInstance = (User) constructor.newInstance("123", "123");

1.6 禁止使用反射机制初始化

将构造函数为私有化。

1.7 反射创建api

方法名称

作用

getDeclaredMethods []

获取该类的所有方法

getReturnType()

获取该类的返回值

getParameterTypes()

获取传入参数

getDeclaredFields()

获取该类的所有字段

setAccessible

允许访问私有成员

1.8 样例

public class PrivateAttribute {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException, InstantiationException {
        //1、使用Java的反射机子 获取类的所有属性 方法 并且为私有属性赋值
        Class<?> aClass = Class.forName("com.ilose.reflect.User");
        //2、获取当前类的所有属性
        Field[] fields=aClass.getDeclaredFields();
        for (Field field :fields) {
            System.out.println(field.getName());
        }
        //3、获取当前类的所有方法
        Method[] methods=aClass.getDeclaredMethods();
        for (Method method:methods) {
            System.out.println(method.getName());
        }
        //4、使用Java的反射机制给私有属性赋值
        Object o = aClass.newInstance();
        Field id = aClass.getDeclaredField("id");
        //允许反射操作私有属性
        id.setAccessible(true);
        id.set(o,"20");
        Field name = aClass.getDeclaredField("name");
        name.setAccessible(true);
        name.set(o,"losemyfuture");
        User user= (User) o;
        System.out.println(user.toString());
    }
}

1.9 手写spring IOC

spring IOC就是把么一个bean(实体类)与bean(实体类)之间的关系都交给第三方容器管理

1.利用传入的参数获取xml文件的流,并且利用dom4j解析成Document对象

2.对于Document对象获取根元素对象<beans>后对下面的<bean>标签进行遍历,判断是否有符合的id.

3.如果找到对应的id,相当于找到了一个Element元素,开始创建对象,先获取class属性,根据属性值利用反射建立对象.

4.遍历<bean>标签下的property标签,并对属性赋值.注意,需要单独处理int,float类型的属性.因为在xml配置中这些属性都是以字符串的形式来配置的,因此需要额外处理.

5.如果属性property标签有ref属性,说明某个属性的值是一个对象,那么根据id(ref属性的值)去获取ref对应的对象,再给属性赋值.

6.返回建立的对象,如果没有对应的id,或者<beans>下没有子标签都会返回null

添加依赖:
<dependencies>
		<!-- https://mvnrepository.com/artifact/org.apache.commons/commons-lang3 -->
		<dependency>
			<groupId>org.apache.commons</groupId>
			<artifactId>commons-lang3</artifactId>
			<version>3.4</version>
		</dependency>
		<dependency>
			<groupId>org.dom4j</groupId>
			<artifactId>dom4j</artifactId>
			<version>2.0.0</version>
		</dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.16.20</version>
        </dependency>
	</dependencies>
Java代码: 
User.java
@Data
public class User{

    public User() {
        System.out.println("无参构造");
    }

    private String id;
    private String name;

    @Override
    public String toString() {
        return "User{" +
                "id='" + id + '\'' +
                ", name='" + name + '\'' +
                '}';
    }
}


ClassPathXmlApplicationContext.java 
public class ClassPathXmlApplicationContext {
    private String PATH;
    private static String ID;
    private static String CLASS;
    private static String NAME;
    private static String VALUE;
    public void init(){
        ID="id";
        CLASS="class";
        NAME="name";
        VALUE="value";
    }
    public ClassPathXmlApplicationContext(String path){
        this.PATH=path;
        init();
    }

    public Object getBean(String beanId) throws DocumentException, ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchFieldException {
        //1、解析xml
        if(StringUtils.isEmpty(beanId)){
            return null;
        }
        Object o=null;
        SAXReader saxReader=new SAXReader();
        Document read=saxReader.read(this.getClass().getClassLoader().getResource(PATH));
        Element rootElement=read.getRootElement();
        List<Element> elements = rootElement.elements();
        for (Element element :elements) {
            String id = element.attributeValue(ID);
            if(!beanId.equals(id)){
                //结束本次循环
                continue;
            }
            //2、使用beanid查找xml结点,获取class节点属性
            //获取配置文件中的bean
            String attClass = element.attributeValue(CLASS);
            //3、使用Java反射机制初始化类
            Class<?> aClass = Class.forName(attClass);
            o = aClass.newInstance();
            //获取属性值
            List<Element> elements1 = element.elements();
            for (Element sonEle:elements1) {
                //4、使用Java的反射机制私有化属性赋值
                String attrField = sonEle.attributeValue(NAME);
                String attrFieldValue = sonEle.attributeValue(VALUE);
                Field declaredField = aClass.getDeclaredField(attrField);
                declaredField.setAccessible(true);
                declaredField.set(o,attrFieldValue);
            }
        }
        return o;
    }

    public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, InstantiationException, DocumentException, IllegalAccessException {
        ClassPathXmlApplicationContext classPathXmlApplicationContext=new ClassPathXmlApplicationContext("applicationContext.xml");
        User user1 = (User) classPathXmlApplicationContext.getBean("user1");
        System.out.println(user1.toString());
    }
}
 
applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
	xmlns:tx="http://www.springframework.org/schema/tx" xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="    
     http://www.springframework.org/schema/beans     
     http://www.springframework.org/schema/beans/spring-beans-3.0.xsd    
     http://www.springframework.org/schema/tx     
     http://www.springframework.org/schema/tx/spring-tx-3.0.xsd    
     http://www.springframework.org/schema/aop     
     http://www.springframework.org/schema/aop/spring-aop-3.0.xsd    
     http://www.springframework.org/schema/context    
     http://www.springframework.org/schema/context/spring-context-3.0.xsd">

	<bean id="user1" class="com.ilose.reflect.User">
		<property name="id" value="0002"></property>
		<property name="name" value="张三"></property>
	</bean>
	<bean id="user2" class="com.ilose.reflect.User">
		<property name="id" value="0003"></property>
		<property name="name" value="蚂蚁课堂"></property>
	</bean>


</beans>   




输出:
无参构造
User{id='0002', name='张三'}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Java反射机制是指在运行时动态地获取一个类的信息,并可以操作类的属性、方法和构造器等。Java反射机制可以使程序员在运行时动态地调用类的方法和属性,扩展类的功能,并可以实现注解、工厂模式以及框架开发等。 Java反射机制的原理如下:首先,Java编译器将Java源代码编译为字节码文件,字节码文件中包含着类的信息,这些信息包括类的名称、方法、属性和构造器等等。接着,Java虚拟机将字节码文件加载到内存中,然后通过类加载器将类加载到内存中形成一个类对象,这个类对象可以操作字节码文件中的信息。 使用Java反射机制的过程如下:首先获取类对象,通过类对象来获取类的构造器、属性、方法等信息,然后调用构造器来创建对象,通过属性获取和设置类的成员属性,通过方法调用类的方法等。 Java反射机制的优点是可以在运行时动态地得到类的信息,使得程序员在程序运行时能够对类进行更加灵活的操作,并可以使得程序更加通用化,同时也存在着一定的性能问题,因为Java反射机制需要Java虚拟机进行一定的额外处理,所以在程序运行时需要进行额外的时间和资源消耗。 总之,Java反射机制Java语言的一项重要特性,在Java开发中广泛应用,在代码编写、框架开发以及API开发中具有重要作用。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值