GoofyHTS
GoofyHTS

Reputation: 263

Java Reflection, Ignore case when using GetDeclaredField

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

Answers (8)

jdmneon
jdmneon

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

lifesoordinary
lifesoordinary

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

jdmneon
jdmneon

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

Danilo Tommasina
Danilo Tommasina

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

secmask
secmask

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

drekka
drekka

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

P&#233;ter T&#246;r&#246;k
P&#233;ter T&#246;r&#246;k

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

Jon Skeet
Jon Skeet

Reputation: 1502806

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

Upvotes: 18

Related Questions