Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsWhite Papers
Discussion GroupsFirst AidDatabasesJavaBeansGUIJava 3DVirtual MachineCORBASecurityToolsGeneral
Java DirectoryOpen Source ProjectsSample Book ChaptersUser GroupsWeb Resources
Related Topics
Databases.NETMore Topics ...

Java Forum / General / June 2005

Tip: Looking for answers? Try searching our database.

multiple inheritance and java generics flaw?

Thread view: 
Murat Tasan - 22 Jun 2005 19:40 GMT
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.
Murat Tasan - 22 Jun 2005 20:34 GMT
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...


Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.