7

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

Dead Programmer
  • 12,207
  • 20
  • 77
  • 111
GoofyHTS
  • 253
  • 1
  • 6
  • 15
  • 1
    Beware that Java itself is case-sensitive so there may be 2 different fields which have same name when you do .toLowercase() on the name! – Jan Zyka Mar 18 '11 at 11:22
  • I'm aware of that, but in my case it's guaranteed not to happen – GoofyHTS Mar 18 '11 at 12:25

7 Answers7

17

Just use Class.getDeclaredFields() and look through the results performing a case-insensitive match yourself.

Jon Skeet
  • 1,335,956
  • 823
  • 8,931
  • 9,049
3

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.
    }
}
secmask
  • 7,037
  • 4
  • 32
  • 51
2

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.

Péter Török
  • 112,083
  • 30
  • 265
  • 327
2

Get a list of all declared fields and manually go through them in a loop doing a case insensitive comparison on the name.

drekka
  • 19,752
  • 14
  • 73
  • 119
2

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 );
}
Danilo Tommasina
  • 1,730
  • 11
  • 25
1

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.

jdmneon
  • 411
  • 7
  • 10
  • If you only want to access one field for a particular class performance will be worse and there might be other situatuations. – lifesoordinary Sep 13 '18 at 13:02
0

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);
    }
}
lifesoordinary
  • 113
  • 2
  • 8