我想知道在包含类型层次结构和许多通用变量时是否有可能使java的泛型更具可读性和/或更易于使用。我还不熟悉java的泛型。在以下示例中可以执行的操作:
我们假设我需要以下课程......
abstract class BaseClass<T> {}
...使用以下课程的列表...
class Foo<T1, T2> {}
...并在此类情况下另外激活迭代器。
所以我会做以下事情:
class ImplClass<T1, T2> extends BaseClass<List<Foo<T1, T2>>> implements Iterator<Foo<T1, T2>> {}
我们还假设有一个处理BaseClass的接口:
interface Manipulator<T, B extends BaseClass<T>> {
void doSomething(B baseClassInstance);
}
因此,当为ImplClass编写实现该接口的类时,我总是必须再次编写整个泛型签名,不是吗? 如下所示:
class ManipulatorA<T1, T2> implements Manipulator<List<Foo<T1, T2>>, ImplClass<T1, T2>> {
@Override
void doSomething(ImplClass<T1, T2> baseClassInstance) {...}
}
class ManipulatorB<T1, T2> implements Manipulator<List<Foo<T1, T2>>, ImplClass<T1, T2>> {
@Override
void doSomething(ImplClass<T1, T2> baseClassInstance) {...}
}
所以我可以提供一个EMPTY接口,它只用于类型转换以减少泛型变量:
interface ImplManipulator<T1, T2> extends Manipulator<List<Foo<T1, T2>>, ImplClass<T1, T2>>{
// actually empty
}
并且实现看起来像:
class ManipulatorA<T1, T2> implements ImplManipulator<T1, T2> {
@Override
void doSomething(ImplClass<T1, T2> baseClassInstance) {...}
}
class ManipulatorB<T1, T2> implements ImplManipulator<T1, T2> {
@Override
void doSomething(ImplClass<T1, T2> baseClassInstance) {...}
}
拥有一堆空接口似乎对我来说不太可读。 不得不一直考虑巨大的通用签名。 在处理这种情况时,我能做些什么来产生更好的代码?
答案 0 :(得分:0)
在处理这种情况时,我能做些什么来产生更好的代码?
改变语言......
java不支持类型别名或haskell样式的新类型。如果可以,请将scala添加到项目中。你可以混合使用scala和java。
另一种选择是使用某种源生成/预处理。甚至可能使用AST变换器。但这完全是习惯性的,所以如果不确切知道你的情况,很难给你任何建议
如果你必须坚持使用java,那么,正如你所注意到的,别名泛型类型的唯一方法是创建一个中间接口或类。您可以通过以下方式清理它:
ImplManipulator
并未向您提供更多信息,但FooListManipulator
可能会有所帮助TypeAliases
并将所有接口与包scoppe放在一起。如果您需要全局,请创建一个包typeAliases
,将所有内容放在那里,永远不要再看那里另一种选择是简单地删除泛型。人们经常使用hamcrest匹配器,因为他们的长签名会破坏可读性。在所有仿制药都要帮助你之后,不要让你的生活变得更加艰难(至少这是个想法)