Java 泛型参数绑定到任何类型的范围

是否有将泛型类型参数限制为任何类型范围的语法或解决方法?

Is there a syntax or workaround to constrain a generic type parameter to any of a range of types?

我知道您可以将一个类型限制为 all 的一系列类型(即 AND 逻辑):

I am aware that you can constrain a type to be all of a range of types (ie AND logic):

public class MyClass<T extends Comparable<T> & Serializable> { } // legal syntax

是否有OR逻辑版本,即类似这样的:

Is there an OR logic version, ie something like this:

public class MyClass<T extends Comparable<T> | Serializable> { } // illegal syntax

如果没有支持这一点的语法(我不认为有),是否有一种很好的解决方法或方法?

If there isn't a syntax that supports this (I don't think there is), is there a workaround or approach that is a good pattern?

在某些情况下,一个示例用例可能是:

For some context, one example use case might be:

/** @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;
}

人们似乎对我上面的方法示例的确切语义感到困惑.让我们试试这个:

People seem to be getting hung up on the exact semantic of my method example above. Let's try this instead:

public class MyWrapper<T extends A | B> {
    // my class can wrap A or B (unrelated classes). Yes I will probably use instanceof
}


我不会在编译时知道我可能会得到哪个(来自外部代码),所以我想避免每种类型都有具体的类.此外,我必须将我的类提供给调用我的 class.method 的外部系统,但另一个系统可以为我提供各种类的实例,但定义狭隘且已知种类.

有些人评论说 instanceof 是不纯的".好吧,一种解决方法是使用工厂方法根据传入对象的类来选择我的具体类,但是该工厂方法必须使用 instanceof,所以你只是移动 instanceof 到另一个地方 - 你仍然需要 instanceof.

Some people have commented on instanceof being "impure". Well, one workaround is to use a factory method to pick my concrete class based on the class of the incoming object, but that factory method would have to use instanceof, so you're just moving the instanceof to another place - you still need the instanceof.

或者这个想法从来都不是一个好的想法?

Or is this idea just not ever a good one?

推荐答案

没有.除非所有类型都具有非空联合类型,否则它没有任何意义,例如他们都实现的接口,或者他们都扩展的基类,在这种情况下,您只需指定联合类型.

No. It wouldn't make any sense unless all the types had a non-empty union type, e.g. an interface they all implemented, or a base class they all extended, in which case you just specify the union type.

相关文章