第02天 java基础加强

今日内容介绍

u Properties的基本操作

u 反射综合案例

u BeanUtils概述及使用

第1章   Properties的基本操作

1.1  Properties的概述及基本使用

1.1.1 Properties的概述

Properties 类表示了一个持久的属性集。Properties 可保存在流中或从流中加载。属性列表中每个键及其对应值都是一个字符串。

特点:

1、Map接口的子类,map中的方法都可以用。

2、该集合没有泛型。键值都是字符串。

3、它是一个可以持久化的属性集。键值可以存储到集合中,也可以存储到持久化的设备(硬盘、U盘、光盘)上。键值的来源也可以是持久化的设备。

4、有和流技术相结合的方法。

1.2  常用方法

l  public Object setProperty(String key, String value)调用 Map 的方法 put。

l  public Set<String> stringPropertyNames()返回此属性列表中的键集,

l  public String getProperty(String key)用指定的键在此属性列表中搜索属性

 

1.2.1 案例代码一

public class PropsDemo_01 {

    @Test

    public void demo01(){

       

        //Properties对象 特殊Map<String,String>

       

        //1 创建对象

        Properties props = new Properties();

       

        //2 设置数据

        //props.put(key, value)

        props.setProperty("k01", "v01");

        props.setProperty("k02", "v02");

        props.setProperty("k03", "v03");

       

        //3 获得指定名称的数据

        String prop = props.getProperty("k02");

        System.out.println(prop);

       

        //4获得所有名称,并遍历获得所有的数据

        System.out.println("--------------");

        Set<String> names = props.stringPropertyNames();

        for(String name : names){

            String value = props.getProperty(name);

            System.out.println(name + " : " + value);

        }

    }

}

 

1.3  Properties加载文件写入文件

1.3.1 将集合中内容存储到文件

l  store(OutputStream,commonts)

l  stroe(Writer,comments);

把集合中的数据,保存到指定的流所对应的文件中,参数commonts代表对描述信息

1.3.2 案例代码二

    @Test

    public void demo01() throws Exception{

       

        //将内容写入到文件

        // * Properties 对应一种特殊文件:*.properties

        // * 一行表示一个键值对,格式:k=v

       

        //1 创建对象

        Properties props = new Properties();

       

        //2 设置数据

        //props.put(key, value)

        props.setProperty("k01", "v01黑马");

        props.setProperty("k02", "v02程序员");

        props.setProperty("k03", "v03");

       

        //3 将props写入到硬盘

        Writer writer = new OutputStreamWriter(new FileOutputStream("1.properties"),"UTF-8");

        props.store(writer, "描述");

        writer.close();

       

    }

 

1.3.3 读取文件中的数据,并保存到集合

l  load(InputStream) 

l  load(Reader) 

把指定流所对应的文件中的数据,读取出来,保存到Propertie集合中

1.3.4 案例代码三

@Test

    public void demo02() throws Exception{

        //从properties文件中获得数据

       

        //1 获得资源流

        Reader reader = new InputStreamReader(new FileInputStream("1.properties"),"UTF-8");

       

        //2 通过Properties对象加载流

        Properties props = new Properties();

        props.load(reader);

       

        //3 遍历所有

        for(String name : props.stringPropertyNames()){

            String value = props.getProperty(name);

            System.out.println(name + " @ " +  value);

        }  

    }

第2章   反射综合案例

2.1  需求分析

将javaBean的数据以配置文件的方式写进properties中,读取配置文件写进BeanConfig进行封装,在测试类中去读BeanConfig中封装的数据,并以反射的方式根据读取的数据创建对象,给对象的属性设置值。
反射的好处:我们不用将数据写死到java代码中,可以使用配置文件将数据写入配置文件中。提高了代码的灵活性。

 

2.2      案例代码四

2.2.1 首先编写JavaBean

User

package com.itheima_02_demo.bean;

 

public class User {

   

    private String uid;

    private String username;

    private String password;

   

    public String getUid() {

        return uid;

    }

    public void setUid(String uid) {

        this.uid = uid;

    }

    public String getUsername() {

        return username;

    }

    public void setUsername(String username) {

        this.username = username;

    }

    public String getPassword() {

        return password;

    }

    public void setPassword(String password) {

        this.password = password;

    }

    @Override

    public String toString() {

        return "User [uid=" + uid + ", username=" + username + ", password=" + password + "]";

    }

}

 

 

 

Book

package com.itheima_02_demo.bean;

 

public class Book {

   

    private String bid;

    private String title;

    private String price;

   

    public String getBid() {

        return bid;

    }

    public void setBid(String bid) {

        this.bid = bid;

    }

    public String getTitle() {

        return title;

    }

    public void setTitle(String title) {

        this.title = title;

    }

    public String getPrice() {

        return price;

    }

    public void setPrice(String price) {

        this.price = price;

    }

    @Override

    public String toString() {

        return "Book [bid=" + bid + ", title=" + title + ", price=" + price + "]";

    }

}

 

2.2.2 创建配置文件

bean.properties

id=id001

className=com.itheima.domain.User

 

data.properties

uid=u001

userName=jack

password=1234

2.2.3 编写BeanConfig类

目的: 封装2个Properties文件中的内容

import java.util.Properties;

 

public class BeanConfig {

 

    private String id;

    private String className;

   

    private Properties props = new Properties();

 

    public String getId() {

        return id;

    }

 

    public void setId(String id) {

        this.id = id;

    }

 

    public String getClassName() {

        return className;

    }

 

    public void setClassName(String className) {

        this.className = className;

    }

 

    public Properties getProps() {

        return props;

    }

 

    public void setProps(Properties props) {

        this.props = props;

    }

 

    @Override

    public String toString() {

        return "BeanConfig [id=" + id + ", className=" + className + ", props=" + props + "]";

    }

}

 

2.2.4 解析Properties

public class Demo_02 {

   

    @Test

    public void demo01() throws Exception{

        //读取配置文件,获得具体信息

        BeanConfig beanConfig = new BeanConfig();

        //1 读取bean.properties文件,设置id和className属性

        Properties beanProps = new Properties();

        beanProps.load(new InputStreamReader(new FileInputStream("bean.properties"), "UTF-8"));

        beanConfig.setId(beanProps.getProperty("id"));

        beanConfig.setClassName(beanProps.getProperty("className"));

        //2读取data.properties文件,设置getProps().setProperty()

        Properties dataProps = new Properties();

        dataProps.load(new InputStreamReader(new FileInputStream("data.properties"), "UTF-8"));

        for(String name : dataProps.stringPropertyNames()){

            String value = dataProps.getProperty(name);

            beanConfig.getProps().setProperty(name, value);

        }

        System.out.println(beanConfig);

    }

}

 

 

2.2.5 使用BeanConfig数据

import java.lang.reflect.Method;

 

import org.junit.Test;

 

import com.itheima.domain.BeanConfig;

 

public class Demo_03 {

   

    @Test

    public void demo01() throws Exception{

        //模拟数据

        BeanConfig beanConfig = new BeanConfig();

        beanConfig.setId("id001");

        beanConfig.setClassName("com.itheima.domain.User");

       

        beanConfig.getProps().setProperty("uid", "u001");

        beanConfig.getProps().setProperty("userName", "jack");

        beanConfig.getProps().setProperty("password", "1234");

       

        //使用数据创建JavaBean实例,并为JavaBean封装具体数据

        //1 创建实例,使用反射

        Class clazz = Class.forName(beanConfig.getClassName());

        Object obj = clazz.newInstance();

       

        //2 调用JavaBean的setter方法进行数据封装

        for(String name : beanConfig.getProps().stringPropertyNames()){

            String value = beanConfig.getProps().getProperty(name);

            // 获得方法名称 : set前缀 + 大写首字母 + 其他内容

            String methodName = "set" + name.substring(0, 1).toUpperCase() + name.substring(1);

            // 调用setter方法

            Method method = clazz.getMethod(methodName, String.class);

            method.invoke(obj, value);

        }

        System.out.println(obj);

    }

}

 

2.2.6 综合案例整合

import java.io.FileInputStream;

import java.io.InputStreamReader;

import java.lang.reflect.Method;

import java.util.Properties;

import org.junit.Test;

import com.itheima.domain.BeanConfig;

 

public class Demo_04 {

    //获得配置文件具体数据

    public BeanConfig getBean() throws Exception{

        //读取配置文件,获得具体信息

        BeanConfig beanConfig = new BeanConfig();

        //1 读取bean.properties文件,设置id和className属性

        Properties beanProps = new Properties();

        beanProps.load(new InputStreamReader(new FileInputStream("bean.properties"), "UTF-8"));

        beanConfig.setId(beanProps.getProperty("id"));

        beanConfig.setClassName(beanProps.getProperty("className"));

        //2读取data.properties文件,设置getProps().setProperty()

        Properties dataProps = new Properties();

        dataProps.load(new InputStreamReader(new FileInputStream("data.properties"), "UTF-8"));

        for(String name : dataProps.stringPropertyNames()){

            String value = dataProps.getProperty(name);

            beanConfig.getProps().setProperty(name, value);

        }

        return beanConfig;

    }

   

    @Test

    public void demo01() throws Exception{

        //真实具体数据

        BeanConfig beanConfig = getBean();

        //使用数据创建JavaBean实例,并为JavaBean封装具体数据

        //1 创建实例,使用反射

        Class clazz = Class.forName(beanConfig.getClassName());

        Object obj = clazz.newInstance();

       

        //2 调用JavaBean的setter方法进行数据封装

        for(String name : beanConfig.getProps().stringPropertyNames()){

            String value = beanConfig.getProps().getProperty(name);

            // 获得方法名称 : set前缀 + 大写首字母 + 其他内容

            String methodName = "set" + name.substring(0, 1).toUpperCase() + name.substring(1);

            // 调用setter方法

            Method method = clazz.getMethod(methodName, String.class);

            method.invoke(obj, value);

        }

        System.out.println(obj);

    }

}

 

第3章   BeanUtils的概述及使用

 

3.1  BeanUtils的概述和简单使用

3.1.1 BeanUtils概述

BeanUtils 是 Apache commons组件的成员之一,主要用于简化JavaBean封装数据的操作。它可以给JavaBean封装一个字符串数据,也可以将一个表单提交的所有数据封装到JavaBean中。

3.1.2 需要的jar包

 

BeanUtils工具常用工具类有两个:BeanUtils、ConvertUtils[WU1] 。BeanUtils用于封装数据,ConvertUtils用于处理类型转换

常用方法:

setProperty(Object obj,String name,Object value)

设置属性值,如果指定属性不存在,不抛异常

getProperty(Object obj,String name)

获得属性值,如果指定属性不存在,抛方法找不到异常

 

3.1.3 案例代码五

使用BeanUtils把数据封装进User对象

import org.apache.commons.beanutils.BeanUtils;

import org.junit.Test;

 

import com.itheima_01_bean.User;

 

public class BeanUtilsDemo_01 {

   

    @Test

    public void demo01(){

        //模拟向User对象封装数据

        User user = new User();

        user.setUid("u001");

        user.setUserName("jack");

        user.setPassword("1234");

       

        System.out.println(user);

    }

   

    @Test

    public void demo02() throws Exception{

        /* 实际开发中,需要封装到JavaBean中的数据存放在配置文件

         * * 内容:uid=u001 、userName=jack

         *

         * JavaBean中两个概念:字段Field、属性Property

         * * 字段:就是成员变量。

         *      例如:private String userName;

         *      字段名称:userName

         * * 属性:通过getter或setter方法推敲获得

         *      获得方式:省略set或get前缀,首字母小写

         *      例如:getUserName  --> UserName  --> userName

         * * 注意:一般情况下,字段名称和属性名称一致的。

         *

         * * 特殊情况

         *      private String description;     //字段名:description

         *      public String getDesc(){        //属性名:desc

         *          return description;

         *      }

         */

       

       

        //1 BeanUtils工具类,提供setProperty 给指定属性设置内容  和 getProperty获得指定属性的值

        User user = new User();

        System.out.println("封装前:" + user);

        // * 封装数据来自配置文件 , 底层其实  user.setUid("u002")

        BeanUtils.setProperty(user, "uid", "u002");

        BeanUtils.setProperty(user, "userName", "rose");

       

        System.out.println("封装后:" + user);

       

        //2 获得属性值

        String userName = BeanUtils.getProperty(user, "userName");

        System.out.println(userName);

       

    }

   

   

 

}

 

User

import java.util.Arrays;

 

public class User {

 

    private String uid;

    private String userName;

    private String password;

    private String[] hobbies;       //爱好

    private int age;

   

   

    public String getUid() {

        return uid;

    }

    public void setUid(String uid) {

        this.uid = uid;

    }

    public String getUserName() {

        return userName;

    }

    public void setUserName(String userName) {

        this.userName = userName;

    }

    public String getPassword() {

        return password;

    }

    public void setPassword(String password) {

        this.password = password;

    }

   

    public String[] getHobbies() {

        return hobbies;

    }

    public void setHobbies(String[] hobbies) {

        this.hobbies = hobbies;

    }

   

    public int getAge() {

        return age;

    }

    public void setAge(int age) {

        this.age = age;

    }

    @Override

    public String toString() {

        return "User [uid=" + uid + ", userName=" + userName + ", password=" + password + ", hobbies="

                + Arrays.toString(hobbies) + ", age=" + age + "]";

    }

}

3.2  BeanUtils的populate方法的使用

3.2.1 方法说明

BeanUtils对象    populate(Object bean, Map<String,String[]> properties)    将Map数据封装到指定Javabean中,一般用于将表单的所有数据封装到javabean。

3.2.2 案例代码六

使用populate方法将数据封装到User对象中

import java.util.HashMap;

import java.util.Map;

 

import org.apache.commons.beanutils.BeanUtils;

import org.junit.Test;

 

import com.itheima_01_bean.User;

 

public class BeanUtilsDemo_02 {

    @Test

    public void demo01() throws Exception{

        //1.模拟数据,创建一个Map,填充需要的数据

        Map<String,String[]> map = new HashMap<String,String[]>();

        map.put("uid", new String[]{"u001"});

        map.put("userName", new String[]{"jack","rose"});

        map.put("password", new String[]{"1234"});

       

       

        //2 将使用populate进行填充

        User user = new User();

        BeanUtils.populate(user, map);

       

        System.out.println(user);

       

       

    }

   

    @Test

    public void demo02() throws Exception{

        //1.模拟数据,创建一个Map,填充需要的数据

        Map<String,String[]> map = new HashMap<String,String[]>();

        map.put("uid", new String[]{"u001"});

        map.put("userName", new String[]{"jack","rose"});

        map.put("password", new String[]{"1234"});

        map.put("hobbies", new String[]{"敲代码","早上敲代码","晚上敲代码"});

        map.put("age", new String[]{"123"});

       

       

        //2 将使用populate进行填充

        // * 可以向指定的属性,填充一组数据。需要类型必须是[]

        // * 如果属性不是数组,将使用map.value表示数组中的第一个。

        // * BeanUtils支持类型:基本类型 和 基本类型对应的包装类 。自动将字符串转换基本类型

        User user = new User();

        BeanUtils.populate(user, map);

       

        System.out.println(user);

    }

}

 

 

3.3      BeanUtils自定义工具类

3.3.1 自定义工具类的基本使用

3.3.2 案例代码七

1.定义静态的一个工具类,定义方法populate,参数为Object 和 Map<String,String[]>

返回值类型为void

import java.util.Map;

 

import org.apache.commons.beanutils.BeanUtils;

 

public class MyBeanUtils {

   

    /**

     * 自动填充

     * @param bean

     * @param properties

     */

    public static void populate(Object bean , Map<String,String[]> properties ){

        try {

            BeanUtils.populate(bean, properties);

        } catch (Exception e) {

            //将编译时异常,转换成运行时,方便调用者(使用者不需要再次处理异常)

            throw new RuntimeException(e);

        }

    }

}

 

测试代码

    @Test

    public void demo01() {

        //1.模拟数据,创建一个Map,填充需要的数据

        Map<String,String[]> map = new HashMap<String,String[]>();

        map.put("uid", new String[]{"u001"});

        map.put("userName", new String[]{"jack","rose"});

        map.put("password", new String[]{"1234"});

       

       

        //2 将使用populate进行填充

        User user = new User();

        MyBeanUtils.populate(user, map);

       

        System.out.println(user);

       

    }

 

2.定义静态的一个工具类,定义方法populate,参数为Class 和 Map<String,String[]>

返回值类型为Object

/**

     * 自动填充

     * @param bean

     * @param properties

     */

    public static Object populate(Class beanClass , Map<String,String[]> properties ){

        try {

            //1 使用反射进行实例化

            Object bean = beanClass.newInstance();

            //2 填充数据

            BeanUtils.populate(bean, properties);

            //3 将填充好JavaBean实例返回

            return bean;

        } catch (Exception e) {

            //将编译时异常,转换成运行时,方便调用者(使用者不需要再次处理异常)

            throw new RuntimeException(e);

        }

    }

 

}

 

 

3.3.3 带泛型的自定义工具类

3.3.4 代码案例八

1.定义静态的一个工具类,定义方法populate,参数为Class<T>和 Map<String,String[]>

返回值类型为T

public class MyBeanUtils3 {

   

    /**

     * 自动填充

     * @param bean

     * @param properties

     *

     * Class<T> 此处的T就是一个变量,在运行时,接收具体类型。例如:User

     * 变量必须先定义在使用

     *      泛型变量的定义方式:修饰符 <变量名> 返回值

     */

    public static <T> T populate(Class<T> beanClass , Map<String,String[]> properties ){

        try {

            //1 使用反射进行实例化

            T bean = beanClass.newInstance();

            //2 填充数据

            BeanUtils.populate(bean, properties);

            //3 将填充好JavaBean实例返回

            return bean;

        } catch (Exception e) {

            //将编译时异常,转换成运行时,方便调用者(使用者不需要再次处理异常)

            throw new RuntimeException(e);

        }

    }

}

 

 

2.测试类

 

@Test

public void demo03() throws Exception{

    //工具类使用

    Map<String,String[]> properties = new HashMap<String,String[]>();

    properties.put("id", new String[]{"18"});

    properties.put("username", new String[]{"jack"});

    properties.put("pwd", new String[]{"1234"});

   

    User obj = MyBeanUtils.populate2(User.class, properties);

   

    System.out.println(obj);

   

    /* 结果:

     * User [id=18, username=jack, pwd=1234]

     */

}

 

 


 [WU1]

已经删除