【问题标题】:Why are parenthesis used in the middle of a method call in Java?为什么Java中的方法调用中间要使用括号?
【发布时间】:2014-02-19 14:26:23
【问题描述】:

虽然我进行了一些广泛的搜索,但我遇到了一些代码,但无法理解其中的某个方面!

我的问题是:为什么要在方法调用中间使用括号?

    package com.zetcode;

    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;

    import javax.swing.JButton;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    import javax.swing.SwingUtilities;


    public class QuitButtonExample extends JFrame {

    public QuitButtonExample() {

        initUI();
    }

    private void initUI() {

       JPanel panel = new JPanel();
       getContentPane().add(panel);

       panel.setLayout(null);

       JButton quitButton = new JButton("Quit");
       quitButton.setBounds(50, 60, 80, 30);

       quitButton.addActionListener(new ActionListener() {
           @Override
           public void actionPerformed(ActionEvent event) {
               System.exit(0);
          }
       });

       panel.add(quitButton);

       setTitle("Quit button");
       setSize(300, 200);
       setLocationRelativeTo(null);
       setDefaultCloseOperation(EXIT_ON_CLOSE);
    }

    public static void main(String[] args) {

        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                QuitButtonExample ex = new QuitButtonExample();
                ex.setVisible(true);
            }
        });
    }
}

我指的是getContentPane().add(panel); 声明。我知道它的作用,但并不真正了解它是如何工作的。我是 Java 新手,并且具备 OO 的基础知识,例如类字段、类方法、实例字段、实例方法、内部类,但只有这个。

【问题讨论】:

  • 我相信您正在寻找的答案是:如果一个方法返回一个对象,那么可以从该方法调用该对象的方法。
  • 您可能会理解{ Foo a = getFoo(); a.doSomethingFooish();}。但是不需要存储getFoo()的结果,我们可以直接使用:getFoo().doSomethingFooish()
  • 哦,我明白了。非常感谢您的帮助。

标签: java class methods field instance


【解决方案1】:

这就是称为方法链的常见习语的样子。

getContentPane().add(panel);

解析为

Container c = this.getContentPane();
c.add(panel);

括号表示一个方法调用,它的返回值就地用作下一个方法调用的this 对象(add)。

【讨论】:

    【解决方案2】:

    这称为方法链接。要理解这一点,一个简单的例子会对你有所帮助。

    String a = "hellloo";
    String b = a.toUpperCase().replace("LOO", "O").concat(" WORLD");    
    System.out.println(b);
    

    这将打印 HELLO WORLD。

    记住方法链中的方法是从左到右处理的。

    上面的执行方式为

    1. toUpperCase() - “你好”
    2. replace("LOO", "O") - “你好”
    3. concat(" WORLD") - “你好世界”
    4. 将“HELLO WORLD”分配给字符串 b。

    与上面的代码类似,我们首先获取 ContentPane,然后为其添加一个面板。

    这减少了实现它所需的代码量。

    一般情况下是这样的

    Container container = getContentPane();
    container.getContentPane();
    

    链接将代码减半。

    希望这会有所帮助。

    【讨论】:

    • 方法链,我觉得我对它并不陌生。当我研究“代码”时,它没有意义。现在我知道了,谢谢。
    【解决方案3】:
    getContentPane().add(panel);
    

    getContentPane 方法没有输入参数,所以你必须用空括号调用它才能使 java 编译器满意。之后,您对getContentPane-call 的结果进行add(panel) 调用。

    【讨论】:

      【解决方案4】:

      getContentPane() 是在this 上调用的方法。因为它是一个方法,所以必须使用括号来调用它。

      在 Java 中,this 指的是对象的当前实例,在调用当前类中的方法时可以省略。由于QuitButtonExample 扩展了JFrame 类,它能够调用JFrame 的所有受保护和公共方法。

      所以你可能在你正在处理的类上看不到getContentPane() 方法,但该方法在类层次结构的更深处可用,并且通过与JFrame 的继承关系公开。

      另外,getContentPane() 方法返回一个 Container 类型的对象,我们也可以在其上调用方法。当从一个方法接收到一个对象并立即调用另一个方法(例如getContentPane().add(panel))时,这称为链接。不需要将方法返回的每个对象都存储到变量中,我们可以简单地使用从被调用方法返回的对象,而无需将其分配给存储的变量。

      【讨论】:

        【解决方案5】:

        Java语言规范可能有点形式化,但是作为开发者,你要处理很多形式化的语法,所以我指出相关规则并解释一下:

        method invocation 的语法定义括号是强制性的:

        MethodInvocation:
            MethodName ( ArgumentList? )
            Primary . NonWildTypeArguments? Identifier ( ArgumentList? )
            ...
        

        Primary 表达式可以是MethodInvocation,因此返回对象的方法调用可以被“链接”:

        Primary:
            PrimaryNoNewArray
            ...
        
        PrimaryNoNewArray:
            ...
            MethodInvocation
            ...
        

        【讨论】:

          【解决方案6】:

          getContentPane()JFrame 中的一个方法,它返回一个对象(ContentPane),该对象有一个方法add(),该方法又将JPanel 对象的引用作为其参数。最后很直接。

          由于getContentPane()属于当前对象,代码写成这样会更清晰一些

          this.getContentPane().add(panel);
          

          要跟进此类事情,最好查看 Javadoc。例如 API for JSE7

          【讨论】:

            猜你喜欢
            • 2021-05-23
            • 1970-01-01
            • 2020-08-17
            • 1970-01-01
            • 2021-12-09
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多