例如,我进行下面定义的递归调用。该方法从最后一个中找到第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;
}
答案 0 :(得分:3)
如果对象引用是方法的本地对象,则调用方或其他任何人都无法看到对它的更改。
E.g:
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");
}
答案 1 :(得分: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
引用的对象进行更改,因此更改在调用方中可见。
如果您是来自C
或C++
背景的人,这相当于在被调用方法中指定一个指针参数,该参数不会影响调用者传递的内容。
答案 2 :(得分:0)
public void findKthFromLast(Node head, int k){
Node kth;
recrusiveHelper(head, k, kth);
System.out.println(kth.data); //this is null
}
您将null传递给该方法,无论您在该方法中执行什么操作,在此之外将保持为null。您无法以在方法之外可见的方式更改引用值。