Java反射,使用GetDeclaredField时忽略大小写

发布于 2024-10-22 21:02:37 字数 264 浏览 1 评论 0原文

假设我有一个带有名为“myfield”的字符串字段的类,并使用反射来获取该字段,我发现 Object.getClass().getDeclaredField("myfield"); 是这种情况敏感,如果我使用 Object.getClass().getDeclaredField("MyField"); ,它会抛出 NoSuchFieldException

有什么办法可以解决吗?强迫它忽略大小写?

谢谢

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

以酷 2024-10-29 21:02:37

只需使用 Class.getDeclaredFields()并自行执行不区分大小写的匹配来查看结果。

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

旧城烟雨 2024-10-29 21:02:37

不,没有这样的办法。您可以获取所有字段并搜索它们:

Field[] fields = src.getClass().getDeclaredFields();
for(Field f:fields){
    if(f.getName().equalsIgnoreCase("myfield")){
    //stuff.
    }
}

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.
    }
}
忆依然 2024-10-29 21:02:37

我看到的唯一方法是迭代所有声明的字段,并将名称不区分大小写地与您正在查找的字段名称进行比较。

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.

夜清冷一曲。 2024-10-29 21:02:37

获取所有已声明字段的列表,并在循环中手动遍历它们,对名称进行不区分大小写的比较。

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

倾城月光淡如水﹏ 2024-10-29 21:02:37

不,没有直接的方法可以做到这一点,但是您可以创建一个辅助方法来执行此操作。
例如(未经测试)

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

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 );
}
一城柳絮吹成雪 2024-10-29 21:02:37

我并不是要破坏这个线程,但如果你在循环中使用上面的任何方法,你的性能将会很糟糕。预先创建地图,

首先将您搜索的项目设为大写,

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

我想说总是创建这样的地图,在反射时总是考虑性能。

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.

节枝 2024-10-29 21:02:37

最好尝试使用 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);
    }
}

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);
    }
}
望她远 2024-10-29 21:02:37

要记住的一件事是保存 getDeclaredFields() 的结果,这样在迭代时仅使用 equalsIgnoreCase 进行反射。反射有时会使速度减慢超过 100 倍,因此您只需执行一次的任何操作就执行一次。

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
}

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
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文