我在RequestDto中有一个声明字段(requestDto有很多声明的字段,但是我只想要这个自定义字段)
private String custom;
我想获得这个声明的字段名称Custom作为String
像String name-"custom"(but custom has to be dynamic)
解决方案必须无需修改默认的getter和setter
实际上,我有一个问题,例如如果请求Dto中的字段之一包含错误数据,则应处理requestDto以进行内容验证,我应该提供错误消息以及字段名称作为字符串,其中包含不相关的数据< / p>
问题是,将来在RequestDto中修改自定义字段时,修改该字段的人甚至都不知道自定义字段已设置为字符串并被使用,因此我想将自定义字段名称作为RequestDto中的字符串只有,所以当字段值更改时,我会在字符串中获取更改的名称
答案 0 :(得分:4)
编辑:在注释“如果将来有人更改此名称该怎么办”中添加了最重要的信息之后...好吧,那么思考就不可行了!
然后,我宁愿使用类似Function<RequestDto, String>
之类的字词,例如:
static String getCustom(RequestDto requestDto, Function<RequestDto, String> customExtractor) {
return customExtractor.apply(requestDto);
}
并通过以下方式调用它:
RequestDto someRequest = ...;
getCustom(someRequest, RequestDto::getCustom);
如果将来会重构该字段,那么该部分也会被重构,然后也会自动重构(嗯……可能取决于您的IDE ;-)。但是...它不会给您适当的字段名称作为错误消息。请注意,如果要获取正确的字段,唯一的属性就是它的名称,这不是一种捕获正确字段的好方法。如果要在字段上添加注释,则可以过滤并抓取具有该特定注释的字段。这样,您无需知道实际名称...而是反问:您如何确定只有1个字段使用该注释进行注释?我宁愿重新设计应用程序的特定部分。我不会向“客户端”公开任何字段。如果那意味着我在错误消息和字段名称中可能使用不同的名称,那就这样吧。
还请注意,现代IDE也允许您重构字符串(重命名字段时)。您只需要确保随后将这些信息传播到整个团队(以及将来的成员)即可。
使用反射的先前答案:
如果使用动态,是指它必须以该名称开头或包含该名称,则可能需要使用以下内容,即getDeclaredFields()
并对其进行迭代以过滤出感兴趣的字段:
private static String getCustom(RequestDto requestDto) throws NoSuchFieldException, IllegalAccessException {
return Arrays.stream(requestDto.getClass().getDeclaredFields())
.filter(e -> e.getName().startsWith("custom"))
.findFirst() // if the first match suffices
.map(f -> { // you may want to extract that part if you use streams
f.setAccessible(true);
try {
return (String) f.get(requestDto);
} catch (IllegalAccessException e) {
// TODO whatever you need to do...
return null;
}
}).orElseThrow(IllegalArgumentException::new); // or whatever suites better
}
如果您需要按类型或注释等进行过滤,则此示例就足够了。只需对过滤器进行相应调整即可。
如果只是您需要的字段名称,那么它就是您想要的Field.getName()
。
答案 1 :(得分:2)
private static String getCustom(RequestDto requestDto) throws NoSuchFieldException, IllegalAccessException {
Field field = requestDto.getClass().getDeclaredField("custom");
field.setAccessible(true);
return (String) field.get(requestDto);
}
如果它对您来说不够“动态”:
private static String getField(RequestDto requestDto, String fieldName) throws NoSuchFieldException, IllegalAccessException {
Field field = requestDto.getClass().getDeclaredField(fieldName);
field.setAccessible(true);
return (String) field.get(requestDto);
}