当Java将它们添加到Swing组件时,Java在哪里复制和存储对象?

时间:2013-06-24 15:54:38

标签: java swing jcomponent

总体问题是 - 当Java存储组件(按钮,菜单项等)添加到JFrame,JPanel,JMenu之类的对象时,它们会在哪里对象?在浏览文档的过程中,我看到了一些内容,说它们存储在列表中,但我仍然试图通过挖掘Oracle的文档来找到有关该实现的具体信息。能够理解它的人能帮助我理解吗?

在浏览Oracle的Java教程时,我注意到重复使用单个标识符来创建相同类型的对象。例如,这会创建两个单独的按钮:

JPanel buttonPnale = new JPanel("Making some buttons");
JButton buttonMaker;

buttonMaker = new JButton("Left button", blueBurstIcon);
buttonPanel.add(buttonMaker);

buttonMaker = new JButton("Right button", orangeBurstIcon);
buttonPanel.add(buttonMaker);

通常我认为我需要这样做:

JButton buttonOne = new JButton("Left button", blueBurstIcon);
JButton buttonTwo = new JButton("Right button", orangeBurstIcon);

创建单独的标识符以与每个单独的对象一起使用。

显然,第一段代码中的对象正在某处保存,我只是想找出原因。它必须是当我打电话给.add他们被复制 - 但他们在哪里复制?如果它们被添加到JPanel中,它们是否被复制到JPanel包含的数据结构中?或者是添加了JPanel的JFrame的一部分的数据结构?

5 个答案:

答案 0 :(得分:3)

大多数Swing组件都包含一个子列表。框架有这样的列表,只要您使用按钮调用add(),该按钮就会添加到该列表中。

没有复制。列表中的(未命名)引用和命名引用buttonMaker都指向内存中的同一实例。有些语言将buttonMaker称为“别名”,以强调它实际上不是对象或实例本身,而是一个允许您访问实例的名称。

当您为buttonMaker指定新引用时,这对框架列表中的按钮没有影响。

这也意味着Java总会看到有人(引用buttonMaker或列表)引用按钮,因此它们不会被垃圾回收。

答案 1 :(得分:3)

JPanel继承自java.awt.Container,它维护客户端组件的内部列表(在这种情况下为JButton)。您可以在Container的源代码中找到此列表:

/**
 * The components in this container.
 * @see #add
 * @see #getComponents
 */
private java.util.List<Component> component = new java.util.ArrayList<Component>();

组件由protected void addImpl(...)方法添加,该方法是从public Component add(Component comp)中的Container方法调用的。

所以这都是私人的。你不应该看到这一点。 ; - )

答案 2 :(得分:2)

那么你的问题很好......但是是新手......

C不同,Java没有为您提供遍历C中pointers的基本内存块的功能。但是,这个概念仍然是安全的。

这是因为当我们谈论Multi-Threading时,这样的设施(在java中使用指针)会让内存发生冲突。因此JVM会自动处理。使Java成为thread-safe语言。

除此之外,你在exaple中提出的是......

如何创建两个按钮?

因此,当您详细看到代码时,它遵循树结构,即JPanel位于树的顶部,而您只是将子项添加到树中。所以它跟踪所有子节点。但是,如果你只是写这段代码:

JPanel buttonPnale = new JPanel("Making some buttons");
JButton buttonMaker;

buttonMaker = new JButton("Left button", blueBurstIcon);
buttonMaker = new JButton("Right button", orangeBurstIcon);
buttonPanel.add(buttonMaker);

然后buttonMaker将松开按钮的旧记录。并将添加新创建的按钮。

请记住,它遵循树结构,井指针(内存管理)完全由JVM

完成

答案 3 :(得分:0)

添加第一个 buttonMaker 后,buttonMaker会引用另一个JButton。第一个 buttonPanel.add(..)方法调用对之后设置的buttonMaker变量没有兴趣,因为此变量的范围仅在方法级别。该变量不存在于第二个 buttonPanel.add(..)调用

答案 4 :(得分:0)

使用new创建新的按钮对象。

  

“当我调用.add时,它们必须被复制 - 但它们被复制到哪里?如果它们被添加到JPanel中,它们是否被复制到JPanel包含的数据结构中?”< / em>的

当您将这些按钮添加到任何JPanel时,您只需将按钮的引用添加到JPanel的内部列表中(具体而言,您要添加Container的引用1}} class的component列表,因为JPanelContainer类的子类。以下是add类的Container方法的source code

我想再强调一点,在将组件添加到任何容器时,没有任何关于将对象本身复制到任何地方的信息。它只是添加了对内部列表的引用!