【发布时间】:2009-03-25 21:25:13
【问题描述】:
我有一组相当复杂的 Java 泛型类。比如我有一个界面
interface Doable<X,Y> {
X doIt(Y y);
}
和实现
class DoableImpl implements Doable<Foo<Bar<Baz,Qux>>,Foo<Bar<Zot,Qux>>> {
Foo<Bar<Baz,Qux>> doIt(Foo<Bar<Zot,Qux>> fooBZQ) { ... }
}
在实际实现中,Doable 有很多方法,所以Foo<Bar<Baz,Qux>> 等会一遍又一遍地出现。
(信不信由你,泛型类型比这更痛苦。我已经为示例简化了它们。)
我想简化这些,以节省自己的打字时间并减轻眼睛的压力。我想要的是为Foo<Bar<Baz,Qux>> 等设置一个简单的“类型别名”,例如FooBBQ 和FooBZQ。
我目前的想法是定义包装类:
class FooBBQ {
public static FooBBQ valueOf(Foo<Bar<Baz,Qux>> fooBBQ) {
return new FooBBQ(fooBBQ);
}
private Foo<Bar<Baz,Qux>> fooBBQ;
private FooBBQ(Foo<Bar<Baz,Qux>> fooBBQ) {
this.fooBBQ = fooBBQ;
}
public Foo<Bar<Baz,Qux>> toGeneric() {
return fooBBQ;
}
}
class FooBZQ { /* pretty much the same... */ }
class DoableImpl implements Doable<FooBBQ,FooBZQ> {
FooBBQ doIt(FooBZQ fooBZQ) { ... }
}
这很好用,但也有一些缺点:
- 我们需要为每个通用实例定义单独的包装器。包装类很短且风格化,但我想不出一种宏化它们的方法。
-
我们有调用
valueOf和toGeneric在FooBBQ和Foo<Bar<Baz,Qux>>之间转换的转换开销(从概念上讲,如果不是在操作上)。例如,如果doIt调用了一些库例程,该例程需要Foo<Bar<Zot,Qux>>(实际实现会这样做),我们最终会得到类似return FooBBQ.valueOf( libraryCall( fooBZQ.toGeneric() ) )我们原本应该有的地方
return libraryCall(fooBZQ);
还有其他方法可以在这里获得我想要的“类型别名”行为吗?也许使用一些第三方宏工具集?或者我是否需要接受我将不得不进行大量输入,一种方式(在实现中使用泛型类型)或另一种方式(为它们编写包装器)?也许让这么多泛型参数飞来飞去只是个坏主意,我需要重新考虑这个问题?
[更新] 好的,我禁止任何进一步的“不要那样做”的答案。假定Foo<Bar<Baz,Qux>> 在我的问题域中具有真正的价值(Pete Kirkham 可能是正确的,它具有 足够 的价值来获得具有描述性名称的适当包装类)。但这是一个编程问题;不要试图定义问题。
【问题讨论】:
-
我要对最后一个说“可能是”,但实际上并没有任何建设性的反馈:P 看起来很乱!祝你好运!
-
我认为这个问题对 Java 来说是一个很好的建议。如果您可以向 Oracle 提出类型别名功能,我认为这将是一个很棒的语言功能,可以简化语言并使源代码更具可读性。
-
今天深入了解 Java 并想清理一些冗长的代码......我不仅没有得到类型推断,而且也没有类型别名。 呜咽
-
我同意@BasilMusa,类型别名看起来像是该语言缺少的功能。从语法上讲,它可能类似于
class FooBBQ = Foo<Bar<Baz,Qux>> -
考虑项目 8。 Java 在 blog.jooq.org/2014/11/03/10-things-you-didnt-know-about-java 上有类型别名