我可以推断Java中的子类型吗?

时间:2013-11-20 14:33:30

标签: java generics type-inference

我希望能够做到这一点:

    public class ConcreteA<B extends AbstractC<D>> {
      public D getD() {...}
    }

甚至:

    public class ConcreteA<B extends AbstractC<?>> {
      public <D> D getD() {return cInst.dRelatedMethod();}
    }

但似乎我必须这样做:

    public class ConcreteA<D, AbstractB extends C<D>> {
      public D getD() {...}
    }

如果D有自己的类型参数,会变得混乱。有没有办法按照我喜欢的方式进行这种类型的推理? Java Community Process是否在工作中改进了类型推断?

符合条件的答案:
1)存在一种类型推断解决方案,它可以提供我想要的东西,而不需要求助于块#3中的解决方案 2)对任何旨在以适用的方式改进类型推断的JSR的引用 3)驳斥概念的有效性
4)这种JSR不存在的权威声明

2 个答案:

答案 0 :(得分:1)

当然!例如,以下代码编译(虽然我不知道为什么有人会需要这样一个奇怪的结构):

public class ConcreteA<B extends AbstractC<D>> {
    AbstractC<D> c;

    ConcreteA(B b) {
        c = b;
    }

    public D getD() {
        return c.getE();
    }
}

class AbstractC<E> {
    E e;

    AbstractC(E e) {
        this.e = e;
    }

    E getE() { return e; };
}

class D {

}

请注意,根据您的班级定义,ConcreteAAbstractCD(!)是类,而B只是模板参数。不要混淆了!

如果您想将D作为模板参数,则必须在ConcreteA的类标题中明确指定:

public class ConcreteA<B extends AbstractC<D>, D> {
    AbstractC<D> c;

    ConcreteA(B b) {
        c = b;
    }

    public D getD() {
        return c.getE();
    }
}

class AbstractC<E> {
    E e;

    AbstractC(E e) {
        this.e = e;
    }

    E getE() { return e; };
}

现在,BD(和E)是模板参数。

答案 1 :(得分:0)

最常见的技术是将你想要的类的Class<T>作为参数传递给你。

以下是一个示例,但它不会停留在newInstance。您可以在T方法内的任何位置正常使用getT

public class A<B extends Set<String>> {
  final B b;

  public A(B b) {
    this.b = b;
  }

  // Hard-coded - not the best.
  public String getString () {
    return "";
  }

  // Internally stored so type is retained.
  public B getB () {
    return b;
  }

  // Inferred from a parameter passed as a Class<T>.
  public <T> T getT(Class<T> clazz) throws InstantiationException, IllegalAccessException {
    return clazz.newInstance();
  }

}