Java学习路线-31:反射与简单Java类
  TEZNKK3IfmPf 2023年11月12日 32 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> 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;

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 < objKeys.length - 1; i++) {
String objKey = objKeys[i];

Object tempObject = getValue(currentObject, objKey);

// 没有实例化
if (tempObject == null) {
tempObject = getFieldInstance(currentObject, objKey);
setValue(currentObject, objKey, tempObject);
}

currentObject = tempObject;
}

// 最后一个就是属性
String attrKey = objKeys[objKeys.length - 1];
setValue(currentObject, attrKey, convertFieldValue(currentObject, attrKey, val));
}

// 单级关系
else {
setValue(obj, key, convertFieldValue(obj, key, val));
}

} catch (Exception e) {
e.printStackTrace();
}
}
}

/**
* 给对象设置属性值
*/
public static void setValue(Object obj, String key, Object value) {
try {
Field field = obj.getClass().getDeclaredField(key);
String setName = "set" + StringUtil.capitalize(key);
Method method = obj.getClass().getDeclaredMethod(setName, field.getType());
method.setAccessible(true);
method.invoke(obj, value);
} catch (Exception e) {
e.printStackTrace();
}
}

/**
* 获取对象属性值
*/
public static Object getValue(Object obj, String key) {
Object value = null;

try {
String getName = "get" + StringUtil.capitalize(key);
Method getMethod = obj.getClass().getDeclaredMethod(getName);
getMethod.setAccessible(true);
value = getMethod.invoke(obj);

} catch (Exception e) {
e.printStackTrace();
}
return value;
}

/**
* 获取对象属性对应类的实例化对象
*/
public static Object getFieldInstance(Object obj, String key) {
Object fieldObj = null;

try {
Field field = obj.getClass().getDeclaredField(key);
Constructor constructor = field.getType().getConstructor();
constructor.setAccessible(true);
fieldObj = constructor.newInstance();
} catch (Exception e) {
e.printStackTrace();
}
return fieldObj;
}

/**
* 转换字符串为对应类型的值
*/
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;
}
}

public static Object convertFieldValue(Object obj, String key, String value) {
Object val = null;

try {
Field field = obj.getClass().getDeclaredField(key);
val = convertValue(field.getType().getName(), value);
} catch (Exception e) {
e.printStackTrace();
}
return val;
}
}

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'}}}
}
}
【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2023年11月12日 0

暂无评论

推荐阅读
  TEZNKK3IfmPf   19天前   43   0   0 java
  TEZNKK3IfmPf   2024年05月31日   54   0   0 java
TEZNKK3IfmPf