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 / November 2005

Tip: Looking for answers? Try searching our database.

A question about generics

Thread view: 
Lemon Tree - 02 Nov 2005 12:41 GMT
Hello,

I am wondering what is the most elegant (and correct) way to organize
the following type hierarchy.

Let's suppose to have the following parametric class:

class Foo<T extends InfoType> {
 private T info;
 ...
 public T getInfo() {
   ...
 }
}

Let's now suppose that we want to create a Container for Foo instances,
and that we want to be able to search that container by using the info
contained in every Foo instance.

I might do the following:

class FooCollection<T extends Foo> extends HashSet<T> {
 ...
 public T findByInfo(InfoType info) {
   for(T t : this) {
     if(t.getInfo().compareTo(info) == 0) {
       return t;
     }
   }
   return null;
}

Obviously the InfoType class contains an int compareTo(Bar info) method
for comparing InfoType (and their subclasses)

The previous code is correct but generates some warnings with respect
to the fact that the type parameter T is of type Foo and Foo is a
parametric type which is not instantiated with respect to its type
parameter.

In order to avoid the warnings I might do the following:

class FooCollection<T extends InfoType> extends HashSet<Foo<T>> {
 ...
 public Foo<T> findByInfo(T info) {
   ...
 }
}

This solution eliminates the warnings but I do not like it because when
I declare a FooCollection<InfoType>, by reading the declaration, it is
not clear that I am actually instantiating a collection of
Foo<InfoType> objects but it gives the impression that I am dealing
with a InfoType collection.

The third solution is to make explicit both the InfoType and the Foo
instances contained in the collection:

class FooCollection<T extends InfoType, S extends Foo<T>> extends
HashSet<S> {
 ...
 public S findByInfo(T info) {
   ...
 }
}

This also works, but when I have to declare a FooCollection I need to
do:
FooCollection<MyInfoType, Foo<MyInfoType>> which is a bit redundant and
unclear.

I do not see any other solution to how to structure the hierarchy.

In my opinion the most elegant and simple solution is the first one.
But I would like to get rid of the warnings. Do you know how to do
this? Can you suggest another more elegant solution (if it exists?)

Thank you
zero - 02 Nov 2005 14:22 GMT
> Hello,
>
[quoted text clipped - 35 lines]
> parametric type which is not instantiated with respect to its type
> parameter.

<snipped>

I don't see the problem with your first version.  If you instantiate a
FooCollection with FooCollection<Foo<InfoType>> col = new
FooCollection<Foo<InfoType>>();
you should not get any warnings.  And it
is very clear that you are dealing with a collection of Foo objects -
and more specifically Foo<InfoType> objects.
Lemon Tree - 02 Nov 2005 14:42 GMT
> <snipped>
>
[quoted text clipped - 4 lines]
> is very clear that you are dealing with a collection of Foo objects -
> and more specifically Foo<InfoType> objects.

It gives me a warning in the definition of the findByInfo method:

Type safety: The method getInfo() belongs to the raw type Foo.
References
to generic type Foo<T> should be parameterized

That's what I would like to remove.
But I am starting to think that it is not possible.
zero - 02 Nov 2005 16:02 GMT
>> <snipped>
>>
[quoted text clipped - 13 lines]
> That's what I would like to remove.
> But I am starting to think that it is not possible.

The following quick test compiled without warnings for me.

Alternatively, have you tried

class FooCollection<T extends Foo<?>> extends HashSet<T>

This will tell the compiler you want a FooCollection of any type of Foo,
and you don't care which type - but this is still type-checked, unlike
the raw Foo in <T extends Foo>.

-- test code --

import java.util.HashSet;

public class GenericsTest
{
public static void main(String args[])
{
 new GenericsTest();
}

public GenericsTest()
{
 FooCollection<Foo<InfoType>> col = new FooCollection<Foo<InfoType>>();
}

private class InfoType implements Comparable<InfoType>
{
 public int compareTo(InfoType i)
 {
  return 0;
 }
}

private class Foo<T extends InfoType>
{
 private T info;
 public T getInfo()
 {
  return info;
 }
}

private class FooCollection<T extends Foo> extends HashSet<T>
{
 public T findByInfo(InfoType info)
 {
  for(T t : this)
  {
   if(t.getInfo().compareTo(info) == 0)
   {
    return t;
   }
  }
  return null;
 }
}
}
Lemon Tree - 02 Nov 2005 17:26 GMT
zero ha scritto:

> The following quick test compiled without warnings for me.

Your code works without any warning.
I was suprised because your code is basically identical to mine (the
one which generated the warnings). But when I tried to split your code
in several files (a class per file) the warning appeared again!

I don't know why. It would be interesting to know.

> Alternatively, have you tried
> class FooCollection<T extends Foo<?>> extends HashSet<T>

Bingo!
That works even in the "splitted" layout.

Thank you for your help.

> This will tell the compiler you want a FooCollection of any type of Foo,
> and you don't care which type - but this is still type-checked, unlike
> the raw Foo in <T extends Foo>.

Yes. That's what I missed before :)

Thank you again
zero - 02 Nov 2005 18:47 GMT
"Lemon Tree" <lemontree75@gmail.com> wrote in news:1130948806.773789.264120
@g44g2000cwa.googlegroups.com:

> zero ha scritto:
>
[quoted text clipped - 6 lines]
>
> I don't know why. It would be interesting to know.

That is indeed surprising.  I can't think of a reason that may be.  Maybe
someone else here has an idea?

>> Alternatively, have you tried
>> class FooCollection<T extends Foo<?>> extends HashSet<T>
[quoted text clipped - 11 lines]
>
> Thank you again

My pleasure
Ingo R. Homann - 02 Nov 2005 14:59 GMT
Hi,

> Hello,
>
[quoted text clipped - 5 lines]
>   }
> }

I think, this is the (only) "correct" solution:

> class FooCollection<T extends InfoType> extends HashSet<Foo<T>> {
>   ...
[quoted text clipped - 8 lines]
> Foo<InfoType> objects but it gives the impression that I am dealing
> with a InfoType collection.

Perhaps you can rename the classes, so that it becomes more obvious?
(Perhaps simply "CollectionFoo<InfoType>" or (IMHO not so good)
"CollectionOfFooOf<InfoType>")

Ciao,
Ingo


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



©2009 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.