multiple inheritance and java generics flaw?

M

Murat Tasan

disclaimer: i already know about type erasure, so i understand the logical
flaw present here. what i'm most interested in is knowing:

a) why i don't get a compiler error (i think i should, but i don't, not
even a warning with all flags turned on).

b) how others have gotten around this eloquently (i.e. without a ton of
unchecked warnings)

okay, here are 4 very small classes than can be used to test this. first,
i have a DistanceFunction interface with one method:

public interface DistanceFunction<D extends Number & Comparable<D>>
{
public D computeDistance(Object o1, Object o2);
}

and i have an implementing class of this interface:

public class TestDistanceFunction implements DistanceFunction<Double>
{
public Double computeDistance(Object o1, Object o2)
{
return 69.0d;
}
}

and i have another class that should be initialized by using the output of
a distance function:

public class TestContainer
{
public <D extends Number & Comparable<D>> TestContainer(D c)
{
}
}

now. when i compile all of this, everything is kosher. in particular, i
think the constructor of TestContainer should at least give me a warning.

why? because when type erasure occurs for types using multiple
inheritance (i.e. <D extends Number & Comparable<D>>), the FIRST
class/interface listed is the chosen erasure class.

this implies that i cannot have a reference to an object with the
reference having more than one type. (i.e. i cannot have a true multiple
inheritance reference).

thus, i should NEVER be able to pass a correct D to TestContainer(D c).

nevertheless, the compiler thinks everything is fine, which is misleading.

it turns out that my intuition is correct and i CANNOT ever seem to create
a new TestContainer.

note the final test class:

public class Test
{
public static void main(String[] args)
{
DistanceFunction<?> d = new TestDistanceFunction();

Number x = d.computeDistance(null, null);
Comparable<? extends Number> y = d.computeDistance(null, null);

// TestContainer container = new TestContainer(x);
// TestContainer container = new TestContainer(y);
// TestContainer container = new TestContainer(d.computeDistance(null,
null));
}
}

un-commenting any of the commented lines causes failure. why? because no
appropriate constructor signature of TestContainer is found.

i expect the error certainly when calling with x and y. but even the last
attempt fails.

now, once again. i understand why it fails. i do not understand why when
compiling TestContainer i don't receive either an error or a warning about
this.

second part of the question (although i'm far more interested in the
first part, i unfortunately also have work to do...). the above
illustrates that i want to make a TestContainer that can hold results of
some distance function. but i want all results to be of the same
Comparable type, to get rid of catching ClassCastExceptions when sorting a
group of results. nevertheless, i would like to keep references to the
results as Number, as i will never explicitly call compareTo(), the sort()
methods will do that.

i know i can cast my Number references to the raw type Comparable, but
then i get either ugly unchecked warnings or i have to worry about
ClassCastExceptions. both of these i'd like to avoid using generics.
(isn't that part of the point of generics in java?)

anyone have a similar problem with multiple inheritance and have an
eloquent solution using generics?

thanks much.
 
M

Murat Tasan

well, i found a way to make this work. but it's not nice. i also know
why the compiler accepts the constructor: if i pass a Double directly, or
even the results of TestDistanceFunction directly, everything works fine.

why? because a Double does satisfy the requirements for D. but a Number
does not, and due to type erasure only a Number is returned from a
DistanceFunction, where as a Double is returned from TestDistanceFunction.

so basically, what i would like to see is generics handled at runtime,
along with references that can assume multiple types.

which java doesn't have.

thanks for the help anywho...
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,764
Messages
2,569,564
Members
45,039
Latest member
CasimiraVa

Latest Threads

Top