3

总的问题是——当 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 的一部分中的数据结构?

4

5 回答 5

3

AJPanel继承自java.awt.Container,它维护客户端组件的内部列表(JButton在这种情况下是您的 s)。您可以在以下源代码中找到此列表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

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

于 2013-06-24T16:35:30.303 回答
3

大多数 Swing 组件都包含一个子级列表。框架有这样一个列表,一旦你add()用按钮调用,按钮就会被添加到所述列表中。

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

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

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

于 2013-06-24T16:04:08.773 回答
2

好吧,您的问题是一个很好的问题..但是是新手..

与 不同的是CJava不为您提供遍历pointersC 中已知的基本内存块的功能。但是,是的,这个概念仍然是安全的。

这是因为当我们谈论 时Multi-Threading,这样的工具(在 java 中使用指针)会导致内存冲突。所以这是由 自动处理的JVM。使Java成为一种thread-safe语言。

除此之外,您在示例中要问的是...

为什么会创建两个按钮?

因此,当您详细查看代码时,它遵循树形结构,即 位于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

于 2013-06-24T16:10:53.487 回答
0

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

于 2013-06-24T16:00:17.187 回答
0

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

“一定是在我调用 .add 时,它们被复制了——但它们被复制到哪里?如果它们被添加到 JPanel,它们是否被复制到 JPanel 包含的数据结构中?”

当您将这些按钮添加到 anyJPanel时,您只是将按钮的引用放入 的JPanel内部 List (具体来说,您正在添加对Containercomponent列表的引用,因为JPanel它是类的子Container类)。这是类方法的源代码addContainer

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

于 2013-06-24T16:32:28.613 回答