总体问题是 - 当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的一部分的数据结构?
答案 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
列表,因为JPanel
是Container
类的子类。以下是add
类的Container
方法的source code。
我想再强调一点,在将组件添加到任何容器时,没有任何关于将对象本身复制到任何地方的信息。它只是添加了对内部列表的引用!