我不太确定如何在不发布完整代码的情况下提出这个问题(这是相当多的),但我会尽我所能。
我有一个实现接口的枚举类。整个程序的目的是在Fields中表示一堆整数。因此,有一个具体的类TrueField
派生自抽象类AbstractField
,它具有一个名为boolean sameAs(Field that)
的方法的实现。枚举类中也存在该方法(由于接口的原因):
enum SimpleField implements Field{
Empty(),Zero(0),Binary(0,1),Unsigned(Integer.MAX_VALUE);
private Field simpleField;
SimpleField(int... intArray){
simpleField = new TrueField(intArray);
}
@Override
public boolean sameAs(Field that){
return that.sameAs(simpleField);
}
}
TrueField
的实施:
public class TrueField extends AbstractField{
private final int[] intArray;
TrueField(int... thatArray){
intArray = thatArray;
}
@Override
public int at(int index){
if(index<0 || index>=intArray.length){
throw new IndexOutOfBoundsException();
}
return intArray[index];
}
@Override
public int length(){
return intArray.length;
}
...
AbstractField:
public abstract class AbstractField implements Field{
@Override
public abstract int length();
@Override
public boolean sameAs(Field that){
if(that==null)
throw new RuntimeException("that is null");
boolean result = true;
if(length()==that.length()){
for(int i=0;i<length();i++){
if(at(i)!=that.at(i))
result = false;
}
}
else
result = false;
return result;
}
@Override
public String toString(){
String result = "";
for(int i=0;i<length();i++){
result += at(i);
if(length()-i>1)
result += ",";
}
return "["+result+"]";
}
}
我的问题是,当我在我的主要方法中做这样的事情时:
Field sf = SimpleField.Binary;
Field sf2 = SimpleField.Binary;
Field tf = new TrueField(1,2);
System.out.println(sf.sameAs(sf2));
...很明显,enum类中的方法sameAs
被调用。但是为什么它不再自称,所以它是递归的?由于接口存在动态绑定,因此JVM看到sf
是动态类型SimpleField.Binary
和静态类型Field
。我不太明白发生了什么以及它为什么不再自称。我希望我已经清楚地解释了我的问题。
答案 0 :(得分:0)
这不是递归的,因为sameAs
枚举中的SimpleField
方法调用参数对象的sameAs
方法,不 a {{1} },它是SimpleField
。
因此TrueField
方法正在sameAs
类声明中运行。
在进一步检查时,可能是递归的,但只有Field
类中的声明也是递归的,我们可以看到它不是,现在此代码已在上面添加。
答案 1 :(得分:0)
该方法不是递归的,因为它不会调用本身。
@Override
public boolean sameAs(Field that){
return that.sameAs(simpleField);
}
此方法使用参数调用sameAs
。这个论点很可能是同一个枚举,但它仍然没有自称。
这是一个简单的递归方法的例子:
public long factorial(int value) {
return value == 0 ? 1 : factorial(value-1);
}
在此,没有额外的参考用于再次调用该方法;我只是在参数略有变化的情况下再次调用它。