I wish to have a method which has a signature like
method(T1 t1, T2 t2)
such that T2 is-a T1 and/or T1 is-a T2. I do not want the case where T1 and T2 are both a T but where neither is-a the other. I wish for the most allowed type to be bounded above by the highest of either T1 or T2 in the inheritance tree. I am using Java 6.
Below is an attempt to show some desired use cases
class Experiment
{
static List genericList = new ArrayList();
static ArrayList arrayList = new ArrayList();
static class Test1 { }
static class Test2 extends Test1 { }
static class Test3 extends Test1 { }
static <T> T experiment0(T expected, T actual)
{
return actual;
}
/** Almost works, but want arbitrary ordering. Cannot overload due to erasure. */
static <T, S extends T> S experiment1(T expected, S actual)
{
return actual;
}
private static void experimentDriver()
{
// good, allowed
List l = experiment0(genericList, arrayList);
// bad, allowed; want compile-time error
Object o = experiment0(new String(), new Integer(0));
// good, allowed
Test1 test1 = experiment1(new Test1(), new Test3());
String string = experiment1(new String(), new String());
List list = experiment1(genericList, new ArrayList());
// good, disallowed
experiment1(new Test2(), new Test3());
experiment1(new Test3(), new Test2());
experiment1(new Integer(0), new String());
experiment1(new ArrayList(), new LinkedList());
// bad, disallowed; want either order
experiment1(new Test3(), new Test1());
experiment1(new ArrayList(), genericList);
}
}
I know that I can achieve something similar with a signature like
experiment(Class<T> clazz, T expected, T actual)
but that forces the programmer to explicitly mention the highest allowable type, when I'd like it inferred by the language.
Note that the closer solution can't simply be overloaded because their erasures are the same.
I hope I've provided enough information to convey what I want. I realize this may just be impossible in Java, but I hope it's doable. This is also my first question on this forum, so if I've unknowingly violated any rules I apologize in advance and appreciate your patience!
T
can always beObject
. – FluorometerT extends S, S extends T
creates a circular dependency between the types. Clearly both of those constraints can't be true at the same time unlessS == T
. In C# you could do it by overloading the method (because there's no erasure). In Java, it can't be done at all. – Mccorkle