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.

Strange compile error involving generics (short code snippet included)

Thread view: 
Oliver Wong - 01 Nov 2005 22:46 GMT
I've got two pieces of code; one of them compiles without error, and the
other one doesn't. I can't figure out why. Here's the code snippets:

<compilesFine>
import java.util.Vector;

public class HistoryObjectsManager  {
 public void doSomethingWithRecord(Record record)  {
   for (Integer integer : record.getVector()) {
     //Does nothing.
   }
 }
}

abstract class Record {
 public Vector<Integer> getVector() {
   return new Vector<Integer>();
 }
}
</compilesFine>

<generatesCompileError>
import java.util.Vector;

public class HistoryObjectsManager  {
 public void doSomethingWithRecord(Record record)  {
   for (Integer integer : record.getVector()) {
     //Does nothing.
   }
 }
}

abstract class Record<A> {
 public Vector<Integer> getVector() {
   return new Vector<Integer>();
 }
}
</generatesCompileError>

   The only difference between the two is that Record has a type parameter.
The compile error I get is:

<errorMessage>
HistoryObjectsManager.java:5: incompatible types
found   : java.lang.Object
required: java.lang.Integer
   for (Integer integer : record.getVector()) {
                                          ^
</errorMessage>

   I'm using JavaC 1.5.0.

   Is this a bug in the compiler or a misunderstanding on my part about
generics?

   - Oliver
John C. Bollinger - 02 Nov 2005 06:43 GMT
> I've got two pieces of code; one of them compiles without error, and the
> other one doesn't. I can't figure out why. Here's the code snippets:
[quoted text clipped - 50 lines]
>     Is this a bug in the compiler or a misunderstanding on my part about
> generics?

I don't know, but I have seen similar.  It seems that the compiler
ignores all type parameters associated with a "raw" parameterized type,
such as you have in the second case.  This may be intended to provide
compilation diagnostics equivalent to those of a pre-1.5 compiler when
compiling mixed 1.[234]/1.5 codes.  In any case, if you don't care what
the Record's type parameter is then the most appropriate Java 1.5 way to
write the method is:

   public void doSomethingWithRecord(Record<?> record)  {
     for (Integer integer : record.getVector()) {
       //Does nothing.
     }
   }

I haven't actually tested it, but I bet it will do what you want.  It
has the further advantage of documenting that it in fact works with a
Record type having any type argument, which your original code does not do.

Signature

John Bollinger
jobollin@indiana.edu

Oliver Wong - 02 Nov 2005 16:15 GMT
> In any case, if you don't care what the Record's type parameter is then
> the most appropriate Java 1.5 way to write the method is:
[quoted text clipped - 8 lines]
> the further advantage of documenting that it in fact works with a Record
> type having any type argument, which your original code does not do.

   Yeah, this does fix the compile error and does seem to reflect the
"intent" of the code. Thanks.

   - Oliver
Ingo R. Homann - 02 Nov 2005 11:12 GMT
Hi,

> <generatesCompileError>
> import java.util.Vector;
[quoted text clipped - 13 lines]
> }
> </generatesCompileError>

This should work:

public void doSomethingWithRecord(Record<Integer> record)  {

Ciao,
Ingo
Ross Bamford - 02 Nov 2005 13:05 GMT
> import java.util.Vector;
> public class HistoryObjectsManager  {
[quoted text clipped - 9 lines]
>   }
> }

Heres how I see it. In the version above, Record is a generic class. When  
you say:

   public void doSomethingWithRecord(Record record)  {
     for (Integer integer : record.getVector()) {
       //Does nothing.
     }
   }

You're not just saying 'any type of record', but 'an untyped record'.  
Either the compiler assumes that you're not interested in generics at all,  
or it has no way to distinguish between literal types (like <Integer>) and  
types that are inferred (e.g. if instead of integer it was <? super  
Integer>). So, everything behaves as if there are no parameters, and the  
vector returns a untyped iterator (of Object).

If you change the method:

   public void doSomethingWithRecord(Record<?> record)  {
     for (Integer integer : record.getVector()) {
       //Does nothing.
     }
   }

You'll find it works, because you're now saying 'any type of Record'.

Signature

Ross Bamford - rosco@roscopeco.remove.co.uk

Oliver Wong - 02 Nov 2005 16:10 GMT
>> import java.util.Vector;
>> public class HistoryObjectsManager  {
[quoted text clipped - 35 lines]
>
> You'll find it works, because you're now saying 'any type of Record'.

   Notice though that the getVector() method returns a Vector<Integer>,
regardless of the type of A. This was a simplified code snippet; in the
original code, A did affect some methods, but it wasn't affecting the
getVector() method. I.e. the original code looked something like this:

<originalCode>
public class Record<A> {
 private A myValue;

 public Vector<Integer> getVector() {
   return null;
 }

 public A getInternalValue() {
   return myValue;
 }
}
</originalCode>

So no matter WHAT kind of record (whether it be Record<Object>,
Record<String> or anything else), Record's .getVector() method should ALWAYS
return a Vector<Integer>.

   - Oliver


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.