【问题标题】:Adding buttons with a void method使用 void 方法添加按钮
【发布时间】:2012-11-03 12:15:11
【问题描述】:

我对编程电路很陌生,并且我正在尝试系统地学习 Java,目前最终在 Swing 结束。我想我知道 void 方法的作用和用途,但我无法理解这段示例代码(摘自http://docs.oracle.com --BorderLayoutDemo):

public class BorderLayoutDemo {

public static void addComponentsToPane(Container pane) {

    JButton button = new JButton("Button 1 (PAGE_START)");
    pane.add(button, BorderLayout.PAGE_START);

}

private static void createAndShowGUI() {

    JFrame frame = new JFrame("BorderLayoutDemo");
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    **addComponentsToPane(frame.getContentPane());**
    frame.pack();
    frame.setVisible(true);
}

public static void main(String[] args) {
   createAndShowGUI();

}
}

为什么这段代码可以工作,导致一个带有 1 个按钮的窗口(我预计这只会导致一个空窗口)。是否将 frame.getContentPane() 作为参数复制到 addComponentsToPane() 并在此 void 方法结束时销毁(未添加到框架)?为什么它不应该返回一个 Container 对象或 JPanel 对象,然后可以将其添加到框架中(即 frame.add())。

(已编辑问题。pivot 关键字是无效的,而不是静态的。我看到我已经用原始类型教授了这个概念(无效方法),这使问题变得混乱)

【问题讨论】:

  • 没有人理解你为什么认为它行不通。这不是很好的代码,但每个语句都非常清楚它的作用。 addComponentsToFrame 将组件添加到您在参数中提供的内容框架。一旦它们被添加,框架就会被打包并显示(setVisible)。非常简单。
  • 但我确实理解为什么 Stegeman 认为它行不通;这个问题也很清楚他认为会发生什么,并且很容易解释哪些假设是错误的。他得到的答案解决了他明确的问题,你说“没人理解”是不正确的。
  • 我尝试稍微压缩代码以保持问题简短并显示相关陈述。 Tzhechev 先生确实了解我。 (忍者)

标签: java swing static add


【解决方案1】:

对象是通过引用传递的,不会被复制。 Java 通过引用而不是通过值传递对象,正如您在 C 等语言中可能习惯的那样。因此,您使用 addComponentsToPane(frame.getContentPane()); 传递的是对框架内容窗格的实际引用。

然后静态方法使用该引用将按钮添加到实际内容窗格。没有充分的理由复制对象。例如,想象一下创建一个包含大量数据的类。每次将它传递给函数时都复制这个类是没有意义的。

这有一个例外,在 Java 中的“原始”类型的情况下,例如“int”或“double”。它们的处理方式与您在 C/C++ 中学习的方式相同。但是请记住,Integer 和 Double 是类。

希望有帮助!

【讨论】:

  • 谢谢!我试图用 int 来获得这种行为。这让我很困惑。
  • 恕我直言,你说 Objexts 在 Java 中通过引用传递是完全错误的。取而代之的是,对象引用在 Java 中是按值传递的,最好清楚地阅读或提出问题,以便人们可以就该主题以正确的方式回答您。 -1 从我这边来看只是因为你在 Java 中说的对象是通过引用传递的,但事实并非如此。对象永远不会通过引用传递,就像您可以在 C 中那样。我很惊讶有人如何在这件事上投票给您。
  • 我不觉得进入那个特殊的区别会有助于澄清最初的问题。是的,你是正确的,对象不是以与 C 相同的意义通过引用传递的,我从未说过你不能在 C 中这样做。我没有进入细节,因为这个问题不值得,不是因为我需要更清楚地阅读。
  • 查看我发布的答案,运行该示例并亲自查看。你不能说Java中的对象是通过引用传递的。尽管当您将单个对象传递给函数时,它会给您一种错觉,即对象是通过引用传递的,而在 Java 中,对象引用是通过值传递的。因为如果它们是通过引用传递的,那么对象的原始状态也会在 main 方法中发生变化,就像它们在 swap 方法中发生的那样,这从未发生过。
  • 您说对象引用是按值传递是正确的。你说对象不会在 main 方法中改变是不正确的。通过引用传递的对象和通过引用值传递的对象之间的区别经常被忽视,因为它通常是微不足道的。示例:modify(SomeObj x) { x = new SomeObj; } // X is not modified in mainmodify(SomeObj x) { x.stringMember = "a new string!"; } // X's stringMember IS modified
【解决方案2】:

我认为您正在寻找 java 的按值传递的东西。看看这个article,您可能会了解代码中发生的事情背后的内容以及为什么它没有按照您的预期工作。

【讨论】:

    【解决方案3】:

    只是为了澄清@tzhechev,对象在Java中不是通过引用传递的,对象引用在Java中是通过值传递的,Abu在答案中非常清楚地说明了这一点。为了更清楚地说明这个话题,请看这个例子。

    class Employee
    {
        String name;
        int age;
    }
    
    public class ValueOrReference
    {
        public static void main(String... args)
        {
            Employee emp1 = new Employee();
            emp1.name = "Myself";
            emp1.age = 1;
            Employee emp2 = new Employee();
            emp2.name = "Yourself";
            emp2.age = 2;
            System.out.println("Before swapping values are : ");
            System.out.println("Employee 1 : ");
            System.out.println("Name : " + emp1.name);
            System.out.println("Age : " + emp1.age);
            System.out.println("Employee 2 : ");
            System.out.println("Name : " + emp2.name);
            System.out.println("Age : " + emp2.age);
            /*
             * Now if Objects are passed by Reference
             * then if I swap the two objects in a method, 
             * then the actual objects will reciprocate
             * to the said change. Lets find out.
             */
            swapObjects(emp1, emp2); 
            System.out.println("****************************************");
            System.out.println("Inside main after swap method.");
            System.out.println("After swapping values are : ");
            System.out.println("Employee 1 : ");
            System.out.println("Name : " + emp1.name);
            System.out.println("Age : " + emp1.age);
            System.out.println("Employee 2 : ");
            System.out.println("Name : " + emp2.name);
            System.out.println("Age : " + emp2.age);
            System.out.println("****************************************");
        }
    
        private static void swapObjects(Employee emp1, Employee emp2)
        {
            System.out.println("****************************************");
            System.out.println("Inside the swap method.");
            Employee temp = emp1;
            emp1 = emp2;
            emp2 = temp;
            System.out.println("After swapping values are : ");
            System.out.println("Employee 1 : ");
            System.out.println("Name : " + emp1.name);
            System.out.println("Age : " + emp1.age);
            System.out.println("Employee 2 : ");
            System.out.println("Name : " + emp2.name);
            System.out.println("Age : " + emp2.age);
            System.out.println("****************************************");
        }
    }
    

    输出案例1:

    C:\Mine\JAVA\J2SE\classes>java ValueOrReference
    Before swapping values are :
    Employee 1 :
    Name : Myself
    Age : 1
    Employee 2 :
    Name : Yourself
    Age : 2
    ****************************************
    Inside the swap method.
    After swapping values are :
    Employee 1 :
    Name : Yourself
    Age : 2
    Employee 2 :
    Name : Myself
    Age : 1
    ****************************************
    ****************************************
    Inside main after swap method.
    After swapping values are :
    Employee 1 :
    Name : Myself
    Age : 1
    Employee 2 :
    Name : Yourself
    Age : 2
    ****************************************
    

    虽然如果我只使用一个对象并以某种方法修改它的内容,那么结果会令人惊讶。试试下面的代码以获得惊喜:

    class Employee
    {
        String name;
        int age;
    }
    
    public class ValueOrReference
    {
        public static void main(String... args)
        {
            Employee emp1 = new Employee();
            emp1.name = "Myself";
            emp1.age = 1;
            System.out.println("Before swapping values are : ");
            System.out.println("Employee 1 : ");
            System.out.println("Name : " + emp1.name);
            System.out.println("Age : " + emp1.age);
            /*
             * Now if Objects are passed by Reference
             * then if I swap the two objects in a method, 
             * then the actual objects will reciprocate
             * to the said change. Lets find out.
             */
            modifyObject(emp1); 
            System.out.println("****************************************");
            System.out.println("Inside main after modify method.");
            System.out.println("After modifying values are : ");
            System.out.println("Employee 1 : ");
            System.out.println("Name : " + emp1.name);
            System.out.println("Age : " + emp1.age);
            System.out.println("****************************************");
        }
    
        private static void modifyObject(Employee emp1)
        {
            System.out.println("****************************************");
            System.out.println("Inside the modify method.");
            emp1.name = "Yourself";
            emp1.age = 2;
            System.out.println("After modifying values are : ");
            System.out.println("Employee 1 : ");
            System.out.println("Name : " + emp1.name);
            System.out.println("Age : " + emp1.age);
            System.out.println("****************************************");
        }
    }
    

    输出案例 2:

    C:\Mine\JAVA\J2SE\classes>java ValueOrReference
    Before swapping values are :
    Employee 1 :
    Name : Myself
    Age : 1
    ****************************************
    Inside the modify method.
    After modifying values are :
    Employee 1 :
    Name : Yourself
    Age : 2
    ****************************************
    ****************************************
    Inside main after modify method.
    After modifying values are :
    Employee 1 :
    Name : Yourself
    Age : 2
    ****************************************
    

    【讨论】:

    • 感谢您澄清这一点。我阅读了 Abu 发表的文章,该文章很好地以图形方式解释了这一原理。因此,如果我得到了这个正确的值,它会按值传递引用,除非在原始类型的情况下,在创建新引用的同时复制对象本身?再次感谢所有答案,并帮助我进行基本的理解!很棒的社区。​​span>
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-17
    • 1970-01-01
    • 2020-07-15
    • 1970-01-01
    • 2015-05-11
    相关资源
    最近更新 更多