您当前的位置: 首页 >  Java

彭世瑜

暂无认证

  • 0浏览

    0关注

    2791博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

Java学习路线-31:反射与简单Java类

彭世瑜 发布时间:2019-12-31 22:46:31 ,浏览量:0

第24 章 : 反射与简单Java类 109 传统属性赋值弊端

简单Java类,setter,getter过多,代码重复 通过反射(Object类直接操作属性或方法)实现相同功能类的重复操作的抽象处理

110 属性自动赋值实现思路

类设计的基本机构: 应该由一个专门的ClassInstanceFactory类负责反射处理 接收反射对象与要设置的属性内容,同时可以获取指定类的实例化对象


class ClassInstanceFactory{
    private ClassInstanceFactory(){}

    /**
     * 实例化对象的创建方法,该对象可以根据传入的字符串结构“属性:内容|属性:内容”
     * @param clazz 要进行反射实例化的Class对象,有Class就可以反射实例化对象
     * @param value 要设置给对象的属性内容
     * @return 一个已经配置好属性内容的Java类对象
     */
    public static  T getInstance(Class clazz, String value){
        return null;
    }
}
111 单级属性赋值

完成2项内容: 1、通过反射进行指定类对象的实例化处理 2、进行内容设置 Field Method

必须要有无参构造

处理流程

Class
    -Field 
    -Method 调用setter

Utils
    -BeanUtils   获取类型,属性设置
    -StringUtils 首字母大写

ClassInstanceFactory 对象实例化并设置属性

main 测试类

即使类中的属性再多,也可以实现属性赋值

StringUtil.java

package util;

class StringUtil{
    /**
     * 首字母大写
     */
    public static String capitalize(String str){
        if(str == null || "".equals(str)){
            return str;
        }
        if(str.length() == 1){
            return str.toUpperCase();
        } else{
            return str.substring(0, 1).toUpperCase() + str.substring(1);
        }
    }
}

BeanUtil.java

package util;

import java.lang.reflect.Field;
import java.lang.reflect.Method;

public class BeanUtil {
    /**
     * 对象属性赋值
     * @param obj
     * @param value 数据结构"key:value|key:value"
     */
    public static void setValue(Object obj, String value){
        String[] attrs = value.split("\\|");
        // System.out.println(Arrays.toString(attrs));

        for(String attr : attrs){
            String[] keyValue = attr.split(":");
            String key = keyValue[0];
            String val = keyValue[1];
            
            String setName = "set" + StringUtil.capitalize(key);
            // System.out.println(key + val + setName);

            try{
                Field field = obj.getClass().getDeclaredField(key);
                Method method = obj.getClass().getDeclaredMethod(setName, field.getType());
                method.setAccessible(true);
                method.invoke(obj, val);
            } catch (Exception e){
                e.printStackTrace();
            }
        }
    }
}

Demo.java

import util.BeanUtil;

class Person{
    private String name;

    public Person() {
    }

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

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

/**
 * 属性赋值工厂类
 */
class ClassInstanceFactory{
    private ClassInstanceFactory(){}

    public static  T getInstance(Class clazz, String value) {
        try {
            Object obj = clazz.getDeclaredConstructor().newInstance();
            BeanUtil.setValue(obj, value);
            return (T) obj;
        }catch (Exception e){
            e.printStackTrace();
            return null;
        }
    }
}

class Demo{
    public static void main(String[] args) {
        Person person = ClassInstanceFactory.getInstance(Person.class, "name:Tom");
        System.out.println(person);
        // Person{name='Tom'}
    }
}
112 设置多种数据类型

简单Java类中属性类型 long(Long) int(Integer) double(Double) String

在 BeanUtil.java中添加类型转换方法

package util;

import java.lang.reflect.Field;
import java.lang.reflect.Method;

public class BeanUtil {
    public static void setValue(Object obj, String value){
        String[] attrs = value.split("\\|");        

        for(String attr : attrs){
            String[] keyValue = attr.split(":");
            String key = keyValue[0];
            String val = keyValue[1];

            String setName = "set" + StringUtil.capitalize(key);

            try{
                Field field = obj.getClass().getDeclaredField(key);

                Method method = obj.getClass().getDeclaredMethod(setName, field.getType());
                method.setAccessible(true);
                Object convertVal = convertValue(field.getType().getName(), val);
                method.invoke(obj, convertVal);
            } catch (Exception e){
                e.printStackTrace();
            }
        }
    }

    public static Object convertValue(String type, String value){
        if ("java.lang.String".equals(type)){
            return value;
        } else if("int".equals(type)){
            return Integer.parseInt(value);
        } else{
            return null;
        }
    }
}

Person类添加int类型的age属性,和修改测试Demo类传入参数

import util.BeanUtil;

class Person{
    private String name;
    private int age;

    public void setAge(int age) {
        this.age = age;
    }

    public Person() {
    }

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

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

class Demo{
    public static void main(String[] args) {
        Person person = ClassInstanceFactory.getInstance(Person.class, "name:Tom|age:23");
        System.out.println(person);
        // Person{name='Tom', age=23}
    }
}

如果要做一个完整的产品,需要考虑所有可能的类型

113 级联对象实例化

例如: 一个员工属于一个部门,一个部门属于一个公司

约定使用.作为级联关系 eg:

company.dept.dname:财务部

考虑代码简洁性

114 级联属性赋值

完整代码

StringUtil.java

package util;

class StringUtil{
    /**
     * 首字母大写
     */
    public static String capitalize(String str){
        if(str == null || "".equals(str)){
            return str;
        }
        if(str.length() == 1){
            return str.toUpperCase();
        } else{
            return str.substring(0, 1).toUpperCase() + str.substring(1);
        }
    }
}

BeanUtil.java

package util;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

public class BeanUtil {
    /**
     * 对象属性赋值
     *
     * @param values 数据结构"key:value|key.subKey.subKey:value"
     */
    public static void setValues(Object obj, String values) {
        String[] attrs = values.split("\\|");

        for (String attr : attrs) {
            String[] keyValue = attr.split(":");
            String key = keyValue[0];
            String val = keyValue[1];

            try {
                // 级联关系,通过点. 分隔 eg: company.name
                if (key.contains(".")) {
                    String[] objKeys = key.split("\\.");
                    Object currentObject = obj;

                    // 对象链
                    for (int i = 0; i             
关注
打赏
1665367115
查看更多评论
0.2084s