Adding buttons with a void method

2019-07-18 03:32发布

问题:

I'm quite new to the programming circuit and I'm trying to learn Java systematically ending up at Swing for the moment. I think I get what void methods do and are used for but I can't wrap my head around this piece of example code (extracted from 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();

}
}

Why does this piece of code work, resulting in a window with 1 button (I expected this to result in just an empty window). Isn't frame.getContentPane() given as argument copied to addComponentsToPane() and destroyed as this void method ends (not added to frame)? Why shouldn't it return a Container object or JPanel object that then can be added to the frame (i.e. frame.add()).

(Question edited. The pivot keyword was void, not static. I see I've been taught this concept (void methods) with primitive types which confuses the matter)

回答1:

The object is passed by reference and isn't copied. Java passes objects by reference rather than by value, as you may be used to in languages like C. So what you're passing with addComponentsToPane(frame.getContentPane()); is the actual reference to the content pane of the frame.

The static method then uses that reference to add a button to the actual content pane. Objects aren't copied for good reason. Imagine creating a class that contains huge arrays of data, for instance. It wouldn't make sense to copy this class every time you pass it to function.

There is an exception to this, in the case of 'primitive' types in Java, such as 'int' or 'double'. Those are treated the same way as you might've learned in C/C++. Keep in mind that Integer and Double are classes, however.

Hope that helps!



回答2:

I think you are looking for pass-by-value stuff of java. Look at this article and you might understand the stuff behind what is happening in your code and why it is not working as per your expectation.



回答3:

Just to clarify @tzhechev, that Objects are not passed by reference in Java instead, Object references are passed by value in Java, which is very much stated by Abu in the answer. To clarify the topic a bit more, watch this example.

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("****************************************");
    }
}

OUTPUT Case 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
****************************************

Though if I use only one Object and modify it's contents in some method, then the outcome will be surprising. Try the code that follows for that surprise :

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("****************************************");
    }
}

OUTPUT Case 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
****************************************