类型变量的通用类型?

时间:2013-06-14 17:25:20

标签: java generics raw-types

我如何在Java泛型中表达以下类型关系:

class MyClass<T> { }

interface MyInterface<T extends MyClass> { 
  void m1(T<Integer> argument);
  void m2(T<String> argument);
  void m3(T<?> argument);
}

没有编译器投诉。这甚至可能吗?我想确保所有方法都接收MyClass的相同(子)类,同时不破坏类型安全性。在域中,不同的子类og MyClass不会出现。我真的必须列出三个泛型类型变量,如下所示:

class MyClass<T> { }

interface MyInterface<T1 extends MyClass<Integer>, 
   T2 extends MyClass<String>, T3 extends MyClass<?>> { 
  void m1(T1 argument);
  void m2(T2 argument);
  void m3(T3 argument);
}

我觉得读起来很糟糕,并没有像我希望的那样表达我的意图。这个问题与我关于泛型Raw types inside of generic definition的其他问题有关,这仍然让我感到困惑。也许有人可以帮忙!谢谢。

2 个答案:

答案 0 :(得分:0)

不确定它是否是一个好方法。我觉得使用下面的方法你不能“绑定”参数m1m2m3方法,而是在调用你时可以有权使用任何类型的参数{{1} }或MyClass<Integer>

MyClass<String>

和实施者

public class MyClass<T> { }

interface MyOtherClass<T extends MyClass<?>> { 
  void m1(T argument);
  void m2(T argument);
  void m3(T argument);
}

这就是你可以打电话的方式

class MyOtherClassImpl<T extends MyClass<?>> implements MyOtherClass<T> {

    @Override
    public void m1(T argument) {

    }

    @Override
    public void m2(T argument) {

    }

    @Override
    public void m3(T argument) {

    }

}

答案 1 :(得分:0)

嗯,我意识到我得到了因为我无法在Java中表达这一点:

class MyClass<T> { }

interface MyInterface<T extends MyClass> { 
  T<S> m1(S argument);
}

然而,我找到了一个相当奇特的解决方案。我没有在每个子接口中手动升级我的返回类型,而是使用Spoon在编译之前读取和写入相应的源代码。编译器看到我的代码就像我手动覆盖每个接口中的返回类型一样。这使我的代码与每个Maven构建的超级界面保持同步,我不必再担心它了。

这个解决方案可能不适合所有人,但它是我能够以DNRY的精神想到的最干净的解决方案。