簡體   English   中英

使用反射確定字段是否為我創建的類型

[英]Determine if a field is a type I created, using reflection

假設我有一個對象,並將其帶入字段:

Field[] fields = obj.getFields();

現在,我要遍歷每個對象,如果是某種類,則希望打印其成員,否則,如果它是字符串,int或此命令將打印其值的任何東西,則僅使用field.get(obj) ,而不僅僅是參考指針。

如何檢測到它?

您可以在不需要實例化的情況下獲得此類的每個字段的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;
        ...
    }
}

您可以使用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");
        }
    }
}

如果需要測試對象是否來自項目,則可以查看程序包名稱並將其與項目的程序包名稱進行比較。

您可以在字段的聲明類型或字段內容的運行時類型上執行此操作。 下面的代碼段演示了后一種方法:

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() ,則可以在上面的示例中省略可訪問性代碼。

通過一些工作,您可以通過加載它們的類加載器來區分您的類。 看看這個:

查找從何處加載Java類

盡管這可能有所幫助,但這並不是解決問題的靈丹妙葯,主要是因為:

  • 基元(byte,short,char,int,long,float,double和boolean)不是類。
  • 在不同的應用服務器中,類加載器的體系結構是不同的。
  • 同一類可以由不同的類加載器多次加載。

我了解的是您要在對象層次結構中遞歸並獲取基元的值

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM