0

例如,我进行下面定义的递归调用。该方法从最后一个元素中查找第 k 个元素。如果找到,它将当前节点分配给我传递给递归调用的对象。由于某种原因,节点 kth 为空。你不能这样做吗?为什么?

public void findKthFromLast(Node head, int k){
    Node kth;     
    recrusiveHelper(head, k, kth);
    System.out.println(kth.data); //this is null
}

public int recursiveHelper(Node n, int k, Node kthFromLast){
    (if n == null){
        return 0;
    }
    val = 1 + recursiveHelper(n.next, k, kthFromlast);
    if(k == val){
        kthFromLast = n;
    }
    return val;
}
4

3 回答 3

3

如果对象引用是方法的本地引用,那么调用者或其他任何人都不会看到对它的更改。

例如:

void caller()
{
    obj = new String("asdf");
    doStuff(obj)
    System.out.println(obj) // still prints "asdf"
}

void doStuff(String obj)
{  
   // obj is a local reference, changing it wont affect caller's ref 
   obj = new String("ghj");
}
于 2012-09-30T14:37:47.563 回答
2

首先,该代码不应编译,因为kth未初始化,因此不能用作recursiveHelper方法调用的参数。

其次,对被调用方法中的引用所做的任何更改都不会传播给 Java 中的调用者,即

private void caller()
{
    StringBuilder s = new StringBuilder();
    s.append("test");
    calledMethod1(s);
    System.out.println(s.toString());
    calledMethod2(s);
    System.out.println(s.toString());
}

private void calledMethod1(StringBuilder buffer)
{
    buffer = new StringBuilder();
    buffer.append("calledMethod1");
    return;
}

private void calledMethod2(StringBuilder buffer)
{
    buffer.append(", calledMethod2");
    return;
}

输出:

test
test, calledMethod2

原因是,calledMethod1您只是在更改buffer引用指向的内容,而不是buffer在调用方法时对引用指向的内容进行任何更改。在calledMethod2中,您正在对引用的对象进行更改buffer,因此更改在调用者中可见。

如果您是来自CC++背景的人,这相当于在被调用方法中分配指针参数,这不会影响调用者中传递的内容。

于 2012-09-30T14:39:34.380 回答
0
public void findKthFromLast(Node head, int k){
    Node kth;     
    recrusiveHelper(head, k, kth);
    System.out.println(kth.data); //this is null
}

您将 null 传递给该方法,无论您在该方法内做什么,在该方法之外都将保持为 null。您不能以在方法之外可见的方式更改参考值。

于 2012-09-30T14:38:57.850 回答