0

我目前正在开发一个实现 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 个节点的新图形。现在我的问题是,在输入例如 n 5 之后,它仍然为空。在我看来,myGraph 应该在 n 命令之后收到一个新的引用,但显然它没有,我不明白为什么。顺便说一句,行 graoh = new Graph(size); 绝对被执行。那不是错误。

4

5 回答 5

3

Java 不允许您重新设置引用,因为它是按传递的。这意味着引用也是按传递的。当您这样做时graph = new Graph(size),您所做的只是使本地引用(这是从 传入的引用的副本main)指向Graph. graph里面main依旧null

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

于 2013-10-29T20:54:47.100 回答
1

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

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

分配给变量会中断别名。行后

graph = new Graph(size);

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

于 2013-10-29T20:56:38.287 回答
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。

于 2013-10-29T21:16:04.463 回答
0

在您的方法doCommand中,您只需将新图形对象分配给本地引用graph,但由于它是方法的本地对象,因此此更改对您的主myGraph引用没有影响,根据:

Graph myGraph = null;
于 2013-10-29T20:56:41.807 回答
0

你需要花一些时间学习基本的程序逻辑。您的 main() 将图表设置为 null 就在它调用 execute() 之前 - 当然,当该方法开始执行时它为 null,它不可能是其他任何东西。

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

于 2013-10-29T20:57:02.237 回答