【问题标题】:Finding all private fields and their corresponding getters / setters for nested classes查找嵌套类的所有私有字段及其对应的 getter/setter
【发布时间】:2017-07-27 21:16:45
【问题描述】:

情况:很少有应用程序使用 Java DTO 进行通信。 我有一些类作为其字段包含另一个类,并且它们包含另一个类(从顶部 DTO 向下最多三个级别)。

字段可以是单个 DTO,也可以是(仅)其他类 (DTO) 的 ArrayList。 所有类都是 DTO。只是私有字段和公共 setter 和 getter。

现在,当我获得顶级 DTO 时,有什么方法可以检查它并获取所有 getter,包括嵌套的 getter,通过 getter 读取字段,然后做我必须做的事情(更改一些数据,特别是删除/更改一些字符(我有这样做的方法,所有最终字段最终都是字符串或整数),然后使用适当的设置器写回数据。我想最好的方法是为每个最终字段找到 getter/setter 对并进行操作,然后移至下一个。找到final(最低级别的字段)我应该检查它是否是String(执行操作)以及Integer是否跳过操作。

我知道有类似的问题,但它不涉及嵌套 DTO。 Java reflection get all private fields

如果可能,我会避免使用任何 3rd 方库。

对此有何建议?

更新:快到了。这是一种演示代码,我希望它如此简单,但从概念上讲,它更像是这样:

课堂研讨会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;
    }
}

类 ProgramDTO

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;
    }
}

类 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;
}

类 AuthorDTO

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

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

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)

【问题讨论】:

    标签: java java-6


    【解决方案1】:

    您可以使用getDeclaredClasses 查找嵌套类,然后查找私有字段,最后查找 getter 和 setter:

    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);
            }
        }
    }
    

    编辑:上面的代码对问题标题中提到的“嵌套类”有效。将示例代码添加到问题后,问题似乎是关于类字段的 getter 和 setter:

    使用getDeclaredFields获取类的所有字段,如上找到对应的getter和setter;使用getType 获取每个字段的类型(类)并(递归)从该类开始。

    【讨论】:

    • 本可以在一个大流命令中完成所有操作...但我相信这样更容易理解
    • 谢谢,现在我只需要在 Java 6 中编写这部分并尝试一下: Field[] fields = Arrays.stream(innerClass.getDeclaredFields()) .filter( field -> Modifier.isPrivate( field.getModifiers())) .toArray(Field[]::new);
    • @NenadBulatovic 没有提到有问题的 Java 6。答案(和问题)变了!
    • 谢谢,卡洛斯,我想我快到了,但我错过了一些东西。
    • 我错过了您的代码中的“嵌套类”(仅在我的答案的第二版之后添加).... Java 语言规范的第 8 章: “嵌套类是其声明出现在另一个类或接口的主体中的任何类。”
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-02-21
    • 2020-11-08
    • 2014-11-12
    • 1970-01-01
    • 1970-01-01
    • 2014-03-27
    • 2021-11-15
    相关资源
    最近更新 更多