# dynamic **Repository Path**: feizns/dynamic ## Basic Information - **Project Name**: dynamic - **Description**: 一个动态操作实体属性及数据类型转换的工具组件 - **Primary Language**: Java - **License**: Apache-2.0 - **Default Branch**: master - **Homepage**: https://gitee.com/feizns/dynamic - **GVP Project**: No ## Statistics - **Stars**: 11 - **Forks**: 3 - **Created**: 2019-06-09 - **Last Updated**: 2025-09-28 ## Categories & Tags **Categories**: utils **Tags**: None ## README # dynamic #### 介绍 一个动态操作实体属性及数据类型转换的工具组件 #### 安装教程 ``` com.gitee.feizns dynamic 6.7.4-RELEASE ``` #### 介绍 在java中实体类几乎在任何地方都会出现。 而实体类之间及各种数据类型之间的相互转换应用场景频繁 为此个人开发一个动态操作实体属性及数据类型转换的工具组件 #### `Convertible` 接口 通过声明接口 `Convertible` 来获得对应的实体类转换的操作。 另外 `Convertible` 还继承了 `PropertiesIterable` 使用它可以让你遍历实体类中的属性. ```java public class ConvertibleDemo { public static void main(String[] args) { User user = new User(A.firstName, "lastName"); User user1 = user.to(new User()); System.out.println(user1); //ConvertibleDemo.User(firstName=firstName, lastName=lastName) //注解定义映射规则 Admin to1 = user.to(Admin.class); System.out.println(to1); //ConvertibleDemo.Admin(newLastName=lastName, first_name=firstName, last_name=lastName) //自定义映射规则 Admin to2 = user.copyPropertiesTo(Admin.class, StringUtils::toSnakeCase); System.out.println(to2); //ConvertibleDemo.Admin(newLastName=null, first_name=firstName, last_name=lastName) } enum A { firstName(1); private int val; A(int val) { this.val = val; } } @Data @AllArgsConstructor @NoArgsConstructor public static class User implements Convertible { private A firstName; private String lastName; } @Data public static class Admin { @TryGet("lastName") private String newLastName; @TryGet("firstName") private String first_name; @TryGet("lastName") private String last_name; } } ``` 遍历属性 #### `PropertiesIterable` 接口 ```java public class EachPropDemo { public static void main(String[] args) { Admin admin = new Admin("firstName", "lastName"); for (Prop prop : admin) { print(prop); } //属性名=firstName 是否可读=false 是否可写=true 值=null //属性名=lastName 是否可读=true 是否可写=true 值=lastName //属性名=class 是否可读=true 是否可写=false 值=class prop.EachPropDemo$Admin // java 8 admin.forEach(EachPropDemo::print); } private static void print(Prop prop) { System.out.printf("属性名=%-10s 是否可读=%-10s 是否可写=%-10s 值=%-10s\n", prop.name(), prop.isReadable(), prop.isWritable(), prop.val()); } @Setter @AllArgsConstructor public static class Admin implements PropertiesIterable { private String firstName; @Getter private String lastName; } } ``` 更多属性的操作,请见 `Prop` 接口 如果你不想通过声明接口的方式来实现对应功能 可以尝试使用 `PropUtils` 来实现, 其实它们是一样的 #### Converts 转换类 1. 常用类型 ```java public class ConvertDemo { public static void main(String[] args) { //数字 byte q = Converts.to(1.1f, byte.class); short w = Converts.to(1.1, short.class); int e = Converts.to(w, int.class); long r = Converts.to(e, long.class); float t = Converts.to(r, int.class); double y = Converts.to(t, double.class); BigDecimal u = Converts.to(y, BigDecimal.class); BigInteger i = Converts.to(u, BigInteger.class); //日期 String date = "2022-12-01 12:12:12.123"; //Thu Dec 01 12:12:12 CST 2022 System.out.println(Converts.to(date, Date.class)); //2022-12-01 System.out.println(Converts.to(date, java.sql.Date.class)); //12:12:12 System.out.println(Converts.to(date, Time.class)); //2022-12-01 12:12:12.123 System.out.println(Converts.to(date, Timestamp.class)); //2022-12-01 System.out.println(Converts.to(date, LocalDate.class)); //12:12:12.123 System.out.println(Converts.to(date, LocalTime.class)); //2022-12-01T12:12:12.123 System.out.println(Converts.to(date, LocalDateTime.class)); System.out.println("年份:"); //日期 String year = "2022"; //Sat Jan 01 00:00:00 CST 2022 System.out.println(Converts.to(year, Date.class)); //2022-01-01 System.out.println(Converts.to(year, java.sql.Date.class)); //00:00:00 System.out.println(Converts.to(year, Time.class)); //2022-01-01 00:00:00.0 System.out.println(Converts.to(year, Timestamp.class)); //2022-01-01 System.out.println(Converts.to(year, LocalDate.class)); //00:00 System.out.println(Converts.to(year, LocalTime.class)); //2022-01-01T00:00 System.out.println(Converts.to(year, LocalDateTime.class)); //枚举 A e1 = Converts.to("A", A.class);//C.A B e2 = Converts.to("A", B.class);//C.A } //enums enum A { A } enum B { A; public static B valueOf(A a) { return Enum.valueOf(B.class, a.name()); } } } ``` 2. 自定义类型 对于自定义类型,可以使用 ```Converts.registry(..)``` 来自注册对应类型的转换规则。 ```java public class ConvertRegistryDemo { public static void main(String[] args) { Converts.registry((original, targetType) -> new User(ParseToNumberUtils.to(original, int.class))); User user = Converts.to(1, User.class); User user1 = Converts.to(2.1f, User.class); User user2 = Converts.to(3.3d, User.class); System.out.println(user); //ConvertValueOfDemo.Role(id=1) System.out.println(user1); //ConvertValueOfDemo.Role(id=2) System.out.println(user2); //ConvertValueOfDemo.Role(id=3) } @ToString private static class User { private final Integer id; public User(Integer id) { this.id = id; } } } ``` 当然对于自定义类型转换,我们尝试定义一套,通用的类型转换方案。 这其中最好的选择无疑是 ```valueOf(...)``` 方法, 选择它最好的理由便是它可以兼容JDK的原生类型。 对于大部分的通用类型来说,他们都拥有 valueOf 方法。 对于上面的需要我们可以尝试在对应的类型中定义 valueOf方法 ```java class ConvertValueOfDemo { public static void main(String[] args) { User user = Converts.to(1, User.class); User userD = Converts.to(1.1d, User.class); System.out.println(user); //ConvertValueOfDemo.User(id=1) System.out.println(userD); //ConvertValueOfDemo.User(id=33) } @ToString private static class User { private Integer id; public User(Integer id) { this.id = id; } public static User valueOf(int w) { return new User(w); } public static User valueOf(double w) { return new User((int) (w + 32)); } } } ``` 我们默认为 Converts 注册了
        registry(new ToNumberConverter());
        registry(new ToTimeTypeConverter());
        registry(new ToTimestampConverter());
        registry(new ToStringConverter());
        registry(new SingleParameterMethodConverter("valueOf"));
        registry(new SingleParameterMethodConverter("from"));
   
```java public class ConvertValueOfDemo { public static void main(String[] args) { User user = Converts.to(1, User.class); User userD = Converts.to(1.1d, User.class); System.out.println(user); //ConvertValueOfDemo.Role(id=1) System.out.println(userD); //ConvertValueOfDemo.Role(id=33) } @ToString @Data private static class User { private final Integer id; public User(Integer id) { this.id = id; } public static User from(int w) { return new User(w); } public static User from(Integer w) { return new User(w); } public static User from(Double w) { return new User((int) (w + 32)); } } } ``` #### Prop 接口 ```java class PropDemo { public static void main(String[] args) { User userA = new User("A"); User userB = new User("B"); User userC = new User("C"); userA.setUser(userB); userB.setUser(userC); System.out.println(Prop.of(userA, User::getUser).get(User::getDesc).val()); //B Prop userAPro = Prop.of(userA, User::getUser); System.out.println(userAPro.val()); //PropDemo.User(desc=B, user=null) System.out.println(userAPro.isWritable()); //是否可写 System.out.println(userAPro.isReadable()); //是否可读 System.out.println(userAPro.getTarget() == userA); //true //public prop.PropDemo$User prop.PropDemo$User.setUser(prop.PropDemo$User) System.out.println(userAPro.writeMethod()); //public prop.PropDemo$User prop.PropDemo$User.getUser() System.out.println(userAPro.readMethod()); Object user = userAPro.get("user").val(); System.out.println(user == userC); //true System.out.println(userAPro.get("user") .get("xxx").val()); //null:(就算没有的属性也不会有异常) Admin admin = userAPro.val(Admin.class); System.out.println(admin); //PropDemo.Admin(desc=B) System.out.println(userAPro.val(Admin.class) == admin); //false Prop prop = Prop.of(admin, "id"); System.out.println(prop.isAnnotationPresent(Ano.class)); //true System.out.println(Prop.of(admin, "tmp").isAnnotationPresent(Ano.class)); //true } @Data @Accessors(chain = true) public static class User { private String desc; private User user; public User(String desc) { this.desc = desc; } } @Accessors(chain = true) public static class Admin { @Getter @Setter private String desc; private Integer id; @Ano private String tmp; @Ano public void setId(Integer id) { this.id = id; } public static Admin valueOf(User user) { return new Admin().setDesc(user.getDesc()); } } @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.FIELD, ElementType.METHOD}) public @interface Ano { } } ``` 如果你喜欢,欢迎star... 如果你有更好的想法:请联系我 282937567@qq.com #### 参与贡献 1. Fork 本仓库 2. 新建 Feat_xxx 分支 3. 提交代码 4. 新建 Pull Request