2017-03-07 17 views
1

情况:少数应用程序使用Java DTO进行通信。 我有类作为其领域保持另一类,他们举行另一个类(从顶级DTO最多三级)。查找嵌套类的所有私有字段及其相应的获取者/设置者

字段可以是单个DTO或作为(排它)其他类(DTO)的ArrayList。 所有类都是DTO。只是私人领域和公开制定者和获得者。

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

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

如果可能,我会避免任何第三方库。

对此有何建议?

更新:几乎在那里。这是一种演示代码,我希望它是如此简单,但在概念上它就是这样更少:

类SymposiaDTO

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

class 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 < ---作者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); 
     } 
     } 
    } 
    } 
} 

类控制器2 < ---略作修改之前的版本,这个进入循环,但运行两次,它从来没有得到深入嵌套的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); 
     } 
    } 
    } 
} 

这是从控制器2输出:

SymposiaDTO:吸气=公共ProgramDTO SymposiaDTO.getProgramDTO(), 设定器=公共无效SymposiaDTO.setProgramDTO(ProgramDTO)

SymposiaDTO:吸气= 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:吸气=公共java.util.ArrayList中 SymposiaDTO.getPapersDTO(),二传手=公共无效 SymposiaDTO.setPapersDTO(java.util.ArrayList中)

回答

2

你可以使用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); 
     } 
    } 
} 

编辑:上面的代码是有效的“嵌套类”为提在问题标题中编辑。将示例代码添加到问题后,似乎问题是有关类的字段的获取者和设置者:

使用getDeclaredFields获取该类的所有字段并找到与上面相对应的getter和setter;使用getType来获取每个字段的类型(类)并(递归地)从该类重新开始。

+1

本来可以在一个大流命令中完成所有操作......但我相信这样可以更容易理解 –

+0

谢谢,现在我只需在Java 6中编写此部分并尝试它:Field [] fields = Arrays .stream(innerClass.getDeclaredFields()) .filter(field - > Modifier.isPrivate(field.getModifiers())) .toArray(Field [] :: new); –

+1

@NenadBulatovic没有提到Java 6的问题。答案(和问题)改变了! –