代码之家  ›  专栏  ›  技术社区  ›  JR Lawhorne

Java向量字段(私有成员)累加器不存储我的奶牛!

  •  1
  • JR Lawhorne  · 技术社区  · 16 年前

    编辑:这段代码很好。我在伪代码中不存在的某个地方发现了一个逻辑错误。我把它归咎于我缺乏Java经验。

    在the 伪代码 下面,我试图解析所示的XML。也许这是一个愚蠢的例子,但我的代码太大/太具体,任何人都无法从看到它和从发布的答案中学习到任何真正的价值。所以,这更有趣,希望其他人和我一样能从这个答案中学习。

    我是Java新手,但也是一名经验丰富的C++程序员,这让我相信我的问题在于我对Java语言的理解。

    问题:当解析器完成时,我的Vector中充满了未初始化的奶牛。我创建了具有默认容量的奶牛向量(如果它像C++STL向量一样,它不应该影响它的“大小”)。当我在解析后打印出奶牛矢量的内容时,它给出了正确大小的矢量,但所有值似乎从未设置过。

    信息:我已经成功地用其他没有Vector的解析器完成了这项工作 但在这种情况下,我想使用Vector来累积Cow属性。

    更多信息:我不能使用泛型(Vector<Cow>),所以请不要指向我。 :)

    提前感谢。

    <pluralcow>
            <cow>
                <color>black</color>
                <age>1</age>
            </cow>
            <cow>
                <color>brown</color>
                <age>2</age>
            </cow>
            <cow>
                <color>blue</color>
                <age>3</age>
            </cow>
    </pluralcow>
    
    public class Handler extends DefaultHandler{
        // vector to store all the cow knowledge
        private Vector  m_CowVec;
    
        // temp variable to store cow knowledge until
        // we're ready to add it to the vector
        private Cow     m_WorkingCow;
    
        // flags to indicate when to look at char data
        private boolean m_bColor;
        private boolean m_bAge;
    
        public void startElement(...tag...)
        {
            if(tag == pluralcow){   // rule: there is only 1 pluralcow tag in the doc
                    // I happen to magically know how many cows there are here.             
                    m_CowVec = new Vector(numcows);
            }else if(tag == cow ){  // rule: multiple cow tags exist
                m_WorkingCow = new Cow();
            }else if(tag == color){ // rule: single color within cow
                m_bColor = true;
            }else if(tag == age){   // rule: single age within cow
                m_bAge = true;
            }
        }
    
        public void characters(...chars...)
        {
            if(m_bColor){
                m_WorkingCow.setColor(chars);   
            }else if(m_bAge){
                m_WorkingCow.setAge(chars);
            }
        }
    
        public void endElement(...tag...)
        {
            if(tag == pluralcow){
                // that's all the cows
            }else if(tag == cow ){
                m_CowVec.addElement(m_WorkingCow);      
            }else if(tag == color){
                m_bColor = false;
            }else if(tag == age){
                m_bAge = false;
            }
        }
    }
    
    4 回复  |  直到 16 年前
        1
  •  1
  •   Enamul Hassan    10 年前

    当你说奶牛未初始化时,字符串属性是否初始化为null?还是空字符串?

    我知道你提到这是伪代码,但我只是想指出一些潜在的问题:

    public void startElement(...tag...)
        {
            if(tag == pluralcow){   // rule: there is only 1 pluralcow tag in the doc
                    // I happen to magically know how many cows there are here.                     
                    m_CowVec = new Vector(numcows);
            }else if(tag == cow ){  // rule: multiple cow tags exist
                    m_WorkingCow = new Cow();
            }else if(tag == color){ // rule: single color within cow
                    m_bColor = true;
            }else if(tag == age){   // rule: single age within cow
                    m_bAge = true;
            }
        }
    

    你真的应该使用tag.equals(…)而不是tag==。..在这里。

    public void characters(...chars...)
    {
        if(m_bColor){
                m_WorkingCow.setColor(chars);   
        }else if(m_bAge){
                m_WorkingCow.setAge(chars);
        }
    }
    

    我假设您知道这一点,但实际上,此方法是使用具有开始和结束索引的字符缓冲区调用的。

    还要注意,单个文本块可以多次调用字符(…),每次调用都会返回小块: http://java.sun.com/j2se/1.4.2/docs/api/org/xml/sax/ContentHandler.html#characters(char[],%20int,%20int)

    “…SAX解析器可能会返回所有连续的 单个块中的字符数据,或 他们可能会把它分成几个块。.."

    我怀疑你在提供的简单示例中不会遇到这个问题,但你也提到这是一个更复杂问题的简化版本。如果在最初的问题中,XML由大文本块组成,这是需要考虑的。

    最后,正如其他人所提到的,如果可以的话,最好考虑使用XML编组库(例如,JAXB、Castor、JIBX、XMLBeans、XStream等)。

        2
  •  3
  •   Jack Leow    16 年前

    在我看来,这段代码很好。我说在每个函数的开头设置断点,并在调试器中观察它,或者添加一些打印语句。我的直觉告诉我 characters() 未被呼叫或 setColor() setAge() 不正确,但这只是猜测。

        3
  •  0
  •   Uri    16 年前

    我不得不说,我不太喜欢这种设计。 然而,你确定你的角色曾经被召唤过吗?(也许一些system.outs会有所帮助)。如果它从未被调用,你最终会得到一头未初始化的奶牛。

    此外,我不会尝试自己实现这样的XML解析器,因为您需要对验证问题更加健壮。

    您可以使用SAX或DOM4J,或者更好的是使用Apache消化器。

        4
  •  0
  •   javelinBCD    16 年前

    此外,如果我有一个模式,我将使用JaxB或其他代码生成器来加速XML接口代码的开发。代码生成器隐藏了直接使用SAX或DOM4J的许多复杂性。