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

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

第24 章 : 反射与简单Java类

109 传统属性赋值弊端

简单Java类,setter,getter过多,代码重复

通过反射(Object类直接操作属性或方法)实现相同功能类的重复操作的抽象处理


110 属性自动赋值实现思路

类设计的基本机构:

应该由一个专门的ClassInstanceFactory类负责反射处理

接收反射对象与要设置的属性内容,同时可以获取指定类的实例化对象

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

111 单级属性赋值

完成2项内容:

1、通过反射进行指定类对象的实例化处理

2、进行内容设置 Field Method


必须要有无参构造


处理流程


Class<?>
    -Field 
    -Method 调用setter
Utils
    -BeanUtils   获取类型,属性设置
    -StringUtils 首字母大写
ClassInstanceFactory<T> 对象实例化并设置属性
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> T getInstance(Class<T> 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;
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);
        }
    }
}

Demo.java


import util.BeanUtil;
class Person {
    private String name;
    private int age;
    private Company company;
    public Person() {
    }
    public void setAge(int age) {
        this.age = age;
    }
    public Company getCompany() {
        return company;
    }
    public void setName(String name) {
        this.name = name;
    }
    public void setCompany(Company company) {
        this.company = company;
    }
    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", company=" + company +
                '}';
    }
}
class Dept {
    private String name;
    public Dept() {
    }
    public void setName(String name) {
        this.name = name;
    }
    @Override
    public String toString() {
        return "Dept{" +
                "name='" + name + '\'' +
                '}';
    }
}
class Company {
    private String name;
    private Dept dept;
    public Company() {
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getName() {
        return name;
    }
    public void setDept(Dept dept) {
        this.dept = dept;
    }
    public Dept getDept() {
        return dept;
    }
    @Override
    public String toString() {
        return "Company{" +
                "name='" + name + '\'' +
                ", dept=" + dept +
                '}';
    }
}
/**
 * 属性赋值工厂类
 */
class ClassInstanceFactory {
    private ClassInstanceFactory() {
    }
    public static <T> T getInstance(Class<T> clazz, String values) {
        try {
            Object obj = clazz.getDeclaredConstructor().newInstance();
            BeanUtil.setValues(obj, values);
            return (T) obj;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }
}
class Demo {
    public static void main(String[] args) {
        String values = "name:Tom|age:23|company.name:Tech|company.dept.name:law";
        Person person = ClassInstanceFactory.getInstance(Person.class, values);
        System.out.println(person);
        // Person{name='Tom', age=23, company=Company{name='Tech', dept=Dept{name='law'}}}
    }
}

相关文章
|
5月前
|
IDE Java 关系型数据库
Java 初学者学习路线(含代码示例)
本教程为Java初学者设计,涵盖基础语法、面向对象、集合、异常处理、文件操作、多线程、JDBC、Servlet及MyBatis等内容,每阶段配核心代码示例,强调动手实践,助你循序渐进掌握Java编程。
705 3
|
5月前
|
SQL Java 数据库
2025 年 Java 从零基础小白到编程高手的详细学习路线攻略
2025年Java学习路线涵盖基础语法、面向对象、数据库、JavaWeb、Spring全家桶、分布式、云原生与高并发技术,结合实战项目与源码分析,助力零基础学员系统掌握Java开发技能,从入门到精通,全面提升竞争力,顺利进阶编程高手。
1021 1
|
4月前
|
存储 Java 索引
用Java语言实现一个自定义的ArrayList类
自定义MyArrayList类模拟Java ArrayList核心功能,支持泛型、动态扩容(1.5倍)、增删改查及越界检查,底层用Object数组实现,适合学习动态数组原理。
200 4
|
4月前
|
IDE JavaScript Java
在Java 11中,如何处理被弃用的类或接口?
在Java 11中,如何处理被弃用的类或接口?
272 5
|
4月前
|
编解码 Java 开发者
Java String类的关键方法总结
以上总结了Java `String` 类最常见和重要功能性方法。每种操作都对应着日常编程任务,并且理解每种操作如何影响及处理 `Strings` 对于任何使用 Java 的开发者来说都至关重要。
354 5
|
4月前
|
JSON 网络协议 安全
【Java】(10)进程与线程的关系、Tread类;讲解基本线程安全、网络编程内容;JSON序列化与反序列化
几乎所有的操作系统都支持进程的概念,进程是处于运行过程中的程序,并且具有一定的独立功能,进程是系统进行资源分配和调度的一个独立单位一般而言,进程包含如下三个特征。独立性动态性并发性。
260 1
|
4月前
|
Java Go 开发工具
【Java】(8)正则表达式的使用与常用类分享
正则表达式定义了字符串的模式。正则表达式并不仅限于某一种语言,但是在每种语言中有细微的差别。
326 1
|
4月前
|
存储 Java 程序员
【Java】(6)全方面带你了解Java里的日期与时间内容,介绍 Calendar、GregorianCalendar、Date类
java.util 包提供了 Date 类来封装当前的日期和时间。Date 类提供两个构造函数来实例化 Date 对象。第一个构造函数使用当前日期和时间来初始化对象。Date( )第二个构造函数接收一个参数,该参数是从1970年1月1日起的毫秒数。
246 1
|
4月前
|
JSON 网络协议 安全
【Java基础】(1)进程与线程的关系、Tread类;讲解基本线程安全、网络编程内容;JSON序列化与反序列化
几乎所有的操作系统都支持进程的概念,进程是处于运行过程中的程序,并且具有一定的独立功能,进程是系统进行资源分配和调度的一个独立单位一般而言,进程包含如下三个特征。独立性动态性并发性。
269 1
|
存储 SQL Java
Java反射读取注解信息
Java反射读取注解信息
155 0