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 / May 2006

Tip: Looking for answers? Try searching our database.

Type-safe array creation

Thread view: 
Mike Schilling - 13 May 2006 14:11 GMT
Fooling around with generics, trying to create a type-safe list-like class,
and started with the following:

public class Glist<T>
{
   private Class<T> etype;

   private T[] elements;

   public Glist(Class<T> cls, int size)
   {
       etype = cls;
       // the next line gets an unchecked warning
       elements = (T[]) java.lang.reflect.Array.newInstance(cls, size);
  }

   public T get(int i)
   {
       return elements[i];
   }

   public void set(T t, int i)
   {
       elements[i] = t;
   }
}

Which is fine, other than the redundancy in calls to the constructor, e.g.:

   Glist<String> g = new Glist<String>(String.class, 10);

except for the unchecked warning.  I looked at the Javadoc for both String
and Arrays, but couldn't find a type-safe way to create an array from a
Class instance.  Am I missing something?
Thomas Hawtin - 13 May 2006 14:20 GMT
> Which is fine, other than the redundancy in calls to the constructor, e.g.:
>
>     Glist<String> g = new Glist<String>(String.class, 10);

You can add a creation method:

    public static <T> Glist create(Class<T> cls, size) {
        return new Glist<T>(cls, size);
    }

Which can be used as:

    Glist<String> g = Glist.create(String.class, 10);

That even works if you don't pass the Class object.

> except for the unchecked warning.  I looked at the Javadoc for both String
> and Arrays, but couldn't find a type-safe way to create an array from a
> Class instance.  Am I missing something?

The Array.newInstance was designed long before generics. You can pass
int.class to it and get an int[] back. There is no way you can express
that sort of thing in Java generics. Perhaps it would be tidier to have
Array.newReferenceArrayInstance, but no such method exists, yet.

Tom Hawtin
Signature

Unemployed English Java programmer
http://jroller.com/page/tackline/

Mike Schilling - 13 May 2006 16:08 GMT
> The Array.newInstance was designed long before generics. You can pass
> int.class to it and get an int[] back. There is no way you can express
> that sort of thing in Java generics. Perhaps it would be tidier to have
> Array.newReferenceArrayInstance, but no such method exists, yet.

Or

   T[] Class<T>.newArray(int size)

which I was (naively) expecting to find.
Mike Schilling - 13 May 2006 16:20 GMT
>> Which is fine, other than the redundancy in calls to the constructor,
>> e.g.:
[quoted text clipped - 6 lines]
>         return new Glist<T>(cls, size);
>     }

A slight change seems to work better:

   public static <T> Glist<T> create(Class<T> cls, size)

Now it returns the correct sort of Glist, which avoids an "unchecked" cast
for its callers.
Googmeister - 13 May 2006 15:16 GMT
> Fooling around with generics, trying to create a type-safe list-like class,
> and started with the following:
[quoted text clipped - 30 lines]
> and Arrays, but couldn't find a type-safe way to create an array from a
> Class instance.  Am I missing something?

There's no way to do it without a cast somewhere (as far as I know).
The underlying cause is that arrays in Jave are covariant, but
generics are not. In other words, String[] is a subtype of Object[],
but Glist<String> is not a subtype of Glist<Object>.

Note that the following version does essentially the same
thing, but avoids passing around the Class.

public class Glist<T>
{
   private T[] elements;

   public Glist(int size)
   {
       // the next line still gets an unchecked warning
       elements = (T[]) new Object[size];
  }

   public T get(int i)
   {
       return elements[i];
   }

   public void set(T t, int i)
   {
       elements[i] = t;
   }

}
Mike Schilling - 13 May 2006 16:11 GMT
> There's no way to do it without a cast somewhere (as far as I know).
> The underlying cause is that arrays in Jave are covariant, but
> generics are not. In other words, String[] is a subtype of Object[],
> but Glist<String> is not a subtype of Glist<Object>.

This works because arrays know at runtime what their element type is (and
can throw an exception rather than add a bad element) where the JDK's
generic collection objects don't.  That's really what I was fooling around
with, investigating generic collections that *do* know their element type.


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.