【问题标题】:Java Reflection, Ignore case when using GetDeclaredFieldJava反射,使用GetDeclaredField时忽略大小写
【发布时间】:2011-03-18 11:11:08
【问题描述】:

假设我有一个名为“myfield”的字符串字段的类,并使用反射来获取该字段,我发现Object.getClass().getDeclaredField("myfield"); 是区分大小写的,如果我使用它会抛出一个NoSuchFieldException Object.getClass().getDeclaredField("MyField");

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

谢谢

【问题讨论】:

  • 请注意 Java 本身区分大小写,因此当您对名称执行 .toLowercase() 时,可能会有 2 个不同的字段具有相同的名称!
  • 我知道这一点,但就我而言,它保证不会发生

标签: java reflection


【解决方案1】:

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

【讨论】:

    【解决方案2】:

    不,没有这样的方法。您可以获取所有字段并通过它们进行搜索:

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

    【讨论】:

      【解决方案3】:

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

      【讨论】:

        【解决方案4】:

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

        【讨论】:

          【解决方案5】:

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

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

          【讨论】:

            【解决方案6】:

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

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

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

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

            【讨论】:

            • 如果你只想访问一个特定类的字段,性能会更差,可能还有其他情况。
            【解决方案7】:

            如果字段名不存在,最好尝试获取字段,然后遍历字段列表

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

            【讨论】:

              猜你喜欢
              • 2019-06-04
              • 1970-01-01
              • 1970-01-01
              • 2018-05-02
              • 2015-01-15
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多