代码之家  ›  专栏  ›  技术社区  ›  ant

java中的细分对象

  •  6
  • ant  · 技术社区  · 14 年前

    有没有一种方法可以创建某种对象细分路由,并在每个部分搜索我期望的值,它隐藏在对象的某个地方,我只是在eclipse中找不到它,因为它太嵌套了。

    我考虑使用反射遍历object类的所有字段,并搜索每个字段(列表中的字段(列表列表等))中的值。还有其他想法吗?

    不幸的是,这些答案都帮不了我,我开始悬赏了

    11 回复  |  直到 14 年前
        1
  •  6
  •   chedine    14 年前

    我假设你只想找到一个特定的值并追踪它的来源。所有这些,你想在调试的时候做。我建议两种选择。

    使用 -将对象序列化为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"
     ]
    }
    

    选项2 将对象转换/序列化为 XML格式 . 使用 X流 为此,这将是所有可用解析器中最简单的。只有两行代码,

        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>
    

    以上任何一种方法,您都可以将结果打印到控制台或打印到文件并手动检查。 或者,您也可以使用反射,在这种情况下,您将不得不编写大量的代码和大量的时间来测试它。

        2
  •  4
  •   Faisal Feroz    14 年前

    org.apache.commons.lang.builder package .

    System.out.println ( ToStringBuilder.reflectionToString( YOUR_OBJECT ) );
    
        3
  •  2
  •   Dewfy    14 年前

    创建一些静态方法,假设:

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

    并将其实现为(例如)数据挖掘。的用法org.apache.pivot.beans.BeanAdapter -例如可以帮助你治疗

    另一个有用的签名:

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

    为什么这样有用?因为您可以在调试的任何时候使用eclipse的inspector来计算这个方法的结果

        4
  •  1
  •   Steve Jackson    14 年前

    如果类是可序列化的,我经常使用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);
    }
    
        5
  •  1
  •   Thomas Mueller    14 年前

    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);
                            }
                        }
                    }
                }
            }
        }
    }
    
        6
  •  0
  •   Steve    14 年前

    一些提示-

    1)您可以使用shift并单击变量/方法/类,这将使您正确地找到它。

    3)命令和O将向您显示类的大纲,以便您可以快速导航

    4)Quick Type Hierchy将向您展示变量在类的总体方案中的位置。

    希望有帮助

        7
  •  0
  •   Michael Shopsin    14 年前

    打印出一个大对象的值通常会有帮助,这样您就可以仔细地查看它们。在java和C++中,我都编写了函数来打印对象的所有内容,以及递归来处理嵌入对象。调试对象变量的硬拷贝是一种古老的方式,但对于非常复杂的情况,它将导致额外的发现。

        8
  •  0
  •   Skarab    14 年前

    http://www.google.de/search?hl=en&q=java+inmemory+data+store+search )而不是使用它的搜索功能。在执行测试后,您应该感觉到它是否在您的情况下表现更好。如果你集中阅读这个对象,也许使用内存数据库会更好。

        10
  •  0
  •   Community kfsone    7 年前

    1. 反射
    2. 递归
    3. Field#setAccessible
    4. 阵列的特殊情况, Iterable , Enumeration ,原始包装类和 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:TestClass2@6e1408
      |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:[Z@19ee1ac
        |c:[(Boolean)true
        |c:[(Boolean)false
      |list:[TestClass@1befab0]
        |list:[(TestClass)  |count_s:3
        |list:[(TestClass)  |a:a
        |list:[(TestClass)  |obj:TestClass2@13c5982
        |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:[Z@14b7453
          |list:[(TestClass)  |c:[(Boolean)true
          |list:[(TestClass)  |c:[(Boolean)false
        |list:[(TestClass)  |list:[TestClass@c21495]
          |list:[(TestClass)  |list:[(TestClass)  |count_s:3
          |list:[(TestClass)  |list:[(TestClass)  |a:a
          |list:[(TestClass)  |list:[(TestClass)  |obj:TestClass2@1d5550d
          |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:[Z@15b7986
            |list:[(TestClass)  |list:[(TestClass)  |c:[(Boolean)true
            |list:[(TestClass)  |list:[(TestClass)  |c:[(Boolean)false
          |list:[(TestClass)  |list:[(TestClass)  |list:[]
    
        11
  •  -1
  •   savo.fra    14 年前

    如果复杂对象是由java对象组成的,比如字符串、列表、映射等等, 您可以通过反射对它们进行迭代,当您发现您正在查看的“对象”是字符串或int(以及类似的)调用toString时