zoukankan      html  css  js  c++  java
  • 【Java EE 学习 23】【log4j的使用】【ant的使用】【内省】

    一、ant下载地址:http://ant.apache.org/bindownload.cgi 

    二、log4j下载地址:http://logging.apache.org/log4j/2.x/download.html

    三、内省

      1.什么是内省。

        本质上是反射,具体技术由sun替公司提供,集成到了jdk中,可以根据字段名称(String)和字节码对象得到该字段的一个描述:PropertyDescriptor,并由此得到该字段的get、set方法(Method)。

      将要使用的JavaBean

     1 package com.kdyzm.domain;
     2 
     3 import java.util.Date;
     4 
     5 public class Person {
     6     private String name;
     7     private Integer age;
     8     private Date date;
     9     
    10     public Person(String name, Integer age, Date date) {
    11         this.name = name;
    12         this.age = age;
    13         this.date = date;
    14     }
    15     public String getName() {
    16         return name;
    17     }
    18     public void setName(String name) {
    19         this.name = name;
    20     }
    21     public Integer getAge() {
    22         return age;
    23     }
    24     public void setAge(Integer age) {
    25         this.age = age;
    26     }
    27     public Date getDate() {
    28         return date;
    29     }
    30     public void setDate(Date date) {
    31         this.date = date;
    32     }
    33     public Person() {
    34     }
    35     @Override
    36     public String toString() {
    37         return "Person [name=" + name + ", age=" + age + ", date=" + date + "]";
    38     }
    39 }

      2.核心类:

        (1)PropertyDescriptor类。

            [1]继承关系

                java.lang.Object

                  |--java.beans.FeatureDescriptor

                    |--java.beans.PropertyDescriptor

            [2]构造方法

    构造方法摘要

    PropertyDescriptor(String propertyName, Class<?> beanClass)
              通过调用 getFoo 和 setFoo 存取方法,为符合标准 Java 约定的属性构造一个 PropertyDescriptor。

     

    PropertyDescriptor(String propertyName, Class<?> beanClass, String readMethodName, String writeMethodName)
              此构造方法带有一个简单属性的名称和用于读写属性的方法名称。

     

    PropertyDescriptor(String propertyName, Method readMethod, Method writeMethod)
              此构造方法带有某一简单属性的名称,以及用来读取和写入属性的 Method 对象。

     

             [3]核心方法

     Class<?>

    getPropertyType()
              获得属性的 Class 对象。

     Method

    getReadMethod()
              获得应该用于读取属性值的方法。

     Method

    getWriteMethod()
              获得应该用于写入属性值的方法。

    void

    setReadMethod(Method readMethod)
              
    设置应该用于读取属性值的方法。

     void

    setWriteMethod(Method writeMethod)
              
    设置应该用于写入属性值的方法。

            [4]使用示例。

              获的setName方法并给Person对象赋值。

    public void test1() throws Exception
        {
            Person p=new Person();
            /*
             //这里是通过普通的反射方法来实现的。
                    Method method=p.getClass().getMethod("setName", String.class);
                    method.invoke(p, "张三");
                    System.out.println(p);
            */
            //下面通过使用内省的方式来实现该目的。
            PropertyDescriptor pd=new PropertyDescriptor("name", p.getClass(),"getName","setName");
            Method getName=pd.getReadMethod();
            String name=(String) getName.invoke(p);
            System.out.println(name);
            
            Method setName=pd.getWriteMethod();
            setName.invoke(p, "小强");
            getName=pd.getReadMethod();
            System.out.println(getName.invoke(p));
            /*
             * 输出结果:
             * null
             * 小强
             */
        }

            不能进行类型的自动转换。

    public void test2() throws Exception
        {
            Person p=new Person();
            PropertyDescriptor pd=new PropertyDescriptor("age", p.getClass());
            Method setAge=pd.getWriteMethod();
            setAge.invoke(p, "12");//这里只能传递整数类型的参数,所以一定会报错!
            System.out.println(p);
        }

        (2)BeanInfo接口:专门分析一个JavaBean有多少属性,有哪些属性

          [1]获取该接口实例的方法

            使用Introspector(内省)类(   java.lang.Object   )的静态方法:getBeanInfo(Class<?> beanClass)

                            |--java.bean.Introspector

    static BeanInfo

    getBeanInfo(Class<?> beanClass)
              在 Java Bean 上进行内省,了解其所有属性、公开的方法和事件。

          [2]核心方法:getPropertygetDescriptors方法。 

    PropertyDescriptor[]

    getPropertyDescriptors()
              获得 beans PropertyDescriptor。

          [3]使用方法。

    /*
         * 测试非常不好的类:BeanInfo类,该类并不会将一个Bean对象的所有属性都能解析成功,反而是只要是
         * get或者set方法都会
         * 解析出来。
         * 所以即使是getClass方法该类也会将其作为class属性解析出来。
         * 如果不成对,也会解析出来。
         */
        @Test
        public void test3() throws Exception
        {
            BeanInfo beaninfo=Introspector.getBeanInfo(Person.class);
            PropertyDescriptor pd[]=beaninfo.getPropertyDescriptors();
            for(int i=0;i<pd.length;i++)
            {
                String name=pd[i].getName();
                System.out.println(name);
            }
        }
        

      3.解决类型不匹配的方法:遍历判断

        (1)场景:Person类有age成员变量,为int类型,如果想要传递一个字符串给它,一般情况下会报错:不匹配的参数类型。怎样解决这个问题呢?对set方法能接受的参数类型进行判断,如果是整型参数才传递。

        (2)手动遍历解决。

    /*
         * 怎样实现将字符串传递到setAge方法中
         * 通过使用便利的方式依次对set方法进行遍历
         * 这里的JavaBean必须是Integer类型的,否则不识别。
         * 这么麻烦的工作apache已经将其简化开发出了第三方jar包:BeanUtils.jar
         */
        @Test
        public void test4() throws Exception, IllegalArgumentException, IllegalAccessException, InvocationTargetException
        {
            String name="小强";
            String age="30";
            Person p=new Person();
            Method methods[]=p.getClass().getDeclaredMethods();
            for(Method method:methods)
            {
                String methodname=method.getName();
                //如果是set方法才行进下一步,get方法直接跳过
                if(methodname.startsWith("set"))
                {
                    Class<?> clazz[]=method.getParameterTypes();
                    System.out.println(clazz[0]);
                    if(clazz[0].equals(String.class))
                    {
                        method.invoke(p,name);
                    }
                    else if(clazz[0].equals(Integer.class))
                    {
                        method.invoke(p, Integer.parseInt(age));
                    }
                }
                else
                    continue;
            }
            System.out.println(p);
        }

      4.使用第三方jar包:BeanUtils.jar解决 3  中的问题以及使用第三方jar包的好处。

      BeanUtils.jar下载地址:http://commons.apache.org/proper/commons-beanutils/download_beanutils.cgi

      依赖包:commons-logging.jar包

        (1)BeanUtils.jar是干什么用的?

           是一个处理JavaBean的工具包,内部也是使用内省,但是对内省进行了加强。

        (2)使用该工具包的好处是什么?

           JavaBean中的get方法和set方法不用再成对出现。

           能够自动进行基本数据类型的转换(不是基本数据类型不能自动进行转换)。

        (3)演示使用BeanUtils设置值。

    //演示使用BeanUtils设置值
        @Test
        public void setValueTest() throws Exception, Exception
        {
            Person p=new Person();
            BeanUtils.setProperty(p,"name", "小强");
            BeanUtils.setProperty(p, "age", "45");
            BeanUtils.setProperty(p, "date", new Date());
            System.out.println(p);
        }

        (4)演示使用BeanUtils获取值。

    //演示使用BeanUtils获取值。
        @Test
        public void getValueTest() throws IllegalAccessException, InvocationTargetException, NoSuchMethodException
        {
            Person p=new Person("小强",24,new Date());
            System.out.println(BeanUtils.getProperty(p, "name"));
            System.out.println(BeanUtils.getProperty(p, "age"));
            System.out.println(BeanUtils.getProperty(p, "date"));
        }

        (5)使用BeanUtils一次性将获取到的值封装到javaBean中。

    //使用Benutils一次性填入所有值的方法
        @Test
        public void  setValueAll() throws Exception, InvocationTargetException
        {
            Person p=new Person();
            Map<String,Object>map=new HashMap<String,Object>();
            map.put("name", "小强");
            map.put("age", "24");
            map.put("date", new Date());
            BeanUtils.populate(p, map);            //这句是关键
            System.out.println(p);
            
            //这种方式在分析表单提交的数据并封装成JavaBean的时候使用的非常广泛,因为可以大大节省代码量,注意要使用request对象的getParameterMap()方法。
        }
  • 相关阅读:
    Leetcode788.Rotated Digits旋转数字
    Leetcode788.Rotated Digits旋转数字
    Leetcode796.Rotate String旋转字符串
    Leetcode796.Rotate String旋转字符串
    Leetcode784.Letter Case Permutation字母大小写全排列
    Leetcode784.Letter Case Permutation字母大小写全排列
    Leetcode771.Jewels and Stones宝石与石头
    Leetcode771.Jewels and Stones宝石与石头
    Leetcode724.Find Pivot Index寻找数组的中心索引
    Leetcode724.Find Pivot Index寻找数组的中心索引
  • 原文地址:https://www.cnblogs.com/kuangdaoyizhimei/p/4608381.html
Copyright © 2011-2022 走看看