【问题标题】:Determine if a field is a type I created, using reflection使用反射确定字段是否是我创建的类型
【发布时间】:2014-12-19 08:41:34
【问题描述】:

假设我有一个对象,我把它拿来字段:

Field[] fields = obj.getFields();

现在我正在遍历每一个,如果它是某种类,我想打印它们的成员,否则只需使用field.get(obj),以防它是一个字符串、int 或任何该命令将打印其值的东西,而不仅仅是引用指针。

如何检测它?

【问题讨论】:

  • 每个System.out.println(obj) 调用都会隐式调用System.out.println(obj.toString())。所以 int、strings 和任何其他重写 toString() 方法的类都不会打印引用指针。
  • 好的,但是有没有办法判断它是在项目中声明的类,而不是在内部声明的 java 类?
  • @e-r-a-n 可以查看包名。但这并不能解决知道toString() 是否被覆盖的问题。这是你的最终目标吗?如果是这样,请参阅Detect if object has overriden toString()
  • @Duncan 没有,很遗憾没有。我想查看类字段并打印它们的值。但如果它是我创建的某种类,我也想在其上完成打印字段的整个过程

标签: java reflection


【解决方案1】:

您无需实例化即可获得类的每个字段的Type,如下所示:

public class GetFieldType {

    public static void main (String [] args) {
        Field [] fields = Hello.class.getFields();

        for (Field field: fields) {
            System.out.println(field.getGenericType());
        }
    }

    public static class Hello {
        public ByeBye bye;
        public String message;
        public Integer b;
        ...
    }
}

【讨论】:

    【解决方案2】:

    您可以使用instanceof 来区分对象。

    public static void main(String[] args) throws FileNotFoundException, UnsupportedEncodingException {
        Object[] objects = new Object[4];
        objects[0] = new Integer(2);
        objects[1] = "StringTest";
        objects[2] = new BigDecimal(2.00d);
        for (Object obj : objects) {
            if (obj != null) {
                if (obj instanceof BigDecimal) {
                    System.out.println("bigdecimal found " + obj);
                } else if (obj instanceof String) {
                    System.out.println("String found " + obj);
                } else {
                    System.out.println("Integer found " + obj);
                }
            }
            else{
                System.out.println("object is null");
            }
        }
    }
    

    【讨论】:

      【解决方案3】:

      如果您需要测试一个对象是否来自您的项目,您可以查看包名并将其与您的项目的包名进行比较。

      您可以对字段的声明类型或字段内容的运行时类型执行此操作。下面的 sn-p 演示了后一种方法:

      SomeClass foo = new SomeClass();
      
      for (Field f : foo.getClass().getDeclaredFields()) {
      
        boolean wasAccessible = f.isAccessible();
        try {
          f.setAccessible(true);
          Object object = f.get(foo);
      
          if (object != null) {
      
            if (object.getClass().getPackage().getName()
                .startsWith("your.project.package")) {
              // one of yours
            }
          } else {
            // handle a null value
          }
        } finally {
          f.setAccessible(wasAccessible);
        }
      }
      

      请记住,obj.getFields(); 仅返回可公开访问的字段。您可能需要考虑getDeclaredFields(),就像我在上面所做的那样。如果您坚持使用getFields(),则可以省略上面示例中的辅助功能代码。

      【讨论】:

        【解决方案4】:

        通过一些工作,您可以通过加载它们的类加载器来区分您的类。看看这个:

        Find where java class is loaded from

        虽然这可能会有所帮助,但它不会成为解决问题的灵丹妙药,主要是因为:

        • 基元(byte、short、char、int、long、float、double 和 boolean)不是类。
        • 类加载器的架构在不同的应用服务器中是不同的。
        • 不同的类加载器可以多次加载同一个类。

        【讨论】:

          【解决方案5】:

          我的理解是你在对象层次结构中递归并获取原语的值

          public class ParentMostClass {
             int a = 5;
             OtherClass other = new OtherClass();
          
             public static void main(String[] args) throws IllegalArgumentException,
              IllegalAccessException {
                ParentMostClass ref = new ParentMostClass();
                printFiledValues(ref);
            }
          
          public static void printFiledValues(Object obj)
              throws IllegalArgumentException, IllegalAccessException {
          
              Class<? extends Object> calzz = obj.getClass();
              Field[] fileds = obj.getClass().getDeclaredFields();
          
              for (Field field : fileds) {
                  Object member = field.get(obj);
                  // you need to handle all primitive, they are few
                  if (member instanceof String || member instanceof Number) {
                      System.out.println(calzz + "->" + field.getName() + " : "
                      + member);
                  } else {
                     printFiledValues(member);
              }
            }
          }
          }
          
          public class OtherClass {
              int b=10;
          }
          

          我得到了输出

          class com.example.ParentMostClass->a : 5
          class com.example.OtherClass->b : 10
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2015-08-08
            • 2011-02-11
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2012-12-28
            相关资源
            最近更新 更多