0

I'm trying to make a function that takes one of many classes that extends Foo, and return a new instance of that object in its Class, not a new instance of Foo.

I'm sure this is a common issue. Is there any good examples out there?

I have never used a class as an input parameter, only members of a class. Based on what I have searched for, this should be possible to do?

Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
SpiRail
  • 1,377
  • 19
  • 28

4 Answers4

1

Are you passing a Class object as the parameter, or in instance of a subclass of Foo?

The solution is almost the same in either case, you use the newInstance method on the Class object.

/**
 * Return a new subclass of the Foo class.
 */
public Foo fooFactory(Class<? extends Foo> c)
{
    Foo instance = null;
    try {
        instance = c.newInstance();
    }
    catch (InstantiationException e) {
        // ...
    }
    catch (IllegalAccessException e) {
        // ...
    }
    return instance; // which might be null if exception occurred,
                     // or you might want to throw your own exception
}

If you need constructor args you can use the Class getConstructor method and from there the Constructor newInstance(...) method.

Stephen P
  • 14,422
  • 2
  • 43
  • 67
  • Thanks mate. ... Seems to be working now. For other reading, After this I got one of the exceptions and solved with this thread: http://stackoverflow.com/questions/2120699/newinstance-failed-no-init – SpiRail Jan 28 '12 at 15:02
1

Your function could be like this

public class NewInstanceTest {
    public static Object getNewInstance(Foo fooObject){
        java.lang.Class fooObjectClass = fooObject.getClass();
        try {
            return fooObjectClass.newInstance();
        } catch (InstantiationException e) {
            e.printStackTrace();
            return null;
        } catch (IllegalAccessException e) {
            e.printStackTrace();
            return null;
        }
 }
 public static void main(java.lang.String[] args){
        // This prints Foo
        java.lang.System.out.println(getNewInstance(new Foo()).getClass().getName());
        // This prints Foo1
        java.lang.System.out.println(getNewInstance(new Foo1()).getClass().getName());
 }
}
class Foo{
}
class Foo1 extends Foo{
}

Hope this helps.

Ravindra Gullapalli
  • 9,049
  • 3
  • 48
  • 70
1

Look at Abstract Factory pattern.

mishadoff
  • 10,719
  • 2
  • 33
  • 55
0

You can use Java's reflection here.

If you want to get a Class by just its classname, you use Class.forName:

Class type = Class.forName('package.SomeClass');

You can check if this class is Foo or a subclass of it:

boolean isFoo = type.isAssignableFrom(Foo.class);

You can then create a new instance very easily (assuming the constructor takes no arguments):

Object instance = type.newInstance();
fivedigit
  • 18,464
  • 6
  • 54
  • 58