从接口返回类型的通用方法

时间:2015-01-12 15:16:51

标签: java generics

我有一个接口和一个看起来像这样的值类:

public interface ITest<T1> {
  <T2> T1 test(OtherClass<T2> client);
}

基本上,它表示子类型必须实现返回T1的方法test,无论实现子类型是什么。

OtherClass:

public class OtherClass<T> {
  public T contents;  
}

但是,当我想编写一个实现test的子类型并且只返回它获得的客户端实例时,我会遇到编译错误。我想要的是统一T1T2

public class Test<T1> implements ITest<T1> {
  @Override
  public <T1> T1 test(OtherClass<T1> client) { // compile error
    return client.contents;
  }
}

有没有办法让这个课上班?

2 个答案:

答案 0 :(得分:1)

我不认为这是允许的,因为您现在将T2限制为班级T1中的Test<T1>

您可以按如下方式解决此问题:

public interface ITest<T1, T2> {
    T1 test(OtherClass<T2> client);
}

public class OtherClass<T> {
  public T contents;  
}

public class Test<T1> implements ITest<T1, T1> {
    @Override
    public T1 test(OtherClass<T1> client) {
        return client.contents;
    }
}

答案 1 :(得分:1)

<T1>基本上告诉任何一个班级&#34;你选择T1将是什么类型!&#34;。这意味着在这种情况下<T1>OtherClass<T1>引用相同的类型,而返回类型T1引用类T1。如果重命名,则会看到错误:

@Override
public <OtherClassType> T1 test(OtherClass<OtherClassType> client) {
    return client.contents; //you can't do that without casting OtherClassType to T1
}

如果你不能编辑ITest接口,那么编译它的唯一方法是通过强制转换,但你需要确保在执行之前可以实际执行(因为OtherClass可以返回任何类型,而不是必然是T1的子类。

编辑:编译器不允许这样做的确切原因是因为您实际上限制test方法只接受某些类型,而它覆盖的方法允许任何类型。