Java Reflection,使用GetDeclaredField时忽略大小写

问题描述 投票:4回答:7

假设我有一个名为“myfield”的字符串字段的类,并使用反射来获取字段,我发现Object.getClass().getDeclaredField("myfield");区分大小写,如果我使用NoSuchFieldException它将抛出Object.getClass().getDeclaredField("MyField");

它有什么办法吗?强迫它忽略案例?

谢谢

java reflection
7个回答
15
投票

只需使用Class.getDeclaredFields()并查看结果,自己执行不区分大小写的匹配。


3
投票

不,没有这样的方式。您可以获取所有字段并搜索它们:

Field[] fields = src.getClass().getDeclaredFields();
for(Field f:fields){
    if(f.getName().equalsIgnoreCase("myfield")){
    //stuff.
    }
}

3
投票

不,没有直接的方法可以做到这一点,但是你可以创建一个辅助方法来做到这一点。例如(另)

public Field getDeclaredFieldIngoreCase( Class<?> clazz, String fieldName ) throws NoSuchFieldException {

        for( Field field : clazz.getDeclaredFields() ) {
            if ( field.getName().equalsIgnoreCase( fieldName ) ) {
                return field;
            }
        }
        throw new NoSuchFieldException( fieldName );
}

2
投票

我看到的唯一方法是迭代所有声明的字段,并将名称不区分大小写与您要查找的字段名称进行比较。


2
投票

获取所有已声明字段的列表,并在循环中手动浏览它们,对名称进行不区分大小写的比较。


0
投票

我并不是要暗示这个帖子,但是如果你在循环中使用了上面的任何方法,你的表现就会很糟糕。事先创建地图

首先将您搜索的项目取大写

item.getKey()

现在创建一个具有大写版本和真实字段名称的地图

Map<String, String> fieldNames = Arrays.asList(clazz.getDeclaredFields()).stream().collect(Collectors.toMap(t -> t.getName().toUpperCase(), f->f.getName()));

现在使用它来获取真正的字段名称

  Field field = clazz.getDeclaredField(fieldNames.get(key));

我会说总是创建这样的地图,总是在反思时考虑性能。


0
投票

如果不存在则最好尝试使用fieldName获取字段然后循环遍历字段列表

public static Field findFieldIgnoreCase(Class<?> clazz, String fieldName) throws SecurityException, NoSuchFieldException {
    try {
        return clazz.getDeclaredField(fieldName);
    } catch (NoSuchFieldException e) {
        Field[] fields = clazz.getDeclaredFields();
        for (Field field : fields) {
            if (field.getName().equalsIgnoreCase(fieldName)) {
                return field;
            }
        }
        throw new NoSuchFieldException(fieldName);
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.