Java generics parameter bounding to any of a range of types
是否有将泛型类型参数限制为一系列类型的语法或解决方法?
我知道您可以将一个类型限制为一系列类型的所有类型(即
1 | public class MyClass<T extends Comparable< T > & Serializable> { } // legal syntax |
是否有
1 | public class MyClass<T extends Comparable< T > | Serializable> { } // illegal syntax |
如果没有支持此的语法(我认为没有),是否有一种解决方法或方法是一种好的模式?
在某些情况下,一个示例用例可能是:
1 2 3 4 5 6 | /** @return true if the obj is either has the same id, or if obj is the same as id */ public <T extends MyClass | String> boolean sameAs(T obj) { if (obj instanceof String) return this.id.equals(obj); if (obj instanceof MyClass) return this.id.equals(((MyClass)obj).id); return false; } |
人们似乎对我上面的方法示例的确切语义感到困惑。让我们试试这个:
1 2 3 | public class MyWrapper<T extends A | B> { // my class can wrap A or B (unrelated classes). Yes I will probably use instanceof } |
编辑:
我不会在编译时知道我可能会得到哪个(来自外部代码),所以我想避免每种类型都有具体的类。此外,我必须将我的课程交给调用我的 class.method 的外部系统,但另一个系统可以给我各种类的实例,但只是定义狭隘和已知的种类。
有些人评论说
或者这个想法从来都不是一个好的想法?
1 | public class MyWrapper<T extends A | B> {} |
您不能对您无法控制的界面执行此操作,但对于您自己的东西,您可以使用空标记界面:
1 2 3 4 5 6 7 8 9 10 11 12 | interface AOrB { } interface A extends AOrB { someMethodHere(); } interface B extends AOrB { someOtherMethodHere(); } public class MyClass<T extends AOrB> {} |
不管纯粹主义者怎么说,在你需要的时候使用
没有。除非所有类型都具有非空联合类型,否则它没有任何意义,例如他们都实现的接口,或者他们都扩展的基类,在这种情况下,您只需指定联合类型。
虽然Java 对
带有通配符的泛型类型实际上是联合类型:
不支持任意两种类型的联合。
Java 7 的多捕获语法看起来支持任意异常类型的联合
1 |
但不是真的,
使用
以下代码将与提供的示例执行相同的操作,但没有运行时类型检查和类型转换。
1 2 3 4 5 6 | public boolean sameAs(MyClass obj) { return this.id.equals(obj.id); } public boolean sameAs(String obj) { return this.id.equals(obj); } |
NPE 检查可能是个好主意。