我正在写一些我上学几天的JAVA作业,但遇到了很奇怪的事情(嗯,至少对我来说是……)。
由于该问题与我的项目无关,所以我写了一些代码来表达我要询问的行为,因此请忽略以下代码中可能遇到的与该特定问题无关的任何问题。
考虑以下类别:
package test;
import java.util.ArrayList;
import java.util.List;
public class Car {
List<Doors> doors;
int numOfDoors;
public Car(int numOfDoors) {
this.numOfDoors=numOfDoors;
}
public void prepare() {
run(doors);
}
public void run(List<Doors> listOfDoors) {
listOfDoors=new ArrayList<Doors>(numOfDoors);
}
public List<Doors> getDoors() {
return doors;
}
}
还有这个:
package test;
import java.util.List;
public class TestDrive {
public static void main(String[] args) {
Car car=new Car(5);
car.prepare();
List<Doors> listOfDoors=car.getDoors();
if (listOfDoors==null) {
System.out.println("This is not the desired behaviour.");
}
else {
System.out.println("This is the desired behaviour.");
}
}
}
我同意,这有点愚蠢,没有意义,但是再次-我写它只是为了满足我的好奇心。
现在,您可能已经猜到了,输出为“这不是所需的行为。”,这意味着,即使在“ run()”方法中为其分配了新对象,“门”字段仍保留一个空指针。所以我的问题是为什么?为什么它为空?
我的意思是,我知道创建局部变量(可能是原始变量,对象或对对象的引用)会导致在我们离开方法范围时将其失去正确的作用,但实际情况并非如此,因为是对新创建的对象(门)的实时引用,那么JAVA为什么会销毁它?
最佳答案
让我们逐步分析它。
Car car=new Car(5);
car.prepare();
您创建了一辆新车,并希望它在
prepare
之后有5个车门的列表。现在让我们看一下
prepare
期间发生的情况。public void prepare() {
run(doors);
}
public void run(List<Doors> listOfDoors) {
listOfDoors=new ArrayList<Doors>(numOfDoors);
}
new ArrayList
被分配给局部变量listOfDoors
。编写
run(doors)
时,没有传递指向变量doors
的指针,例如在C上下文中可能会期望的那样。您正在将null
(因为doors
尚未初始化)传递给run方法。运行开始时,我们有
List<Doors> listOfDoors = null;
这是在调用时传递
null
引用的结果。然后,为该局部变量分配一个新列表,仅在方法终止时销毁。
如您所见,没有为
doors
分配任何内容,从而导致了意外的行为。要解决此问题,请删除run方法并重写您的prepare方法。
public void prepare() {
doors = new ArrayList<Doors>(numOfDoors);
}
这样,您应该会获得预期的行为。