Java Reflection, Ignore case when using GetDeclare

2020-04-08 07:37发布

问题:

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

回答1:

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



回答2:

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.
    }
}


回答3:

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 );
}


回答4:

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.



回答5:

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



回答6:

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.



回答7:

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);
    }
}