newInstance, generics, and "unchecked or unsafe operations"

E

Eric I.

Hi Everyone,

I'm trying to create a method in a class that takes some type of
genericized collection and creates a new, empty instance of it by
calling the newInstance method. I can get the code to work, but I do
get compiler warnings of "unchecked or unsafe operations".

Please note, I would like this code to be flexible, so whether the
method gets an ArrayList<Integer> or a LinkedList<String> it will work
and not generate compiler warnings.

In trying to hunt down a solution by reading comp.lang.java.programmer
and other online sources, I became aware of the issue of "type
erasure". In fact, at compile time I should know the full type of the
collection. Is there a way to "nicely" re-write this code, so it
doesn't generate the warning? If not "nicely" how about "nastily"?

====

import java.util.Collection;
import java.util.ArrayList;

class EmptyDuplicator<T>
{
public Collection<T> duplicateEmptyVersionOf(Collection<T>
original)
throws InstantiationException, IllegalAccessException
{
// COMPILER WARNING on next line; BUT I KNOW T at compile-
time!!!
Collection<T> emptyVersionOf =
original.getClass().newInstance();
return emptyVersionOf;
}
}


public class Sample
{
public static void main(String[] args)
throws InstantiationException, IllegalAccessException
{
ArrayList<Integer> original = new ArrayList<Integer>();
original.add(1);
original.add(2);

EmptyDuplicator<Integer> duplicator = new
EmptyDuplicator<Integer>();
Collection<Integer> clone =
duplicator.duplicateEmptyVersionOf(original);
clone.add(4);

System.out.println("original");
for(int i : original) {
System.out.println(i);
}

System.out.println("clone");
for(int i : clone) {
System.out.println(i);
}
}
}

====

Thanks in advance,

Eric
 
M

Mike Schilling

Eric said:
Hi Everyone,

I'm trying to create a method in a class that takes some type of
genericized collection and creates a new, empty instance of it by
calling the newInstance method. I can get the code to work, but I
do
get compiler warnings of "unchecked or unsafe operations".

Because of type erasure, the type of original.getClass().newInstance()
is Collection rather than Collection<T>. I wouldn't worry too much
about that warning. It really means "I can't verify that what you've
done is safe, so you're on your own."

The simplest way to prevent the warning from appearing is to annotate
the method, thus:

@SuppressWarnings("unchecked")
public Collection<T> duplicateEmptyVersionOf(Collection<T>
original)
throws InstantiationException, IllegalAccessException
{
...
 
S

softwarepearls_com

Eric, as has been documented and bemoaned extensively in the past,
generics is one of the few Java language features with which you can
hang yourself before you feel the noose around your neck. I would
humbly submit that, with generics, you need to learn things in a more
formal way than reading our posts. An excellent book is "Java Generics
and Collections" (O'Reilly). If you dive in to use generics before
understanding their basics (and erasure is part of that), you'll hang
yourself. I've done it, and I've seen others do it on a project-wide
scale.. which really, really hurts.

In my experience generics require you to be near 100% accurate in your
typing for the feature to help you. As soon as you introduce any
sloppiness in the typing, generics becomes a chronic obstacle course.

My bottom-line advice with generics is to take it very, very slowly..
and read up some authoritative text(s) on the subject.
 
R

Roedy Green

If not "nicely" how about "nastily"?

the secret is code like this:

// Make sure the class we load implements Macro.
final Class<? extends Macro> macroClass = Class.forName(
binaryClassName ).asSubclass( Macro.class );
 
S

Stanimir Stamenkov

Fri, 15 Aug 2008 00:08:17 -0700, /Eric I./:
I'm trying to create a method in a class that takes some type of
genericized collection and creates a new, empty instance of it by
calling the newInstance method. I can get the code to work, but I do
get compiler warnings of "unchecked or unsafe operations". [...]
class EmptyDuplicator<T>
{
public Collection<T> duplicateEmptyVersionOf(Collection<T>
original)
throws InstantiationException, IllegalAccessException
{
// COMPILER WARNING on next line; BUT I KNOW T at compile-
time!!!
Collection<T> emptyVersionOf =
original.getClass().newInstance();
return emptyVersionOf;
}
}

Recently one has mentioned the Class.asSubclass [1] method but I
can't figure out which is the correct syntax, or if it is possible
at all:

Class<? extends Collection<T>> c;
// Syntax error in the |Collection<T>.class| part.
c = original.getClass().asSubclass(Collection<T>.class);
Collection<T> emptyVersionOf = c.newInstance();

[1]
http://java.sun.com/javase/6/docs/api/java/lang/Class.html#asSubclass(java.lang.Class)
 
J

Joshua Cranmer

Stanimir said:
Class<? extends Collection<T>> c;
// Syntax error in the |Collection<T>.class| part.
c = original.getClass().asSubclass(Collection<T>.class);
Collection<T> emptyVersionOf = c.newInstance();

Close, but you'll need to use Collection.class and not
Collection<T>.class, which requires you to change it all to this:
Class<? extends Collection> c;
c = orginal.getClass().asSubclass(Collection.class);
Collection<T> emptyVersionOf = c.newInstance();

There's a bug, I'm not sure in the JLS or not, that Class<? extends
Collection> is not the same as Class<? extends Collection<?>> and that
Collection.class returns Class<Collection> instead of Class<Collection<?>>.

Because of the class issue, this means that you are forced to use rare
types (mixtures of generics and raw types), which is a problematic mess
that I think is underspecified in the JLS.
 
E

Eric I.

Thank you all (Mike, Roedy, Stanimir, Joshua, and softwarepearls) for
your help.

Eric
 

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

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,482
Members
44,901
Latest member
Noble71S45

Latest Threads

Top