1

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

class MyClass<T> { }

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

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

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

我觉得这读起来很糟糕,也没有像我希望的那样很好地表达我的意图。这个问题与我关于泛型定义中的泛型原始类型的其他问题有关,这仍然让我感到困惑。也许有人可以帮忙!谢谢你。

4

2 回答 2

0

好吧,我意识到我得到了因为我无法用 Java 表达这一点:

class MyClass<T> { }

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

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

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

于 2013-06-17T08:00:29.190 回答
0

不确定它是否是一个好方法。我觉得使用下面的方法你不能“绑定”参数m1,,方法,相反m2m3在调用时你可以使用任何类型的参数,无论是它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) {

    }

}

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

  MyOtherClass<MyClass<?>> otc = new MyOtherClassImpl<MyClass<?>>();
  MyClass<Integer> m1 = new MyClass<Integer>();
  MyClass<String> m2 = new MyClass<String>();
  MyClass<Object> m3 = new MyClass<Object>();
  otc.m1(m1);
  otc.m2(m2);
  otc.m3(m3);
于 2013-06-14T17:38:51.987 回答