我正在尝试执行以下操作:
import java.util.ArrayList;
public class One {
private ArrayList<Integer> list;
public One() {
addString(list);
sysoutList(list);
}
public void sysoutList(ArrayList<Integer> list2) {
for (int i = 0; i < list2.size(); i++) {
System.out.println(list2.get(i));
}
}
private void addString(ArrayList<Integer> list2) {
list2 = new ArrayList<>();
list2.add(1);
list2.add(2);
list2.add(3);
list2.add(4);
}
}
问题是,sysoutList()抛出NullPointerException,因为list2为null。看来,addString()中list的初始化没有效果,因为不能引用类变量。在C ++中,我会用指针解决这个问题,但我怎么能用Java做到这一点?
答案 0 :(得分:2)
如果在方法中重新实例化变量,则保持传递的变量不变。你的例子确实如此。
String myValue = "All your variables belong to us";
setValue(myValue);
System.out.println(myValue); //All your variables belong to us
void setValue(String v){
v = "Hello World!";
}
您应首先初始化您的变量:
import java.util.ArrayList;
public class One {
private ArrayList<Integer> list = new ArrayList<Integer>();
public One() {
addString(list);
sysoutList(list);
}
public void sysoutList(ArrayList<Integer> list2) {
for (int i = 0; i < list2.size(); i++) {
System.out.println(list2.get(i));
}
}
private void addString(ArrayList<Integer> list2) {
list2.removeAll();
list2.add(1);
list2.add(2);
list2.add(3);
list2.add(4);
}
}
列表是一个特殊情况。您可以使用add()方法认为我实际修改了变量,因此修改不应该发生。那不是真的,为什么?
那是因为你传递列表的参考值。如果您使用new
关键字为该引用分配新值,则表示&#34;松散&#34;附在它上面的物体(你不再有它的参考)。
但是如果修改该对象的属性(例如使用 add()方法),该对象的引用仍然有效,因此您可以修改原始对象。
我们可以相似。
想象一下,你有一个附加在字符串上的风筝。现在您附加一个新字符串并将新创建的字符串传递给朋友。
如果他切断了弦乐(又创造了一个new
),他就会失去对你的风筝的引用而他无法触及它。他可以附上一个新的风筝并做他想要的所有修改(也就是add()
某些东西),但它永远不会是你的风筝。
如果他改为使用你给他的字符串来接触风筝并进行修改,那么你将获得一个改良的风筝。
为了保持你的情况,您正在创建一个没有风筝(list
)和private ArrayList<Integer> list;
的字符串,然后将其传递给您的朋友创建一个新字符串(list2
) 。现在你和你的朋友都有一个没有任何附加条件的字符串。
他创建了一个新的风筝并将其附加到他的字符串(list2 = new ArrayList<>()
),但你的字符串仍然没有附加任何东西。当你试图放风筝时,你会注意到风筝根本就不存在(null
参考)。
首先,你必须创建自己的风筝并附上你的字符串(private ArrayList<Integer> list = new ArrayList<Integer>();
)。当您将其传递给您的朋友时,会附加另一个字符串(list2
)。现在,您的朋友可以使用list2
来修改您的风筝。
关于你的另一个问题,如果可以在从构造函数中调用的方法中变量变量,那么答案是是,但是这样的变量必须声明为static
如果您想在方法之外使用它。
在风筝中,就像你将一只风筝附加到一根绳子上,你和你的朋友使用相同的字符串对它进行操作(是的,手牵着手)。
因为你变成了:
import java.util.ArrayList;
public class One {
private static ArrayList<Integer> list;
public One() {
addString();
sysoutList();
}
public void sysoutList() {
for (int i = 0; i < list.size(); i++) {
System.out.println(list.get(i));
}
}
private void addString() {
list = new ArrayList<Integer>();
list.add(1);
list.add(2);
list.add(3);
list.add(4);
}
}
您不需要传递ArrayList
,因为您使用相同的&#34;风筝字符串&#34;在您的计划中的任何地方。
注意:如果您在 sysoutList()
之前致电addString()
,您仍会获得NullPointerException
,因为列表不是&# 39; t初始化。
这是一种不好的做法。我强烈建议你改变你的逻辑。
答案 1 :(得分:1)
如果你真的想在方法中实例化类变量,由构造函数调用,你可以这样做:
import java.util.ArrayList;
public class One {
private ArrayList<Integer> list;
public One() {
addString();
}
private void addString() {
list = new ArrayList<>();
list.add(1);
list.add(2);
list.add(3);
list.add(4);
}
}
答案 2 :(得分:0)
只是实例化你的清单:
private ArrayList<Integer> list = new ArrayList<>(); //In 4th line
替换上面代替:
private ArrayList<Integer> list;
发生错误,因为列表未初始化。您也可以在构造函数中初始化它 这是一个例子
public One() {
list = new ArrayList<>();
addString(list);
sysoutList(list);
}
上面的菱形运算符,即<>
在7之前的jdk中不起作用,你需要使用`为此。