查找嵌套 类 的所有私有字段及其相应的 getters/setters
Finding all private fields and their corresponding getters / setters for nested classes
情况:很少有应用程序使用 Java DTO 进行通信。
我有 classes 作为其字段保存另一个 classes 并且它们保存另一个 classes(从顶部 DTO 最多向下三个级别)。
字段可以是单个 DTO 或作为(唯一的)其他 classes (DTO) 的 ArrayList。
所有 classes 都是 DTO。只是私有字段和 public setters 和吸气剂。
现在,当我获得顶级 DTO 时,有什么方法可以检查它并获取所有吸气剂,包括嵌套吸气剂,通过吸气剂读取字段,然后做我必须做的事情(更改一些数据,特别是 remove/change 一些字符(我有这样做的方法,所有最终字段最终都是字符串或整数),然后使用适当的 setter 写回数据。我想最好的办法是在每个最终字段中找到 getter/setter 对字段并执行操作然后转到下一个。找到最终(最低级别的字段)后,我应该检查它是否是字符串(执行操作)以及整数是否跳过操作。
我知道有类似的问题,但它不处理嵌套的 DTO。
Java reflection get all private fields
如果可能,我会避免使用任何第 3 方库。
对此有何建议?
更新:快到了。这是一种演示代码,我希望它如此简单,但从概念上讲它更不像那样:
class 座谈会DTO
import java.util.ArrayList;
public class SymposiaDTO {
private ProgramDTO programDTO;
private ArrayList<PaperDTO> papersDTO;
public ProgramDTO getProgramDTO() {
return programDTO;
}
public void setProgramDTO(ProgramDTO programDTO) {
this.programDTO = programDTO;
}
public ArrayList<PaperDTO> getPapersDTO() {
return papersDTO;
}
public void setPapersDTO(ArrayList<PaperDTO> papersDTO) {
this.papersDTO = papersDTO;
}
}
class 程序 DTO
public class ProgramDTO {
String programTitle;
Integer programID;
public String getProgramTitle() {
return programTitle;
}
public void setProgramTitle(String programTitle) {
this.programTitle = programTitle;
}
public Integer getProgramID() {
return programID;
}
public void setProgramID(Integer programID) {
this.programID = programID;
}
}
class PaperDTO
import java.util.ArrayList;
public class PaperDTO {
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public ArrayList<AuthorDTO> getAuthrosDTO() {
return authrosDTO;
}
public void setAuthrosDTO(ArrayList<AuthorDTO> authrosDTO) {
this.authrosDTO = authrosDTO;
}
private String title;
private ArrayList<AuthorDTO> authrosDTO;
}
class作者DTO
public class AuthorDTO {
private String address;
private String name;
private String title;
private String age;
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getAge() {
return age;
}
public void setAge(String age) {
this.age = age;
}
}
class Controller <--- Carlos 如果我没有听错他的指示,这个版本根本没有输出,甚至从来没有在 for 循环中得到单次迭代。
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
public class Controller {
@SuppressWarnings({ "unused", "rawtypes" })
public static void main(String[] args) {
SymposiaDTO symposiaDTO = new SymposiaDTO();
ProgramDTO programDTO = new ProgramDTO();
PaperDTO paperDTO = new PaperDTO();
AuthorDTO authorDTO = new AuthorDTO();
Class<?> topClass = symposiaDTO.getClass();
for (Class<?> innerClass : topClass.getDeclaredClasses()) {
for (Field field : innerClass.getDeclaredFields()) {
if (Modifier.isPrivate(field.getModifiers())) {
String name = Character.toUpperCase(field.getName().charAt(0)) + field.getName().substring(1);
Method getter;
try {
getter = innerClass.getDeclaredMethod("get" + name);
} catch (Exception ex) {
getter = null;
}
Method setter;
try {
setter = innerClass.getDeclaredMethod("set" + name, field.getType());
} catch (Exception ex) {
setter = null;
}
// TODO real work...
System.out.printf("%s: getter=%s, setter=%s%n", innerClass.getSimpleName(), getter, setter);
}
}
}
}
}
class Controller2 <--- 稍微修改了以前的版本,这进入了循环,但运行了两次,并且它永远不会深入嵌套 DTO。
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class Controller2 {
@SuppressWarnings({ "unused", "rawtypes" })
public static void main(String[] args) {
SymposiaDTO symposiaDTO = new SymposiaDTO();
ProgramDTO programDTO = new ProgramDTO();
PaperDTO paperDTO = new PaperDTO();
AuthorDTO authorDTO = new AuthorDTO();
Class<?> topClass = symposiaDTO.getClass();
List<Class> classesToWalk = new ArrayList<Class>();
for (Field field : topClass.getDeclaredFields()) {
Class symposiaDTO2 = field.getDeclaringClass();
classesToWalk.add(symposiaDTO2);
}
for (Class<?> innerClass : classesToWalk) {
Field[] fields = Arrays.stream(innerClass.getDeclaredFields())
.filter(field -> Modifier.isPrivate(field.getModifiers())).toArray(Field[]::new);
for (Field field : fields) {
String name = Character.toUpperCase(field.getName().charAt(0)) + field.getName().substring(1);
Method getter;
try {
getter = innerClass.getDeclaredMethod("get" + name);
} catch (Exception ex) {
getter = null;
}
Method setter;
try {
setter = innerClass.getDeclaredMethod("set" + name, field.getType());
} catch (Exception ex) {
setter = null;
}
// TODO real work...
System.out.printf("%s: getter=%s, setter=%s%n", innerClass.getSimpleName(), getter, setter);
}
}
}
}
这是 Controller2 的输出:
SymposiaDTO: getter=public ProgramDTO SymposiaDTO.getProgramDTO(),
setter=public void SymposiaDTO.setProgramDTO(ProgramDTO)
SymposiaDTO: getter=public java.util.ArrayList
SymposiaDTO.getPapersDTO(), setter=public void
SymposiaDTO.setPapersDTO(java.util.ArrayList)
SymposiaDTO: getter=public ProgramDTO SymposiaDTO.getProgramDTO(),
setter=public void SymposiaDTO.setProgramDTO(ProgramDTO)
SymposiaDTO: getter=public java.util.ArrayList
SymposiaDTO.getPapersDTO(), setter=public void
SymposiaDTO.setPapersDTO(java.util.ArrayList)
您可以使用 getDeclaredClasses
找到嵌套的 classes,然后找到私有字段,最后找到 getters 和 setters:
Class<?> topClass = ...
for (Class<?> innerClass : topClass.getDeclaredClasses()) {
for (Field field : innerClass.getDeclaredFields()) {
if (Modifier.isPrivate(field.getModifiers())) {
String name = Character.toUpperCase(field.getName().charAt(0))
+ field.getName().substring(1);
Method getter;
try {
getter = innerClass.getDeclaredMethod("get" + name);
} catch (Exception ex) {
getter = null;
}
Method setter;
try {
setter = innerClass.getDeclaredMethod("set" + name, field.getType());
} catch (Exception ex) {
setter = null;
}
// TODO real work...
System.out.printf("%s: getter=%s, setter=%s%n",
innerClass.getSimpleName(), getter, setter);
}
}
}
编辑:如问题标题中所述,以上代码对 "nested classes" 有效。将示例代码添加到问题后,问题似乎是关于 class:
字段的 getters 和 setters
使用getDeclaredFields
获取class的所有字段,找到对应的getter和setter同上;使用 getType
获取每个字段的类型 (class) 并(递归地)从 class.
开始
情况:很少有应用程序使用 Java DTO 进行通信。 我有 classes 作为其字段保存另一个 classes 并且它们保存另一个 classes(从顶部 DTO 最多向下三个级别)。
字段可以是单个 DTO 或作为(唯一的)其他 classes (DTO) 的 ArrayList。 所有 classes 都是 DTO。只是私有字段和 public setters 和吸气剂。
现在,当我获得顶级 DTO 时,有什么方法可以检查它并获取所有吸气剂,包括嵌套吸气剂,通过吸气剂读取字段,然后做我必须做的事情(更改一些数据,特别是 remove/change 一些字符(我有这样做的方法,所有最终字段最终都是字符串或整数),然后使用适当的 setter 写回数据。我想最好的办法是在每个最终字段中找到 getter/setter 对字段并执行操作然后转到下一个。找到最终(最低级别的字段)后,我应该检查它是否是字符串(执行操作)以及整数是否跳过操作。
我知道有类似的问题,但它不处理嵌套的 DTO。 Java reflection get all private fields
如果可能,我会避免使用任何第 3 方库。
对此有何建议?
更新:快到了。这是一种演示代码,我希望它如此简单,但从概念上讲它更不像那样:
class 座谈会DTO
import java.util.ArrayList;
public class SymposiaDTO {
private ProgramDTO programDTO;
private ArrayList<PaperDTO> papersDTO;
public ProgramDTO getProgramDTO() {
return programDTO;
}
public void setProgramDTO(ProgramDTO programDTO) {
this.programDTO = programDTO;
}
public ArrayList<PaperDTO> getPapersDTO() {
return papersDTO;
}
public void setPapersDTO(ArrayList<PaperDTO> papersDTO) {
this.papersDTO = papersDTO;
}
}
class 程序 DTO
public class ProgramDTO {
String programTitle;
Integer programID;
public String getProgramTitle() {
return programTitle;
}
public void setProgramTitle(String programTitle) {
this.programTitle = programTitle;
}
public Integer getProgramID() {
return programID;
}
public void setProgramID(Integer programID) {
this.programID = programID;
}
}
class PaperDTO
import java.util.ArrayList;
public class PaperDTO {
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public ArrayList<AuthorDTO> getAuthrosDTO() {
return authrosDTO;
}
public void setAuthrosDTO(ArrayList<AuthorDTO> authrosDTO) {
this.authrosDTO = authrosDTO;
}
private String title;
private ArrayList<AuthorDTO> authrosDTO;
}
class作者DTO
public class AuthorDTO {
private String address;
private String name;
private String title;
private String age;
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getAge() {
return age;
}
public void setAge(String age) {
this.age = age;
}
}
class Controller <--- Carlos 如果我没有听错他的指示,这个版本根本没有输出,甚至从来没有在 for 循环中得到单次迭代。
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
public class Controller {
@SuppressWarnings({ "unused", "rawtypes" })
public static void main(String[] args) {
SymposiaDTO symposiaDTO = new SymposiaDTO();
ProgramDTO programDTO = new ProgramDTO();
PaperDTO paperDTO = new PaperDTO();
AuthorDTO authorDTO = new AuthorDTO();
Class<?> topClass = symposiaDTO.getClass();
for (Class<?> innerClass : topClass.getDeclaredClasses()) {
for (Field field : innerClass.getDeclaredFields()) {
if (Modifier.isPrivate(field.getModifiers())) {
String name = Character.toUpperCase(field.getName().charAt(0)) + field.getName().substring(1);
Method getter;
try {
getter = innerClass.getDeclaredMethod("get" + name);
} catch (Exception ex) {
getter = null;
}
Method setter;
try {
setter = innerClass.getDeclaredMethod("set" + name, field.getType());
} catch (Exception ex) {
setter = null;
}
// TODO real work...
System.out.printf("%s: getter=%s, setter=%s%n", innerClass.getSimpleName(), getter, setter);
}
}
}
}
}
class Controller2 <--- 稍微修改了以前的版本,这进入了循环,但运行了两次,并且它永远不会深入嵌套 DTO。
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class Controller2 {
@SuppressWarnings({ "unused", "rawtypes" })
public static void main(String[] args) {
SymposiaDTO symposiaDTO = new SymposiaDTO();
ProgramDTO programDTO = new ProgramDTO();
PaperDTO paperDTO = new PaperDTO();
AuthorDTO authorDTO = new AuthorDTO();
Class<?> topClass = symposiaDTO.getClass();
List<Class> classesToWalk = new ArrayList<Class>();
for (Field field : topClass.getDeclaredFields()) {
Class symposiaDTO2 = field.getDeclaringClass();
classesToWalk.add(symposiaDTO2);
}
for (Class<?> innerClass : classesToWalk) {
Field[] fields = Arrays.stream(innerClass.getDeclaredFields())
.filter(field -> Modifier.isPrivate(field.getModifiers())).toArray(Field[]::new);
for (Field field : fields) {
String name = Character.toUpperCase(field.getName().charAt(0)) + field.getName().substring(1);
Method getter;
try {
getter = innerClass.getDeclaredMethod("get" + name);
} catch (Exception ex) {
getter = null;
}
Method setter;
try {
setter = innerClass.getDeclaredMethod("set" + name, field.getType());
} catch (Exception ex) {
setter = null;
}
// TODO real work...
System.out.printf("%s: getter=%s, setter=%s%n", innerClass.getSimpleName(), getter, setter);
}
}
}
}
这是 Controller2 的输出:
SymposiaDTO: getter=public ProgramDTO SymposiaDTO.getProgramDTO(), setter=public void SymposiaDTO.setProgramDTO(ProgramDTO)
SymposiaDTO: getter=public java.util.ArrayList SymposiaDTO.getPapersDTO(), setter=public void SymposiaDTO.setPapersDTO(java.util.ArrayList)
SymposiaDTO: getter=public ProgramDTO SymposiaDTO.getProgramDTO(), setter=public void SymposiaDTO.setProgramDTO(ProgramDTO)
SymposiaDTO: getter=public java.util.ArrayList SymposiaDTO.getPapersDTO(), setter=public void SymposiaDTO.setPapersDTO(java.util.ArrayList)
您可以使用 getDeclaredClasses
找到嵌套的 classes,然后找到私有字段,最后找到 getters 和 setters:
Class<?> topClass = ...
for (Class<?> innerClass : topClass.getDeclaredClasses()) {
for (Field field : innerClass.getDeclaredFields()) {
if (Modifier.isPrivate(field.getModifiers())) {
String name = Character.toUpperCase(field.getName().charAt(0))
+ field.getName().substring(1);
Method getter;
try {
getter = innerClass.getDeclaredMethod("get" + name);
} catch (Exception ex) {
getter = null;
}
Method setter;
try {
setter = innerClass.getDeclaredMethod("set" + name, field.getType());
} catch (Exception ex) {
setter = null;
}
// TODO real work...
System.out.printf("%s: getter=%s, setter=%s%n",
innerClass.getSimpleName(), getter, setter);
}
}
}
编辑:如问题标题中所述,以上代码对 "nested classes" 有效。将示例代码添加到问题后,问题似乎是关于 class:
字段的 getters 和 setters使用getDeclaredFields
获取class的所有字段,找到对应的getter和setter同上;使用 getType
获取每个字段的类型 (class) 并(递归地)从 class.