0

There is a way to avoid the slow reflection to create an instance from a class, obviously within another method ? For example:

Foo foo = new Foo();
foo.create(Dog.class, "rocky");

class Foo {
    Object create(Class object, String dogName) {
        //create an instance of the class 'object' here passing the argument to constructor
        //e.g. Object obj = new object(dogName); <-- this is wrong

        return obj;
    }
}

class Dog extends Animal {
   Dog(String dogName) {
       this.name = dogName;
   }
}

class Animal {
    String name;
}

I cannot create the instance using the keyword "new", because I must create the instance in another method in a dynamic way...

You have carte blanche to improve in the best way (like performance) this code :) Thank you!

Manuel Di Iorio
  • 3,631
  • 5
  • 29
  • 31
  • 1
    Well, the obvious choice is a `switch` statement to select from among the possible `new SomeClass()` invocations. Next would be to use ClassLoader.loadClass to get a Class pointer, then Class.newInstance(). After that are the reflections options. – Hot Licks Mar 19 '14 at 01:06
  • The "switch" no because the result it should be as dynamic as well (for the final user).. I'm looking for other solutions like hot licks suggests, thank you guys – Manuel Di Iorio Mar 19 '14 at 02:50

2 Answers2

3

Leave your Dog and Animal classes the same. and use the Builder pattern

  public interface Builder<T> {
  public T build(String nameString);
}
public static void main(String[] args){
  Builder<Dog> builder =  new Builder<Dog>()
  {

     @Override
     public Dog build(String nameString)
     {
        return new Dog(nameString);
     }

  };
 Dog dog = builder.build("Rocky");
 System.out.print(dog.name);

}

The answers over at Instantiating object of type parameter explain it further as well.

Community
  • 1
  • 1
James Kidd
  • 444
  • 4
  • 8
2
public <T> T create(Class<T> myClass, String constructorArg) 
throws IllegalArgumentException, InstantiationException, IllegalAccessException, InvocationTargetException, SecurityException, NoSuchMethodException {
    Constructor<T> toCall = myClass.getConstructor(String.class);
    return toCall.newInstance(constructorArg);
}
Dawood ibn Kareem
  • 77,785
  • 15
  • 98
  • 110
  • error: "Found too many characters { without a } to match it." at the row of the "throws" keyword – Manuel Di Iorio Mar 19 '14 at 01:20
  • 1
    Sorry, I added the `throws` clause at the wrong place. I've fixed it now. – Dawood ibn Kareem Mar 19 '14 at 01:31
  • O.O Now "error noSuchMethodException" at row of the "[...] myClass.getConstructor( [..]" :O – Manuel Di Iorio Mar 19 '14 at 01:45
  • 1
    So do you have a constructor, in the class that you're using, that takes only a `String` as an argument? That message says otherwise. – Dawood ibn Kareem Mar 19 '14 at 01:46
  • I have replaced with .getConstructor(float.class, float.class) because the constructor requires two floats arguments but still raises the same error – Manuel Di Iorio Mar 19 '14 at 02:10
  • So you wrote `myClass.getConstructor(float.class,float.class)` and then `toCall.newInstance(float1, float2)` or something of that kind? – Dawood ibn Kareem Mar 19 '14 at 02:40
  • yes, see the code here if you want :) http://stackoverflow.com/questions/22495012/strange-error-in-java-reflection-processing – Manuel Di Iorio Mar 19 '14 at 02:45
  • 1
    It looks from that example like `Dog` is a non-static inner class of something else. You never told us that. If that's the case, you need to pass a reference to an object of the outer class as the first argument of `newInstance`; and the type of it as the first argument to `getConstructor`. – Dawood ibn Kareem Mar 19 '14 at 02:59