Java中的一种指针

时间:2014-09-10 08:44:28

标签: java pointers reference nullpointerexception

我正在尝试执行以下操作:

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做到这一点?

3 个答案:

答案 0 :(得分:2)

永远记住Java is pass by value

如果在方法中重新实例化变量,则保持传递的变量不变。你的例子确实如此。

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中不起作用,你需要使用`为此。