奇怪的行为

S.克鲁姆斯

我正在尝试在Java中实现类似CAS的功能,但是我在类型和方法选择方面苦苦挣扎。

当我添加两个子类型时,一切都很好。当我添加具有超类型的子类型时,将发生无限递归。当再次将超型转换为精简型时,以及当我将超型添加到子类型时,再次发生相同的递归。

有人可以解释这里发生的事情以及我做错了什么吗?

public class MathMain{
    public static void main(String[] args){
        Constant constant = new Constant(1);
        constant.add(constant);
        MathObject mathObject = (MathObject)constant;
        constant.add(mathObject);
        constant.add((Constant)mathObject);
        mathObject.add(constant);
    }
}


public abstract class MathObject{
    public abstract MathObject add(MathObject addend);
    public abstract MathObject substract(MathObject subtrahend);
}


public class Constant extends MathObject{
    public final double c;

    public Constant(double c){
        this.c = c;
    }

    public MathObject add(MathObject that){
        return that.add((Constant)this);
    }

    public MathObject substract(MathObject that){
        return that.substract((Constant)this);
    }

    public Constant add(Constant addend){
        return new Constant(c + addend.c);
    }

    public Constant substract(Constant subtrahend){
        return new Constant(c - subtrahend.c);
    }
}
他们是

要记住的重要一点是,方法重载解析是在编译时确定的,而方法重写是在运行时确定的。

mathObject.add(constant)

选择MathObject add(MathObject addend)方法,这是唯一add可用的方法MathObject

在运行时,由于mathObjectis ConstantMathObject add(MathObject that)of的运行时类型Constant已执行,因此调用that.add((Constant)this)由于类型thatMathObject,再次MathObject add(MathObject addend)选择,这意味着您的方法正在无限递归中调用自身。

表达式Constant add(Constant addend)将调用您的唯一方法that.add((Constant)this)是,如果编译时间类型为thatwas Constant,因为MathObject它没有add接受Constant参数方法

现在,对于可行的情况:

constant.add(constant)
constant.add((Constant)mathObject)

两者都Constant add(Constant addend)直接调用,因为constantis的编译类型,Constant并且选择了具有更具体参数类型的方法。

我不知道这是否是一个好的解决方案,但是克服无限递归的一种方法是检查参数的类型:

public MathObject add(MathObject that){
    if (that instanceof Constant)
        return add((Constant) that);
    else
        that.add((Constant)this); // note that the casting here only makes
                                  // sense if MathObject has an add method
                                  // that takes a Constant. otherwise is makes
                                  // no difference
}

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章