0

I have two classes which both extends Example.

public class ClassA extends Example {

    public ClassA() {
        super("a", "class");
    }
    ...
}

public class ClassB extends Example {

    public ClassB() {
        super("b", "class");
    }
    ...
}

public class Example () {

    public String get(String x, String y) {
        return "Hello";
    }
}

So thats all very well. So suppose we have another class called ExampleManager. With example manager I want to use a generic type and consequently return that generic type. e.g.

public class ExampleManager<T extends Example> {

    public T getExample() {
        return new T("example","example"); // So what exactly goes here?
    }
}

So where I am returning my generic type how do i get this to actually work correctly and cast Example as either classA or classB?

Many Thanks

Volker Stolz
  • 6,914
  • 29
  • 47
James Moore
  • 253
  • 4
  • 14
  • duplicate http://stackoverflow.com/questions/75175/create-instance-of-generic-type-in-java – unholysampler Apr 15 '10 at 20:35
  • 1
    You're looking for *Reified Generics*. This is not supported in Java. C# supports it. In Java generics are only compiletime. Lookup the factory pattern, see the above link to duplicate question for the correct answers. – BalusC Apr 15 '10 at 20:54
  • @BalusC: do you see how to apply factory pattern here? I just don't get how to implement `E create()` method in Factory (from Tom Hawtin - tackline answer http://stackoverflow.com/questions/75175/create-instance-of-generic-type-in-java/75528#75528) – Roman Apr 15 '10 at 21:17
  • @Roman: either by reflection (`Class#newInstance()` or even grabbing the constructor) or just using the `new` keyword. The factory pattern is just intented to abstract this away (which is the intent of the OP). – BalusC Apr 15 '10 at 21:22

3 Answers3

1

You can't use a generic type to instantiate new object (i.e. you can't do new T(params)).

Roman
  • 59,060
  • 84
  • 230
  • 322
1

When you are creating a concrete instance of object (that is, you use new), you have know the actual implementing class, you can't use a generic type.

What are you actually trying to achieve? How do you decide whether you want to create ClassA or ClassB?

Try this:

public class ExampleManager {
    public ClassA createClassA() {
        return new ClassA("example","example");
    }

    public ClassB createClassB() {
        return new ClassB("example","example");
    }
}

or this:

public class ExampleManager {
    public Example createExample() {
        if(a == b) {
           return new ClassB("example","example"); 
        }
        return new ClassB("example","example"); 
    }
}
Juha Syrjälä
  • 30,987
  • 31
  • 122
  • 175
0

As others have said, you can't use new to create a new instance of an unknown type. Without using reflection, you could make ExampleManager an abstract superclass of factories.

public abstract class ExampleManager<T extends Example> {
     public abstract T getExample(String x, String y);
}

public class ClassAManager extends ExampleManager<ClassA> {
     public ClassA getExample(String x, String y) {
          return new ClassA(x, y);
     }
}

public class ClassBManager extends ExampleManager<ClassB> {
     public ClassB getExample(String x, String y) {
          return new ClassB(x, y);
     }
}
ILMTitan
  • 10,147
  • 2
  • 26
  • 43