无法访问由兄弟 class 实例化的 Object 引用

Cannot access an Object Reference instantiated by a sibling class

我有一个摘要 class,它声明了一些 object 引用,特别是 JLabel。我有两个 class 都扩展了 class。 children 之一实例化了 JLabel 并调用了它的几个方法。 classes sibling 试图调用 JLabel 上的 setText 方法,我得到一个 NullPointerException(实例化它的兄弟在另一个之前被调用。)

我原以为所有 children 都在内存中引用相同的 object,因此会修改相同的 object 但显然我错了。我该如何解决这个问题?

这是我的意思的一个例子:

public class BlahDriver 
{
    public static void main(String[] args) 
    {
        BlahChildOne blah = new BlahChildOne();
        BlahChildTwo blah2 = new BlahChildTwo();
    }
}
public abstract class Blah 
{
    protected JLabel label;
}
public class BlahChildOne extends Blah
{
    public BlahChildOne()
    {
        label = new JLabel();
    }
}
public class BlahChildTwo extends Blah
{
    public BlahChildTwo()
    {
        label.setText("Fred");
    }
}

我在尝试设置文本时在 BlahChildTwo 收到 NullPointerException。

所有child人都指的是同一个object。每个 child object 都将是一个新的 object,它将拥有自己在 parent 中声明的所有引用的副本以及在其自身中声明的所有引用的副本。

如果您想在 class 之间访问相同的引用,请尝试在 parent class.

中将其设为 static

朋友,你一定是object oriented programming的新手。

A class 是对象的模板。当您实例化一个 class(即 new Child())时,会在堆上分配内存以存储该对象的实例变量。该内存包含对象的变量,仅供该对象使用。每次创建对象时,它在单独的内存中都有自己的实例变量 space.

所以,blah 定义了一个名为 label 的实例字段,但没有初始化它

public abstract class Blah 
{
    protected JLabel label;
}

BlahChildOneBlah

初始化 label
public class BlahChildOne extends Blah
{
    public BlahChildOne()
    {
        label = new JLabel();
    }
}

BlahChildTwo 没有从 Blah 初始化 label,所以它仍然是 null...

public class BlahChildTwo extends Blah
{
    public BlahChildTwo()
    {
        label.setText("Fred");
    }
}

BlahChildOneBlahChildTwo 之间都不共享信息(它们通过继承 Blah 具有共性,但实际上信息是各自拥有的)。

把它想象成同卵双胞胎,他们可能有共同点,但仅仅因为一个生病了,并不意味着另一个会生病,他们是他们自己的独立实例。

如果您想在 class 之间共享信息,您应该考虑提供对 class 的引用以及您想要共享的信息,例如...

public class BlahChildTwo extends Blah
{
    public BlahChildTwo(Blah blah)
    {
        label = blah.label;
        label.setText("Fred");
    }
}

但我真的很想看到一个如此极端的用例...

为什么 static 被认为 不好

让我们假设...

public abstract class Blah 
{
    protected static JLabel label;
}

现在在您的代码中,您可以执行类似...

BlahChildOne bco = new BlahChildOne();
add(bco.label); // It the label to the screen...
BlahChildTwo bct = new BlahChildTwo();

好的,到目前为止,还不错。现在想象一下,在您的代码的其他地方,您做...

BlahChildOne bco = new BlahChildOne();
BlahChildTwo bct = new BlahChildTwo();

...可是为什么画面还没有更新呢?因为 Blah#label 不再指向您之前添加到屏幕的 JLabel,所以您丢失了该引用。

这在调试器中很难找到,即使您知道自己在寻找什么,因为没有责任,任何扩展 Blah 的 class 都可以创建 JLabel 并将其分配给 label.

这一行protected JLabel label;并没有创建对象,它只是引用变量,所以当两者class extends Abstract class。两者 Class 都有自己独立的引用变量副本

BlahChildTwo 有自己的 JLabel 引用变量副本,该变量未实例化,这就是您面临 NullPointerException

的原因

现在回答你的问题

I had thought that all children refer to the same object in memory and would thus modify the same object but apparently I'm wrong. How can I get around this?

是的,如果是 object 不是 Reference Variable

,所有子项都会引用同一个对象