1

So I am attempting to create a class which uses a generic which extends an abstract class. Ex.

public abstract class Template<C extends Abstract>

However, I need to instantiate this 'C' within my class. I figured I might be able to do this:

C s = (C) ((C)new Object()).getClass().getConstructor(Known.class,AnotherKnown.class).newInstance(objectOfKnownType,objectOfAnotherKnownType);

So my question is basically whether this is possible. I feel like the

((C) new Object()).getClass()

might give me some problems.

What if i changed it to:

C a;
C s = (C) (a.getClass().getConstructor( ... ).newInstance( ... ));

1 Answers1

5
(C) new Object()

is not valid and may give you a ClassCastException later, since an Object is not a C.

The way generics are implemented means Template will have no knowledge of the C it was instantiated with, you will have to create a method or constructor that takes a Class object.

public abstract class Template<C extends Abstract>
{
    private Class<C> classOfC;

    public Template( Class<C> clazz ) {
        classOfC = clazz;
    }
}
Paul Bellora
  • 54,340
  • 18
  • 130
  • 181
K-ballo
  • 80,396
  • 20
  • 159
  • 169
  • Note that this is due to the nature of the generics in Java Bytecode. In .NET you can access this information using reflection. – dtech Jun 03 '12 at 23:36
  • Shouldn't that be `Class`? – Jeffrey Jun 03 '12 at 23:38
  • @Jeffrey: It could be, but again generics have no notion of the argument they are instantiated with... – K-ballo Jun 03 '12 at 23:39
  • That said, it's advisable to use a factory object instead, as reflection is pretty fragile. (Many objects _deliberately_ don't expose constructors...) – Louis Wasserman Jun 03 '12 at 23:42
  • @K-ballo Well, if it isn't `Class`, your solution would no longer be type safe. You could pass `Object.class` into that constructor and the compiler wouldn't be any the wiser. – Jeffrey Jun 03 '12 at 23:43
  • @LouisWasserman what do you mean factory object? would that piece of code be considered poor programming practice? – user1434140 Jun 03 '12 at 23:47
  • http://stackoverflow.com/questions/10830865/instantiate-generic-type-in-java/10830904#10830904 – Louis Wasserman Jun 04 '12 at 03:09
  • "will give you a ClassCastException" No it won't, not there, if the erasure of `C` is `Object`, since, as you say, "Template will have no knowledge of the C it was instantiated with". It may (or may not) give you a ClassCastException later on depending on whether you return that value outside the scope of the erasure – newacct Jun 04 '12 at 03:13
  • @newacct: Great point you make, feel free to edit my answer to include that information. – K-ballo Jun 04 '12 at 03:21