【问题标题】:Why can a method be called on another method?为什么一个方法可以在另一个方法上调用?
【发布时间】:2012-06-29 17:52:51
【问题描述】:
NodeList nlList = eElement.getElementsByTagName(sTag).item(0).getChildNodes();

我是 JAVA 新手。谁能解释一下上述语句的结构?

我了解可以通过以下方式访问实例的方法:

objectName.methodName();

在上面的语句中,三个方法名与一个对象名相关联。这是如何工作的?

【问题讨论】:

  • eElement是什么类型?
  • 使用 IDE 并通读相关的 Javadoc。 3个方法名不与一个对象名关联,方法与其他方法返回的对象关联。
  • 如果这是一个不好的问题,为什么会有这么多好的答案? :) @Downvoters:请让 rohit 知道他/她可以改进什么。
  • @Mulmoth 如果您查看编辑历史记录,应该清楚这个问题是一团糟。
  • 好的。我知道这是一团糟,但有人可以回答我的问题吗?

标签: java oop object methods


【解决方案1】:
  • eElement.getElementsByTagName 将返回一个对象
  • 然后在该对象上调用.item(0),这将返回另一个对象
  • 在您调用的最后一个对象上.getChildNodes()

确实,一个方法可以通过object.method() 调用,但是如果你有多个这样的调用,你可以像在你的例子中那样链接它们。

只要你不过度使用它,这可以产生更可读的代码,它保持它的紧凑。

【讨论】:

  • 我建议与其说是嵌套不如说是链式
  • @SoboLAN 非常感谢。那是非常全面的。
【解决方案2】:

对eElement.getElementsByTagName(sTag) 的调用会返回一些对象。之后,在这个对象上调用item(0)。等等。也就是说,上面的语句等价于

SomeObject so = eElement.getElementsByTagName(sTag);
OtherObject oo = so.item(0);
NodeList nlList = oo.getChildNodes();

这种技术被称为method chaining,它在使代码更简洁易读方面非常有用——如果不是过度使用的话。

它的一种特殊形式 - 在某些框架中广泛使用,例如Hibernate - 在同一个对象上链接方法调用,例如

SomeObject o = new SomeObject().setFoo(1).setBar("boo").setBaz(42);

这可以说比

更紧凑
SomeObject o = new SomeObject();
o.setFoo(1);
o.setBar("boo");
o.setBaz(42);

如果您没有具有所需参数的构造函数,您肯定需要它。但即使这样的构造函数可用,人们可能会争辩说

SomeObject o = new SomeObject(1, "boo", 42);

的可读性不如方法链接习语。唉,Java(与 C# 不同)在方法调用中没有命名参数。

【讨论】:

  • @SoboLAN,确实,我只是不想一次在 OP 上扔太多新东西 :-)
【解决方案3】:

每个方法都作用于前一个语句的返回值,例如

   obj.getA().getB().getC();

表示你在obj上调用getA()。这将返回一个对象 A,然后您在 结果对象 A 上调用 getB() - 而不是原来的 obj。

类似

   temp1 = obj.getA();
   temp2 = temp1.getB();
   temp3 = temp2.getC();

但没有临时变量。

缺点是调试更加困难,因为您没有中间变量,而且可能更脆弱(例如,如果 getA() 返回 null 然后整个语句会爆炸并且你不能轻易说出在哪里,因为堆栈跟踪只包含行号)。

【讨论】:

    【解决方案4】:

    上述语句按以下步骤执行:

    1) 在 Element 类型的变量 eElement 中 - 获取名称为 sTag 的所有标签。此方法返回一个 NodeList

    2) 在返回的 NodeList 中 - 从列表中获取第一项 (0)。这将返回一个节点。

    3) 在返回的节点上 - 获取它的所有子节点,它返回一个 NodeList 并将其分配给 nlList。

    在方法返回对象的地方,您可以继续对返回的对象调用方法,无论您想走多远。只要结果方法返回您尝试分配的类型的对象。

    【讨论】:

      【解决方案5】:
      1. 名称为“sTag”的所有节点都从 eElement 中检索

        eElement.getElementsByTagName(sTag)

      2. 从中选出第一个

        eElement.getElementsByTagName(sTag).item(0)

      3. 第一个节点的所有子节点现在都在 nlList 中

        NodeList nlList = eElement.getElementsByTagName(sTag).item(0).getChildNodes();

      【讨论】:

      • 嗨,马丁。感谢您的解释。我对此有一个后续查询。如果没有 ChildNode,nlList 中会出现什么??
      • 嗨,根据this,它将是一个空节点列表
      【解决方案6】:

      如果objectName.methodName() 返回一个对象,那么您可以调用该对象的方法,例如objectName.methodName().anotherMethod()。这只是一个简单的方法调用链接。

      【讨论】:

        【解决方案7】:
        objectName.methodName();
        

        也可能返回一个对象引用(只要它的返回类型不是 'void'),所以它确实是:

        objectRef = objectName.methodName();
        

        第二个方法调用在第一个返回的对象上。所以在你的例子中

        eElement.getElementsByTagName(sTag).item(0).getChildNodes();
        

        getElementsByTagName(sTag) 返回一个对象,并在该对象上调用 item(0)。第二个方法调用返回的对象,然后调用了 getChildNodes()。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2021-05-26
          • 1970-01-01
          • 1970-01-01
          • 2015-12-01
          • 1970-01-01
          • 1970-01-01
          • 2023-04-01
          • 1970-01-01
          相关资源
          最近更新 更多