当前位置: 首页 > 知识库问答 >
问题:

为嵌套类查找所有私有字段及其对应的getter/setter

袁翔
2023-03-14

情境:很少有应用程序使用Java DTO进行通信。我有一个类,它作为字段持有另一个类,它们持有另一个类(从顶部DTO到下面三个级别)。

字段可以是单个DTO或作为其他类(DTO)的ArrayList(排他)。所有类都是DTO。只有私有字段和公共setter和getter。

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

我知道有类似的问题,但它不涉及嵌套的DTO。Java反射获取所有私有字段

如果可能,我会避免任何第三方图书馆。

对此有什么建议吗?

更新:快到了。这里是一个演示代码,我希望它是如此简单,但从概念上来说,它更不是那样:

班级座谈会

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;
    }
}
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;
    }
}
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<----by Carlos如果我正确理解了他的指令,这个版本根本不会给出任何输出,甚至连GET在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);
        }
    }
    }
}

专题讨论会To:getter=public java.util.ArrayList专题讨论会To.getPaperSDTo(),setter=public void专题讨论会To.setPaperSDTo(java.util.ArrayList)

专题讨论会:getter=public ProgramDTO专题讨论会.getProgramdto(),setter=public void专题讨论会.setProgramdto(ProgramDTO)

专题讨论会To:getter=public java.util.ArrayList专题讨论会To.getPaperSDTo(),setter=public void专题讨论会To.setPaperSDTo(java.util.ArrayList)

共有1个答案

景光赫
2023-03-14

您可以使用getDeclaredClasss查找嵌套类,然后查找私有字段,最后查找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获取每个字段的类型(类),并(递归地)从该类重新开始。

 类似资料:
  • 我想通过枚举一组给定类的私有字段来动态创建一个类组合映射。这适用于具有一组独立类的getDeclaredFields()。 但是,如果类包含一个字段,该字段的类型是不可用的类,则调用将失败。有没有办法枚举私有字段,这样我就可以避免这种行为,例如一个接一个地捕捉异常并继续处理其余字段?

  • 基本问题如下:有没有一种方便的方法可以为嵌套查询的所有字段指定多字段匹配?对于普通查询有效。这在嵌套查询中不起作用,可能是因为嵌套对象没有_all? 下面是更详细的问题: 我有一个名为“Parent”的嵌套文档,如下所示: 这是我用于制作儿童嵌套对象的映射: 这是一个查询,我想使用所有子字段的匹配来选择几个术语查询,以及一个术语查询: 上述查询不起作用,因为我无法为嵌套对象选择多匹配查询中的所有字

  • 我使用的是ES版本5.6。我有一个像下面这样的文档存储在ES中。 我想搜索所有已“启用”的字段。 我尝试了以下查询,但都不起作用。 但是下面的查询起作用了 因此,看起来只匹配顶级字段,而不匹配嵌套字段。是否有任何方法可以查询包含在所有字段中的文本,包括嵌套字段。我不想显式指定嵌套字段名。我正在寻找一种全局搜索,我想在文档中的任何地方搜索“文本”。 谢了。

  • 我正在使用Jackson ObjectMapper序列化POJO。我在POJO中有嵌套字段。例如:序列化类 如果字符串为,则不序列化整个属性。也就是说,如果字符串为,我希望输出为: 但我得到的是作为输出。 我已经为序列化包含设置了(),但这并不能解决问题

  • 问题内容: 在我经历1000 s 之后,可能不需要 是否有 任何情况下, 该下降从将使在差异 封装 (或 使用 例如,通过外)?还考虑思考 如果 不 建议将其删除或使其与编码风格保持一致? 我说 没有 和 下降 ,但不知道真的。 编辑: 刚意识到 我 的方式肯定是错误的-至少对于的 字段 -声明这些字段为私有字段,然后在外部类中使用它们- 因为这会在字节码中生成( “ synthetic” )访问

  • 问题内容: 我有一本这样的字典: 基本上是一本具有嵌套列表,字典和字符串的字典,其深度是任意的。 遍历此方法以提取每个“ id”键的值的最佳方法是什么?我想实现与“ // id”之类的XPath查询等效的功能。“ id”的值始终是一个字符串。 因此,从我的示例中,我需要的输出基本上是: 顺序并不重要。 问题答案: 我发现此Q / A非常有趣,因为它为同一问题提供了几种不同的解决方案。我采用了所有这