Java对象不能通过递归通过ref传递

Java对象不能通过递归通过ref传递,java,recursion,binary-search-tree,Java,Recursion,Binary Search Tree,问题是我需要编写一个函数来验证二叉树是否是有效的二叉搜索树 这是我的代码: public static boolean betterValidBSTArray(TreeNode node) { WrapInt lastData = null; return validate(lastData, node); } private static boolean validate(WrapInt lastData, TreeNode node) { if(node == nu

问题是我需要编写一个函数来验证二叉树是否是有效的二叉搜索树

这是我的代码:

public static boolean betterValidBSTArray(TreeNode node) {
    WrapInt lastData = null;
    return validate(lastData, node);
}

private static boolean validate(WrapInt lastData, TreeNode node) {
    if(node == null) return true;
    if(!validate(lastData, node.getLeft())) return false;
    if(lastData != null && node.getData() <= lastData.value) return false;
    if(lastData == null) lastData = new WrapInt();
    lastData.value = node.getData();
    if(!validate(lastData, node.getRight())) return false;

    return true;
}

class WrapInt { int value; }
问题是,这个算法不起作用。我设置了一些断点,并计算出对于每个堆栈调用,在堆栈调用完成后将lastData分配给一个值之后,上一个堆栈调用将继续使用lastData=null,即使lastData对于上一个堆栈调用具有实际值


感谢您的帮助。

您需要在BetterValidStarray中创建WrapInt对象,并为其值指定null。这样,您就可以传递lastData引用。试试这个,它就会工作。

要修复代码,您不应该执行iflastData==null lastData=new WrapInt;由于它只将对新对象的引用分配到方法调用参数中,该参数是每个堆栈调用的局部变量,因此您不应将null作为lastData传递,而应传递一个将在整个递归中使用的对象,只更改其值。

您在引用的工作方式中做出了错误的假设

公共静态布尔BetterValidStarraytreeNode节点{ WrapInt lastData=null; 返回数据,节点; }

您似乎认为这会将lastData的地址向下传递以进行验证,并在触发正确的条件时使用对象对其进行设置

但这实际上是:

   return validate(null, node);
因为lastData的值=null

必须向下传递要由基础方法填充的对象,因为引用总是按值传递。因此,你传递值null null,而不是像你所做的那样,在LASTATDATA变量的地址,以及C++中的LATSTATABASE。 有关更好的解释,请参见

解决方案是在外部创建引用,然后将其传递到要使用的方法中

public static boolean betterValidBSTArray(TreeNode node) {
     WrapInt lastData = new WrapInt();
     return validate(lastData, node);
} 
如果你想区分null/notnull,如果这在你的代码中有意义的话,比如找到它,你可以使用

class WrapInt {
    Integer value;
}


因此,递归之外的代码可以访问此状态信息。

重写“WrapInt”类的克隆,然后在每次递归调用validate方法时尝试传递“lastData”对象的克隆。是否将null指定给基元?
class WrapInt {
    private int value;
    private boolean set;
    public boolean wasSet() { return set; }
    public int getValue() { return value; } 
    public void setValue(int value) { this.value = value; set = true; }
}