简体   繁体   English

获取Java中类的字段名称

[英]Get field names of a class in Java

I am trying to generate a CSV mapping for the fields of a class in Java in an automatic way since I need to use it several times. 我试图以一种自动方式为Java中的类的字段生成CSV映射,因为我需要多次使用它。

I have the following method for trying to get the field names: (where CSV header is something like "DB_NAME|FIELD_NAME|ADDITIONAL_F1|ADDITIONAL_F2") 我有以下尝试获取字段名称的方法:(其中CSV标头类似于“ DB_NAME | FIELD_NAME | ADDITIONAL_F1 | ADDITIONAL_F2”)

package util;

import java.lang.reflect.Field;

public class CsvAttributesMappingGenerator {
public static String generateCsvAttributesMapping(Class<?> model) {

    StringBuilder csvBuilder = new StringBuilder();

    Field[] fieldList = model.getDeclaredFields();
    for (Field field : fieldList) {
        //field.setAccessible(true);
        csvBuilder.append(field.getName().replaceAll("(.)(\\p{Upper})", "$1_$2").toUpperCase());
        csvBuilder.append("|");
        csvBuilder.append(field.getName());
        csvBuilder.append("||\n");
    }
    return formatOutput(csvBuilder.toString());
}

private static String formatOutput(String classText) {
    String delimiter = "\n******************************\n";
    return String.format("%s%s%s", delimiter, classText, delimiter);
}

} }

and a test call like: 和一个测试电话,例如:

import objects.User;
import org.junit.Test;
import util.CsvAttributesMappingGenerator;

public class CsvAttributesMappingGeneratorTest {

@Test
public void testGenerationWithObject() {
    System.out.println(CsvAttributesMappingGenerator.generateCsvAttributesMapping(User.class));
}
}

The object to be parsed has the following structure: package objects; 要解析的对象具有以下结构:包对象;

public class User {
private String userName;
private String userEmail;
private int userAge;
private String otherDetails;
// getters, setters and all args constuctor here
}

The output should have multiple rows like FIELD_NAME|fieldName|| 输出应具有多行,例如FIELD_NAME | fieldName || where the camel cased item should be collected from the given class. 应从给定班级收集骆驼装箱的物品。 I attempted to use Java Reflection API as I have seen on several examples but I get a strange String output instead. 正如我在几个示例中看到的那样,我尝试使用Java Reflection API,但是却得到了奇怪的String输出。 (not the serialized @randomCharsLikeName). (而不是序列化的@randomCharsLikeName)。 Tried toString() and other dirty tricks but nothing worked. 尝试了toString()和其他肮脏的技巧,但没有任何效果。

Can someone tip me up a little with this? 有人可以给我这个小费吗? Or at least tell me if it is possible to do what I tried? 或者至少告诉我是否可以做我尝试过的事情? Thanks in advance! 提前致谢!

EDIT: the current code prototype presented in the question works in an isolated environment (separate new project) and displays the expected output. 编辑:问题中提出的当前代码原型在隔离的环境(单独的新项目)中工作,并显示预期的输出。 It does not work though integrated within the whole application I am trying to integrate it into. 尽管集成到了我要集成到的整个应用程序中,但它不起作用。 I will keep researching and let you know the root cause (in the real app I am using also lombok for the classes ( 我将继续研究,并让您知道根本原因(在真实的应用中,我还将lombok用于课程(

@AllArgsConstructor, @NoArgsConstructor, @Data, @ToString @ AllArgsConstructor,@ NoArgsConstructor,@ Data,@ ToString

), but I do not honestly think that this might be an issue while using Reflection) ),但老实说,我不认为在使用Reflection时可能会遇到问题)

I found the issue in the meanwhile. 同时,我发现了这个问题。 While I was play-prototyping the generator, I used: 在对生成器进行游戏原型制作时,我使用了:

csvBuilder.append(field.getClass().getName().replaceAll("(.)(\\p{Upper})", "$1_$2").toUpperCase());

which produced outputs like JAVA.LANG.REFLECT._FIELD|java.lang.reflect.Field|| 产生了类似JAVA.LANG.REFLECT._FIELD|java.lang.reflect.Field||输出

Since I simply forgot that I actually improved it to use actual class object as a parameter to the function. 由于我只是忘记了我实际上对其进行了改进,以使用实际的类对象作为函数的参数。 Before asking the question I made some Sonar fixes to the code and did not notice that I fixed a WARN to remove the .getClass() method invocation since I already pass in a class (I thought it would not make a difference since it is just a warning). 在问这个问题之前,我对代码进行了一些Sonar修复,但没有注意到我修复了WARN以删除.getClass()方法调用,因为我已经传递了一个类(我认为这没有什么区别,因为它只是一个警告)。 Moral tip of the day - NEVER EVER ignore warnings. 每天的道德提示-永远不要忽略警告。

So the code snippets presented in the question work fine now in an isolated dummy project and also integrated within a more complex project, using the fixed line: 因此,问题中显示的代码段现在可以在一个隔离的虚拟项目中正常工作,并且还可以使用固定的行集成到一个更复杂的项目中:

csvBuilder.append(field.getName().replaceAll("(.)(\\p{Upper})", "$1_$2").toUpperCase());

Also as someone suggested in the comments, the field.setAccessible(true); 就像有人在评论中建议的那样, field.setAccessible(true); can be removed since it is useless for the purpose of the method. 可以将其删除,因为对于该方法而言,它是无用的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM