Reputation: 263
Let's say I have a class with a string field named "myfield", and use reflection to get the field, I've found that Object.getClass().getDeclaredField("myfield");
is case sensitive, it will throw an NoSuchFieldException
if I for example use Object.getClass().getDeclaredField("MyField");
Is there any way around it? forcing it to ignore case?
Thanks
Upvotes: 8
Views: 12513
Reputation: 474
One thing to remember is to save the results of getDeclaredFields() this way you are only doing the reflection once use equalsIgnoreCase when you iterate. Reflection slows things down sometimes over 100x so anything you only have to do once, do once.
Field[] fields = MyClass.class.getDeclaredFields();
Field myField = null;
for (Field field : fields) {
if (field.getName().equalsIgnoreCase("myField")) {
myField = field;
break;
}
}
if (myField != null) {
// do what you want with the found field
} else {
//the field was not found and you wont get an error
}
Upvotes: -1
Reputation: 143
Best to try to get field with fieldName if does not exist then loop through list of fields
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);
}
}
Upvotes: 0
Reputation: 474
I don't mean to necro this thread but if you used any of the methods above inside a loop your performance will be awful. Create map beforehand
first take the item your search for to uppercase
item.getKey()
now create a map that has the uppercase version and the true fieldnames
Map<String, String> fieldNames = Arrays.asList(clazz.getDeclaredFields()).stream().collect(Collectors.toMap(t -> t.getName().toUpperCase(), f->f.getName()));
now use that to grab the true fieldname
Field field = clazz.getDeclaredField(fieldNames.get(key));
I would say always create such a map, always consider performance when it comes to reflection.
Upvotes: 1
Reputation: 1760
No, there is no direct way of doing this, however you could create a helper method for doing this. e.g. (untested)
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 );
}
Upvotes: 2
Reputation: 8127
No, there's no such way. You can get all fields and search through them:
Field[] fields = src.getClass().getDeclaredFields();
for(Field f:fields){
if(f.getName().equalsIgnoreCase("myfield")){
//stuff.
}
}
Upvotes: 4
Reputation: 21903
Get a list of all declared fields and manually go through them in a loop doing a case insensitive comparison on the name.
Upvotes: 2
Reputation: 116296
The only way I see is to iterate over all declared fields and compare the names case-insensitively to the field name you are looking for.
Upvotes: 2
Reputation: 1502806
Just use Class.getDeclaredFields()
and look through the results performing a case-insensitive match yourself.
Upvotes: 18