假设我有一个名为“myfield”的字符串字段的类,并使用反射来获取字段,我发现Object.getClass().getDeclaredField("myfield");
区分大小写,如果我使用NoSuchFieldException
它将抛出Object.getClass().getDeclaredField("MyField");
它有什么办法吗?强迫它忽略案例?
谢谢
只需使用Class.getDeclaredFields()
并查看结果,自己执行不区分大小写的匹配。
不,没有这样的方式。您可以获取所有字段并搜索它们:
Field[] fields = src.getClass().getDeclaredFields();
for(Field f:fields){
if(f.getName().equalsIgnoreCase("myfield")){
//stuff.
}
}
不,没有直接的方法可以做到这一点,但是你可以创建一个辅助方法来做到这一点。例如(另)
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 );
}
我看到的唯一方法是迭代所有声明的字段,并将名称不区分大小写与您要查找的字段名称进行比较。
获取所有已声明字段的列表,并在循环中手动浏览它们,对名称进行不区分大小写的比较。
我并不是要暗示这个帖子,但是如果你在循环中使用了上面的任何方法,你的表现就会很糟糕。事先创建地图
首先将您搜索的项目取大写
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));
我会说总是创建这样的地图,总是在反思时考虑性能。
如果不存在则最好尝试使用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);
}
}