954,554 Members — Technology Publication meets Social Media
Username:
Password:
Lost login information?
Have something to say? Contribute New Article Reply to this Article

MyGenericClass vs. Type Erasure: What's the best solution?

Hello. It's been a while since I was on here.

I'm writing a Java class with a generic type parameter. Among other things, it maintains an internal ArrayList of the same generic type as itself. In a perfect world, the code would go like this:

import java.util.ArrayList;
public class MyGenericClass<T> {
    private ArrayList<T> items;
    public MyGenericClass() {
        items = new ArrayList<T>();
    }
}


Unfortunately, we do not live in a perfect world, and this doesn't work because of type erasure.

The only solution I can think of is to instantiate a raw ArrayList. (This will never result in a ClassCastException; I can guarantee that no non-T objects will ever be stored in the ArrayList.) However, I know that this is not good practice; in fact, I've actually heard from more than one authoritative source that raw types shouldnever be instantiated except in legacy code.

Is there a better way? Thanks for your time.

JDCyrus
Light Poster
27 posts since Jun 2008
Reputation Points: 10
Solved Threads: 2
 

I don't have the references in front of me right now, but there is a solution that involves passing a "dummy" arg to the constructor whose type has to be , then you can use the class of that param at runtime to instantiate your own vars with the same class. (I guess that's what's happening when you pass an empty array to ArrayList's toArray mathod.)

JamesCherrill
Posting Genius
Moderator
6,373 posts since Apr 2008
Reputation Points: 2,130
Solved Threads: 1,073
 
JamesCherrill
Posting Genius
Moderator
6,373 posts since Apr 2008
Reputation Points: 2,130
Solved Threads: 1,073
 

I looked at the "hideous workaround". It seems to be meant for instantiating a generic class with a wildcard as the type parameter (and I cannot imagine why anyone would want to unleash such a monstrosity). What I'm trying to do isn't as extreme as that; I just want to instantiate one generic class from inside another, and pass the type parameter from the latter to the former.

My assumption, upon seeing that this didn't work, was that it was forbidden by type erasure. However, the code from the workaround posted above (which does work; I tested it) does instantiate a generic class using a parameterized type, rather than a hard-coded one; this happens in all five Factory.make methods. How come she can do it and I can't? Is it because that code uses a method type parameter and mine uses a class type parameter? That doesn't seem right.

Presumably, this would have to be answered by someone who has a fairly deep understanding of the details of generics.

JDCyrus
Light Poster
27 posts since Jun 2008
Reputation Points: 10
Solved Threads: 2
 
Unfortunately, we do not live in a perfect world, and this doesn't work because of type erasure.


Why doesn't it work? Instantiating a type parameter won't work, but instantiating parameterized classes which accept a type argument will. The below snippet won't work, but what you posted will.

// doesn't work
public class MyGenericClass<T> {

    private T item;

    public MyGenericClass() {
        item = new T();
    }

}
~s.o.s~
Failure as a human
Administrator
11,938 posts since Jun 2006
Reputation Points: 3,281
Solved Threads: 734
 
Why doesn't it work? Instantiating a type parameter won't work, but instantiating parameterized classes which accept a type argument will. The below snippet won't work, but what you posted will.


You are correct. It turned out that the class I was trying to instantiate was actually an interface. The compiler said it couldn't be instantiated, but not why, so I assumed type erasure was to blame.

Thank you for helping.

JDCyrus
Light Poster
27 posts since Jun 2008
Reputation Points: 10
Solved Threads: 2
 

This question has already been solved

Post: Markdown Syntax: Formatting Help
You
View similar articles that have also been tagged: