java反射内省机制,Introspector

news/2024/5/19 6:59:25 标签: 内省, 反射, javaweb, 就业班

1.为什么要学内省

开发框架时,经常需要使用java对象的属性来封装程序的数据,每次都使用反射技术完成此类操作过于麻烦,所以sun公司开发了一套API,专门用于操作java对象的属性。

2.反射技术

以后我们能开发框架的时候,经常需要把一些数据封装到对象中去
需求:编写一个工厂方法根据配置文件的内容,工厂方法返回对应的对象,并且对象要有对应的属性值
Person.java

package day01.introspector;

public class Person {
    int id;
    String name;
    public Person(int id, String name) {
        super();
        this.id = id;
        this.name = name;
    }


    public Person() {
        super();
    }


    public int getId() {
        return id;
    }


    public void setId(int id) {
        this.id = id;
    }


    public String getName() {
        return name;
    }


    public void setName(String name) {
        this.name = name;
    }


    @Override
    public String toString() {
        return "Person [id=" + id + ", name=" + name + "]";
    }

}

//obj.txt
day01.introspector.Person
id=110
name=张兵杰
//One.java
package day01.introspector;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;


public class One {


        Person p = (Person)getInstance();
        System.out.println(p);
    }

    //根据配置文件生产对应的对象并且要把对象的属性值封装到对象中
    public static Object getInstance() throws IOException, ClassNotFoundException, NoSuchMethodException, SecurityException, NoSuchFieldException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException{

        BufferedReader bufferedReader = new BufferedReader(new FileReader("obj.txt"));
        String className = bufferedReader.readLine();//读取配置文件获取到完整的类名
        Class clazz = Class.forName(className);
        //通过clazz对象获取到无参的构造方法
        Constructor constructor = clazz.getConstructor(null);
        //创建对象
        Object o = constructor.newInstance(null);
        //读取属性值
        String line = null;
        while((line = bufferedReader.readLine())!=null){
            String[] datas =  line.split("=");
            //通过属性名获取到当前的Field对象
            Field field = clazz.getDeclaredField(datas[0]);
            if(field.getType() == int.class){
                field.set(o, Integer.parseInt(datas[1]));
            }else{
                field.set(o, datas[1]);
            }

        }
        return o;
    }
}

内省======一个变态的反射
内省主要解决的问题:把对象的属性数据封装到对象中去

//Two.java
package day01.introspector;

import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class Two {

    public static void main(String args[]) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, IntrospectionException{

        testProperty1();
    }


    public static void testProperty1() throws IntrospectionException, IllegalAccessException, IllegalArgumentException, InvocationTargetException{
        Person p = new Person();
        //属性描述器    属性名+属性类
        PropertyDescriptor descriptor = new PropertyDescriptor("id",Person.class);
        //获取属性对应的get或者是set方法设置或者获取属性
        Method m = descriptor.getWriteMethod();//获取属性set方法
        //执行该方法设置属性值
        m.invoke(p, 110);
        //Method类代表一个方法,invoke(调用)就是调用Method类代表的方法
        Method readMethod = descriptor.getReadMethod();//获取属性get方法
        System.out.println(p);
        System.out.println(readMethod.invoke(p, null));
    }

    public void getAllProperty() throws IntrospectionException{
        //Introspector 内省
        BeanInfo beanInfo = Introspector.getBeanInfo(Person.class);
        //通过BeanInfo获取所有的属性描述器
        PropertyDescriptor[] descriptors = beanInfo.getPropertyDescriptors();//获取一个类中的所有属性描述器
        for (PropertyDescriptor propertyDescriptor : descriptors) {
            System.out.println(propertyDescriptor.getReadMethod());//get方法
        }
    }

}

BeanUtils:
BeanUtils主要解决的问题:把对象的属性数据封装到对象中

BeanUtils的好处
1.BeanUtils设置属性值时候,如果属性是基本数据类型,BeanUtils会自动帮我们转化数据类型
2.BeanUtils设置属性值时候,底层也是依赖于get,set方法设置以及获取属性值的
3.BeanUtils设置属性值,如果设置的属性是其他的引用 类型数据,比如Date,那么这时候必须要注册一个类型转换器

//Three.java
package day01.introspector;

import java.lang.reflect.InvocationTargetException;
import java.util.Date;
import java.text.SimpleDateFormat;
import javax.xml.crypto.Data;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.beanutils.ConvertUtils;
import org.apache.commons.beanutils.Converter;


public class Three {
    public static void main(String[] args) throws IllegalAccessException, InvocationTargetException {

        //从文件中读取到的数据都是字符串的数据,或者是表单提交的数据获取到的时候也是字符串的数据

        String id = "110";
        String name = "张兵杰";
        Person p = new Person();

        BeanUtils.setProperty(p, "id", id);
        BeanUtils.setProperty(p, "name", name);

        System.out.println(p);

        //日期不会自动转换,需要自己注册一个类型转换器
        String birthday = "2017-7-25";

        ConvertUtils.register(new Converter() {

            @Override
            public Object convert(Class type, Object value) {//type目前所遇到的数据类型。value目前参数的值
                Date date = null;
                try{
                    SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
                    date = dateFormat.parse((String)value);
                }catch(Exception e){
                    e.printStackTrace();
                }
                return date;
            }
        },Date.class);
    }
}

http://www.niftyadmin.cn/n/1492265.html

相关文章

Day01Ajax异步请求编码思路(get请求,验证用户名是否重复)

1.AJAX引言 Ansynchronized JavaScript And XML (异步 javacript 和 xml) 异步请求 2.异步请求与同步请求 同步请求(地址栏 超级链接 表单 location href) 问题:用户的交互体验差 现象:同步请求响应给client是一张新的页面 同…

Day01JQuery介绍及使用

jQuery(Javascript框架) 对javascript代码的封装,javascript功能代码的半成品 jQuery作用 1).简化javascript开发,提高开发效率 2).屏蔽浏览器差异 所需插件 1) jQuery ——-js——-jquery-1.xx.x.js eg&#xff1a…

Day02jQuery选择器

1.基本选择器(重点) ID选择器 $("#ID值")//通过id获取标签对象 元素选择器 $("标签名")//通过标签名获取对象 类选择器 $(".样式类名") 即 $(".class值") //通过样式名获取对象$(#id) $(div).css(background-color,red); $(.class…

Day02jQuery遍历

两种对象转化 将dom对象——转化为——jquery对象 $(dom对象) eg:$(dom)将jquery对象——转化为——dom对象 jquery对象.get(0); eg: jquery.get(0)2.遍历 $(selector) ——jquery对象 ——–size()或者length //元素个数 —————————-eq…

Day03jQuery事件绑定

事件绑定 基于HTML实现的事件绑定 存在耦合 //HTML:<input type"button" value"按钮" id"btn" onclick"test()"/> //Script:function test(){alert("按钮点击了");} 2.基于编程的方式给标签添加事件 注意&#xff1…

jsp下拉框select中options遍历集合

第一种方式&#xff1a;使用options <form:options items"后台传过来的集合" itemLabel"取集合中的某个属性进行显示" itemValue"将遍历的值赋值给某个属性" htmlEscape"设置是否启用默认html字符转换,填true或者false"/> 注意…

Day04jQueryDOM编程相关函数

DOM编程相关函数 注意&#xff1a; 1.1.在事件函数中this&#xff0c;代表触发该事件的事件源—dom对象&#xff08;this&#xff0c;事件标签对象&#xff09; 1.2.内置jquery的事件绑定为静态绑定 1.3 $jq.live(事件名称&#xff0c;绑定的函数)&#xff1b;动态绑定 事件…

Day05jQuery相关插件(日期,放大镜,表单验证)

1.日期插件 1)引入datepicker插件相关的js文件和css文件 直接将文件夹引入,导入WdatePicker.js即可 2)在input增加class’Wdate’,绑定单击事件&#xff0c;函数名WdatePicker() 3)可控参数: { dateFmt 日期显示格式, readOnly 是否只读, input输入框是否可改 isShowWee…