在子方法中创建新对象显然不会传递引用

时间:2013-10-29 20:50:05

标签: java reference new-operator

我目前正在开发一个实现dijkstra算法的java项目。 我有一些看起来与此类似的代码

    public static void main(String[] args){
      Graph myGraph = null;
      execute(myGraph);
    }

    private static void execute(Graph graph){
      while(!quit){
      doCommand(graph);
    }}


    doCommand(Graph graph){
      if(command == n){
        graph = new Graph(size); }}

在我的程序中,我可以输入一些命令,例如n 5,这意味着程序应该创建一个包含5个节点的新Graph。 现在我的问题是,在输入例如n 5之后,它仍然是空的。 在我看来,myGraph应该在n命令之后收到一个新的引用,但显然它没有,我不明白为什么。 顺便说一句,行graoh = new Graph(size);肯定是执行。那不是错误。

5 个答案:

答案 0 :(得分:3)

Java不允许您重置引用,因为它是通过 value 传递的。这意味着引用也通过 value 传递。当您执行graph = new Graph(size)时,您所做的只是将本地引用(从main传入的引用的副本)指向Graph的新实例。 graph内的main仍为null

解决方法可能是让doCommand返回Graph的实例,或者使用Graph的静态实例(因为看起来所有方法都是静态方法)。另一种选择是将graph封装在其他类中作为属性,这意味着类中的所有方法都可以访问它。

答案 1 :(得分:1)

别名在这里可能会令人困惑。

将对象传递给方法会创建一个新别名(另一个引用同一对象的名称)。当对象的状态发生变化时,它会反映在所有别名中。

分配给变量会破坏别名。在行之后

graph = new Graph(size);

变量图指向新对象,而不是最初分配的对象。 此更改是变量的本地更改,并且会中断别名。因此,graph不再引用与myGraph相同的对象。

答案 2 :(得分:0)

在您的方法doCommand中,您只需将新图表对象分配给本地参考graph,但由于它是方法的本地对象,因此此更改对您的主myGraph引用无效,根据:

始终保持为空
Graph myGraph = null;

答案 3 :(得分:0)

你需要花一些时间研究基本的程序逻辑。你的main()SETS图在调用execute()之前必须为null - 当然,当该方法开始执行时它是null,它不能是其他任何东西。

如果您想要在命令行中输入的数字,则必须使用它。例如,如果输入“5”,它将在args [0]中显示为字符串。如果你想做多次的事情,你必须将它转换为一个整数(在确认字符串代表一个!)之后,然后将该值用于某些(可能是)整数变量。

答案 4 :(得分:0)

试试这段代码!

public static void main(String[] args){
    Graph myGraph = new Graph();
    doCommand(myGraph);
    System.out.println(myGraph);
}
private static void doCommand(Graph myGraph){
    myGraph = new Graph();
    System.out.println(myGraph);
}

您会注意到两个System.out.println语句都将打印不同的对象引用。

这是因为当你调用doCommand方法并传递myGraph引用的值,然后在doCommand方法中创建一个新对象Graph()时,局部变量myGraph(在doCommand中)将指向一个新的对象,但不会改变main()中myGraph的值。

但是,如果你这样做:

public static void main(String[] args){
    Graph myGraph = new Graph();
    myGraph = doCommand(myGraph);
    System.out.println(myGraph);
}
private static Graph doCommand(Graph myGraph){
    myGraph = new Graph();
    System.out.println(myGraph);
    return myGraph;
}

两个println语句都将打印相同的对象引用。这是因为你在doCommand中将myGraph的引用值返回到main中的myGraph。