无法访问由兄弟 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;
}
BlahChildOne
从 Blah
初始化 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");
}
}
BlahChildOne
和 BlahChildTwo
之间都不共享信息(它们通过继承 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
,所有子项都会引用同一个对象
我有一个摘要 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;
}
BlahChildOne
从 Blah
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");
}
}
BlahChildOne
和 BlahChildTwo
之间都不共享信息(它们通过继承 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
,所有子项都会引用同一个对象