简体   繁体   English

为什么这种方法不递归?

[英]Why is this method not recursive?

I'm not quite sure how to ask this question without posting the whole code here (it's quite a bit), but I'll try my best. 我不太确定如何在不将整个代码都发布到这里的情况下问这个问题(这相当多),但是我会尽力而为。

I have an enum class which implements an interface. 我有一个实现接口的枚举类。 The purpose of the whole program is to represent a bunch of integer numbers in Fields. 整个程序的目的是在Fields中表示一堆整数。 So there is a concrete class TrueField which is derived from abstract class AbstractField that has the implementation of a method called boolean sameAs(Field that) . 因此,有一个具体类TrueField是从抽象类AbstractField派生的,该类具有名为boolean sameAs(Field that)的方法的实现。 That method also exists (it has to, because of the interface) in the enum class: 该方法在enum类中也存在(由于接口的原因,它必须存在):

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);
  }
}

Implementation from TrueField : 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: 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+"]";
}

} }

My question is, when I do something like this in my main method: 我的问题是,当我在主要方法中执行以下操作时:

Field sf = SimpleField.Binary;
Field sf2 = SimpleField.Binary;
Field tf = new TrueField(1,2);

System.out.println(sf.sameAs(sf2));

...obviously the method sameAs in the enum class gets called. ...显然,枚举类中的sameAs方法被调用。 But why isn't it calling itself again so it is recursive? 但是为什么它不再次调用自身,所以它是递归的呢? As there is dynamic binding because of the interface the JVM sees that sf is the dynamic type SimpleField.Binary and the static type Field . 由于通过接口进行了动态绑定,因此JVM看到sf是动态类型SimpleField.Binary和静态类型Field I don't quite understand what's going on and why it isn't calling itself again. 我不太了解发生了什么,以及为什么它不再自称。 I hope I've explained my question clear enough. 我希望我已经足够清楚地解释了我的问题。

It's not recursive because your sameAs method in the SimpleField enum calls the sameAs method of the parameter object, which is not a SimpleField , it's a TrueField . 因为你这不是递归sameAs的方法SimpleField枚举调用sameAs参数对象,这不是一个方法SimpleField ,这是一个TrueField

So the sameAs method is being run as declared in the Field class. 因此, sameAs Field类中的声明运行sameAs方法。

On further inspection, it could be recursive, but only if the declaration in the TrueField class was recursive also, which we can see that it is not, now that this code has been added above. 在进一步检查时,它可以是递归的,但TrueFieldTrueField类中的声明也是递归的, 因为上面已添加了此代码因此我们可以看到它不是递归的

The method isn't recursive because it's not calling itself . 该方法不是递归的,因为它没有调用自身

@Override
public boolean sameAs(Field that){
    return that.sameAs(simpleField);
}

This method is using the argument to call sameAs . 此方法使用参数调用sameAs The argument may very well be the same enum, but it's still not calling itself. 该参数很可能是相同的枚举,但它仍然没有自我称呼。

This is an example of a simple recursive method: 这是一个简单的递归方法的示例:

public long factorial(int value) {
    return value == 0 ? 1 : factorial(value-1);
}

In this, there's no extra reference to use to call the method again; 在此,没有多余的引用可用于再次调用该方法。 I'm just invoking it once more with a slight change in parameters. 我只是在参数稍有变化的情况下再次调用它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM