2010-08-10 63 views
6

我有巨大的對象,我有它的課程,我從中提取一些值,但因爲它真的很大,我不知道在哪個列表或我在找什麼值因爲是。在java中的擊穿對象

有沒有辦法創建某種對象分解路由和搜索每個部分的值我期待,它是隱藏在對象的某個地方,我只是無法找到它在eclipse中它的嵌套。

我想過使用反射去低谷對象類的所有領域,並搜索每個領域內的值(列表內的列表(列表等列表))中的值。任何其他想法?

遺憾的是沒有這些答案幫助我,我開始賞金

+1

看看是否有幫助:http://stackoverflow.com/questions/301536/what-is-the-java-equivalent-of-php-var-轉儲 – 2010-08-10 11:54:19

+3

聽起來像你需要重構和重新設計這個對象。 – Oded 2010-08-10 11:54:38

+0

既然你在這裏問,我假設「問發明家」的答案已經被追究或者是不可能的? – Carl 2010-08-10 11:55:51

回答

6

我假設你只是想找到一個特定的值並追蹤它的來源。而這一切,你想在調試時做。我會建議兩個選項。

選項1 使用JSON - 序列化對象到JSON字符串,並做的結果手動文本搜索。你會爲此需要json.jar(或任何其他解析器)。

try { 
     System.out.println(new JSONObject(new YourHugeObject()).toString(5)); 
    } catch (JSONException e) { 
     log(e); 
    } 

這將產生這樣的事情。 (我已經創造了一些嵌套字段,列表,地圖對象模擬這一點)

{ 
"ct": { 
     "a": 1, 
     "b": "sdf", 
     "f": 12, 
     "nested": { 
      "key1": { 
       "kk": "kk", 
       "ssdf": 123 
      }, 
      "onemorekey": { 
       "kk": "kk", 
       "ssdf": 123 
      } 
     } 
}, 
"doubleProp": 12.2, 
"lngprop": 1232323, 
"strProp": "123", 
"stringlist": [ 
     "String1", 
     "String2", 
     "String3" 
] 
} 

1選項 轉換/序列化對象到XML 。爲此,使用XStream,這將是所有可用解析器中最簡單的。只需兩行代碼,

XStream stream = new XStream(); 
    System.out.println(stream.toXML(new YourHugeObject())); 

將生產,

<com.kmg.jsontools.test.JSTest> 
<stringlist> 
<string>String1</string> 
<string>String2</string> 
<string>String3</string> 
</stringlist> 
<strProp>123</strProp> 
<doubleProp>12.2</doubleProp> 
<lngprop>1232323</lngprop> 
<ct> 
<a>1</a> 
<b>sdf</b> 
<f>12.0</f> 
<nested> 
    <entry> 
    <string>key1</string> 
    <com.kmg.jsontools.test.Type1> 
     <kk>kk</kk> 
     <ssdf>123</ssdf> 
    </com.kmg.jsontools.test.Type1> 
    </entry> 
    <entry> 
    <string>onemorekey</string> 
    <com.kmg.jsontools.test.Type1> 
     <kk>kk</kk> 
     <ssdf>123</ssdf> 
    </com.kmg.jsontools.test.Type1> 
    </entry> 
</nested> 
</ct> 
</com.kmg.jsontools.test.JSTest> 

無論是上述兩種方法,你可以打印結果到控制檯或文件,並手動檢查它。 或者,您也可以使用反射,在這種情況下,您必須編寫大量代碼和大量時間來測試它。

0

一些技巧 -

1)您可以使用移動和點擊變量/方法/類,這將帶來你對它正確。

2)右鍵單擊 - 打開呼叫層次結構將顯示您確切地調用變量的位置。

3)命令和O會告訴你德班的輪廓讓你可以快速瀏覽

4)快速型Hierchy會告訴你如何/在哪裏你的變量在課堂上坐着的宏偉計劃。

希望幫助

0

它常常有助於打印出一個大對象的值,這樣你就可以查看他們仔細。在Java和C++中,我編寫了函數來打印對象的所有內容,以及用於處理嵌入對象的遞歸。調試對象變量的硬拷貝是舊式的,但對於非常複雜的情況,它會導致更多的發現。

+0

'它通常有助於打印出一個大對象的值,以便您可以仔細查看它們這就是我之後 – ant 2010-08-10 14:45:43

1

如果該類是可序列化的,我經常使用XStream將對象轉儲到xml。

如果不是,這裏有一些代碼可能讓你開始使用反射模式。它不像你需要的遞歸,但可以很容易地修改。

public static void debugPrint(Object o1) 
{ 
    if(o1 == null) 
    { 
     System.out.println(o1); 
     return; 
    } 

    Class c = o1.getClass(); 
    do 
    { 
     printFields(c, o1); 
     c = c.getSuperclass(); 
    } 
    while(c != null); 
} 

private static void printFields(Class c, Object o1) 
{ 
    Field[] fields = c.getDeclaredFields(); 
    for(Field field : fields) 
    { 
     printField(field, o1); 
    } 
} 

private static void printField(Field field, Object o1) 
{ 
    try 
    { 
     if(Modifier.isFinal(field.getModifiers())) return; //Skip this guy, he's trouble! 

     field.setAccessible(true); 

     Object val = field.get(o1); 

     System.out.println(field.getName() + ":" + toString(val)); 
    } 
    catch(IllegalAccessException ex) 
    { 
     System.out.println("Could not access field" + field.getName()); 
     ex.printStackTrace(); 
    } 
} 

private static String toString(Object o) 
{ 
    if(o instanceof Object[]) 
     return Arrays.toString((Object[])o); 
    else 
     return String.valueOf(o); 
} 
+0

好的解決方案太糟糕了,它不能正常工作 – ant 2010-08-13 12:45:02

2

創建一些靜態方法,假設:

Map<String, Object> DebugHelper.breakDown(Object bean) 

並執行它(例如)作爲數據挖掘。 org.apache.pivot.beans.BeanAdapter的用法 - 例如可以幫助您將bean視爲普通Map,或者(如您所寫 - 您需要深入挖掘)使用遞歸將所有屬性分組爲單個大Map

另一個有用的簽名:

Map<String, Object> DebugHelper.breakDown(Object bean, String lookFor) 

其中用於從地圖第一種方法的發現價值的子串第二個參數。

這對您有幫助嗎?因爲您可以使用eclipse的檢查器在任何時間調試時計算此方法的結果

+0

請問您可以舉出您所指的靜態方法的示例我不明白你的意思,大多數情況下 – ant 2010-09-17 07:52:18

+0

@ c0mrade在這裏它是:http://ideone.com/BjygK放置到DebugHelper.breakDown(someInstance,「3.14」) - 你可以找到bean的屬性用遞歸挖掘(例如)返回Pi的值。您可以根據需要更改採礦政策。注意,它使用Apache的通用bean實用程序 – Dewfy 2010-09-17 12:00:26

4

如何使用Jakarta-Commons的ToStringBuilder org.apache.commons.lang.builder package

System.out.println (ToStringBuilder.reflectionToString(YOUR_OBJECT)); 
1

我認爲你需要使用反射來獲取數據。下面是一些代碼,應該讓你開始:

static String search(Object o, final String search) { 
    try { 
     inspect(new HashSet<Object>(), o, new StringWriter() { 
      public void write(String s) { 
       System.out.println(s); 
       if (s.indexOf(search) >= 0) { 
        throw new RuntimeException(s) { 
         public Throwable fillInStackTrace() { return null; } }; 
       } 
      } 
     }); 
     return "not found"; 
    } catch (Exception e) { 
     return e.getMessage(); 
    } 
} 

private static void inspect(HashSet<Object> ignore, Object o, Writer w) 
     throws Exception { 
    if (o == null) { 
     return; 
    } 
    for (Class<?> c = o.getClass(); c != null ; c = c.getSuperclass()) { 
     if (c.isArray()) { 
      int len = Array.getLength(o); 
      for (int i=0; i<len; i++) { 
       inspect(ignore, Array.get(o, i), w); 
      } 
     } else if (c.isPrimitive()) { 
      w.write(o.toString()); 
     } else { 
      for (Field f : c.getDeclaredFields()) { 
       if (!Modifier.isStatic(f.getModifiers())) { 
        f.setAccessible(true); 
        if (f.getType().isPrimitive()) { 
         w.write(f.getName() + ": " + f.get(o)); 
        } else { 
         if (!ignore.contains(o)) { 
          ignore.add(o); 
          w.write(f.getName()); 
          inspect(ignore, f.get(o), w); 
         } 
        } 
       } 
      } 
     } 
    } 
} 
-1

以及如果複雜的對象是像字符串,列表,地圖,這樣的java對象組成, 可以通過反射在它們之間迭代,當你發現「對象」你看到的是一個字符串或INT(並且這樣的)調用的toString

如果你的出發對象包含一個「自定義」對象

0

也許完全不同的方法這不會工作。嘗試將對象(分解後)放入內存數據存儲區(請參閱http://www.google.de/search?hl=en&q=java+inmemory+data+store+search),並使用其搜索功能。進行測試後,您應該會感覺到它在您的情況下表現更好。如果您仔細閱讀對象,那麼使用內存數據庫可能會更好。

0

聲明:該代碼是蠻力和非常醜陋的。我只是想證明做什麼OP希望與這些基本理念的可能性:

  1. 反思
  2. 遞歸
  3. Field#setAccessible
  4. 特殊情況的陣列,IterableEnumeration,原始包裝類和String

@Thomas Mueller's answer具有這些元素,但我的#3和#4略強。而他的代碼似乎不適用於我的彎曲測試課程。但我可能仍然錯過了一些角落案例。請不要發送給我的Java導師。

import java.lang.reflect.Array; 
import java.lang.reflect.Field; 
import java.security.AccessController; 
import java.security.PrivilegedAction; 
import java.util.*; 

public class BreakDown 
{ 
    public static void main(String[] args) 
    { 
     printFields(new TestClass(), ""); 
    } 

    private static void printFields(final Object obj, final String prefix) 
    { 
     if(basics.contains(obj.getClass())) 
     { 
      System.out.println(prefix + obj); 
      return; 
     } 
     for(final Field f : obj.getClass().getDeclaredFields()) 
     { 
      try 
      { 
       try 
       { 
        printOneField(f, obj, prefix); 
        continue; 
       } 
       catch(SecurityException e) {} 
       catch(IllegalAccessException e) {} 
       AccessController.doPrivileged(new PrivilegedAction<Void>() 
       { 
        public Void run() 
        { 
         try 
         { 
          printOneField(f, obj, prefix); 
         } 
         catch(Exception e) 
         { 
          e.printStackTrace(); 
         } 
         return null; 
        } 
       }); 
      } 
      catch(Exception e) 
      { 
       e.printStackTrace(); 
      } 
     } 
    } 

    private static void printOneField(Field f, Object obj, String prefix) throws Exception 
    { 
     f.setAccessible(true); 
     System.out.println(prefix + " |" + f.getName() + ":" + (obj = f.get(obj))); 
     if(obj == null) 
      return; 

     if(obj.getClass().isArray()) 
     { 
      for(int i = 0; i < Array.getLength(obj); ++i) 
       printObj(Array.get(obj, i), prefix, f.getName()); 
     } 
     else if(obj instanceof Iterable) 
     { 
      Iterator<?> it = ((Iterable<?>)obj).iterator(); 
      for(; it.hasNext();) 
       printObj(it.next(), prefix, f.getName()); 
     } 
     else if(obj instanceof Enumeration<?>) 
     { 
      Enumeration<?> e = (Enumeration<?>)obj; 
      for(; e.hasMoreElements();) 
       printObj(e.nextElement(), prefix, f.getName()); 
     } 
     else if(!basics.contains(obj.getClass())) 
      printFields(obj, prefix + " |" + f.getName() + ":" + obj.getClass().getCanonicalName()); 
    } 

    private static void printObj(Object o, String prefix, String name) 
    { 
     printFields(o, " " + prefix + " |" + name + ":[(" + o.getClass().getSimpleName() + ")"); 
    } 

    private static final Set<Class<?>> basics = new HashSet<Class<?>>(); 
    static 
    { 
     basics.add(Integer.class); 
     basics.add(Long.class); 
     basics.add(Double.class); 
     basics.add(Float.class); 
     basics.add(Boolean.class); 
     basics.add(Character.class); 
     basics.add(Byte.class); 
     basics.add(Void.class); 
     basics.add(Short.class); 
     basics.add(String.class); 
    } 
} 

class TestClass 
{ 
    public TestClass() 
    { 
     if(++count_s < 3) 
      list.add(new TestClass()); 
    } 

    private static int count_s = 0; 
    public final String a = "a"; 
    final TestClass2 obj = new TestClass2(); 
    final TestClass2[] objArray = new TestClass2[]{new TestClass2(), new TestClass2()}; 
    private final int b = count_s; 
    private final boolean[] c = new boolean[]{true, false}; 
    private final List<TestClass> list = new ArrayList<TestClass>(); 
} 

class TestClass2 
{ 
    private static int count_s = 0; 
    private final float d = 1.5f * (++count_s); 
} 

輸出是:

|count_s:3 
    |a:a 
    |obj:[email protected] 
    |obj:TestClass2 |count_s:9 
    |obj:TestClass2 |d:1.5 
    |objArray:[LTestClass2;@5483cd 
    |objArray:[(TestClass2) |count_s:9 
    |objArray:[(TestClass2) |d:3.0 
    |objArray:[(TestClass2) |count_s:9 
    |objArray:[(TestClass2) |d:4.5 
    |b:0 
    |c:[[email protected] 
    |c:[(Boolean)true 
    |c:[(Boolean)false 
    |list:[[email protected]] 
    |list:[(TestClass) |count_s:3 
    |list:[(TestClass) |a:a 
    |list:[(TestClass) |obj:[email protected] 
    |list:[(TestClass) |obj:TestClass2 |count_s:9 
    |list:[(TestClass) |obj:TestClass2 |d:6.0 
    |list:[(TestClass) |objArray:[LTestClass2;@1186fab 
     |list:[(TestClass) |objArray:[(TestClass2) |count_s:9 
     |list:[(TestClass) |objArray:[(TestClass2) |d:7.5 
     |list:[(TestClass) |objArray:[(TestClass2) |count_s:9 
     |list:[(TestClass) |objArray:[(TestClass2) |d:9.0 
    |list:[(TestClass) |b:1 
    |list:[(TestClass) |c:[[email protected] 
     |list:[(TestClass) |c:[(Boolean)true 
     |list:[(TestClass) |c:[(Boolean)false 
    |list:[(TestClass) |list:[[email protected]] 
     |list:[(TestClass) |list:[(TestClass) |count_s:3 
     |list:[(TestClass) |list:[(TestClass) |a:a 
     |list:[(TestClass) |list:[(TestClass) |obj:[email protected] 
     |list:[(TestClass) |list:[(TestClass) |obj:TestClass2 |count_s:9 
     |list:[(TestClass) |list:[(TestClass) |obj:TestClass2 |d:10.5 
     |list:[(TestClass) |list:[(TestClass) |objArray:[LTestClass2;@c2ea3f 
     |list:[(TestClass) |list:[(TestClass) |objArray:[(TestClass2) |count_s:9 
     |list:[(TestClass) |list:[(TestClass) |objArray:[(TestClass2) |d:12.0 
     |list:[(TestClass) |list:[(TestClass) |objArray:[(TestClass2) |count_s:9 
     |list:[(TestClass) |list:[(TestClass) |objArray:[(TestClass2) |d:13.5 
     |list:[(TestClass) |list:[(TestClass) |b:2 
     |list:[(TestClass) |list:[(TestClass) |c:[[email protected] 
     |list:[(TestClass) |list:[(TestClass) |c:[(Boolean)true 
     |list:[(TestClass) |list:[(TestClass) |c:[(Boolean)false 
     |list:[(TestClass) |list:[(TestClass) |list:[]