开发者

Java, generics and static methods

I would like to have a generic Interpolator class which can interpolate between instances of classes implementing the Interpolatable interface:

interface Interpolatable {
  int getDimension();
  Iterator <? extends Interpolatable> getIterator(double d);
}

class Coordinate extends AnotherClass implements Interpolatable  {
  public int getDimension() {return 3;}
  public Iterator <Coordinate> getIterator (double d) {…}
}

class Interpolator <T extends Interpolatable> {
  Interpolator () {
    int dim = T.getDimension();
  }
  void doSomething (double d) {
    Iterator <? extends Interpolatable> it = T.getIterator(d);
    Interpolatable t = it.next();
    …
  }
}

Of course, the compiler complains about T.getDimension() and T.getIterator(d):

Cannot make a static reference to the non-static method getDimension()/getIterator(double) from the type Interpolatable.

However, the two methods cannot be made static, because they are defi开发者_如何转开发ned in an interface. And at the time I would use them in Interpolator, I do not have an instance of Coordinate (or any Interpolatable) available.

Any suggestions?

(I understand why interface methods cannot be static; I just lack an idea how to elegantly solve a problem like this.)


Because of type erasure, you cannot do much with the generic type at runtime. You need to keep an instance or class object around:

class Interpolator <T extends Interpolatable> {
  private final T target;

  Interpolator (T target) {
    this.target = target;
    int dim = target.getDimension();
  }
  void doSomething (double d) {
    Iterator <? extends Interpolatable> it = target.getIterator(d);
    Interpolatable t = it.next();
    …
  }
}


Basically, you are never passing any instance of the interface to the class. You are just using calls to the type (class), v.g. T.getDimension();

Also you do not need generics at all for this. Plain old interfaces work the way that you want.

You can just do:

class Interpolator  {
  Interpolable interpolable = null;  
  Interpolator (Interpolable _interpolable) {
    this.interpolable = _interpolable;
  }

  void doSomething (double d) {
    Iterator<Interpolable> it = this.interpolable.getIterator(d);
    Interpolatable t = it.next();
    …
  }
}

I recommend that before getting into generics you work more used to interface, static/instance methods and other more basic stuff...


cant you say class Interpolator extends Coordinate

and then just call the method straight away...


I think you're simply overusing generics. This should work:

class Interpolator {
  Interpolatable myInterpolatable;

  Interpolator (Interpolatable i) {
    myInterpolatable = i;
    int dim = i.getDimension();
  }
  void doSomething (double d) {
    Iterator <Interpolatable> it = myInterpolatable.getIterator(d);
    Interpolatable t = it.next();
    …
  }
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜