Is there a syntax or workaround to constrain a generic type parameter to any of a range of types?
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
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
}
EDITED:
I won't know at compile time which I might get (coming from external code), so I want to avoid having concrete classes for each type. Also, I have to give my class to a foreign system who invokes my class.method, but the other system can give me instances of a variety of classes, but a narrowly defined and known variety.
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?