If we ever need to instantiate a bunch of objects, and the order of instantiation needs to be set dynamically, we can take a good use of the class Class and its method forName which receives an String and returns a Class.
For example:
Class i = Class.forName(”java.lang.String”);
String x = (String)i.newInstance();
This would create an String’s instance in x.
But there’s more, you can use this with the Constructor class.
Let’s suppose we have two objects (A,B) implementing an interface like this:
interface IFigure{
public void setName(String name);
}
class A implements IFigure{
int idx;
String name;
public A(){ idx=20; }
public A(int i){ idx=i; }
public String toString(){return “Obj_A(”+idx+”): “+this.name;}
}
class B implements IFigure{
int idx;
String name;
public B(){ idx=10; }
public B(int i){ idx= (i>0) ? (i*3) : 0; //if i>0 then idx=i*3 else i=0 }
public void setName(String name){this.name = name;}
public String toString(){return “Obj_B(”+idx+”): “+this.name;}
}
and we want to instantiate them, we can use this:
//The classical way:
A cA = new A();
cA.setName(”Manolo”);
System.out.println(cA);
//A dynamic way:
try{
Class generic = Class.forName(”A”);
Constructor constructor[] = generic.getDeclaredConstructors();
//Careful with the index of the array!!!!
IFigure figObj = (IFigure) constructor[1].newInstance(new Object[0]); //equals new A();
figObj.setName(”Manolo”);
System.out.println(”A dynamic way: \n”+figObj);
}catch(Exception e){
e.printStackTrace();
}
In the last example, I’ve used the method getDeclaredConstructors() which returns an array with all the declared constructors of the class without an order.
Because this is very annoying, we can use instead:
Constructor c = generic.getConstructor(new Class[]{int.class})
where we explicitly indicate which constructor we want to use.
Here is a whole example:
/**
* @author Juan Luis Jiménez Rumí (www.jjrumi.com/blog)
*
*/
import java.lang.*;
import java.lang.reflect.Constructor;
interface IFigure{
public void setName(String name);
}
class A implements IFigure{
int idx;
String name;
public A(){ idx=-999; }
public A(int i){ idx=i; }
public void setName(String name){ this.name = name; }
public String toString() {return “Name_A: “+name+”. Idx: “+idx;}
}
class B implements IFigure{
int idx;
String name;
public B(){ idx=-999; }
public B(int i){
idx= (i>0) ? (i*3) : 0; //if i>0 then idx=i*3 else i=0
}
public void setName(String name){ this.name = name; }
public String toString() {return “Name_B: “+name+”. Idx: “+idx;}
}
public class test{
String ArrayObjects[] = {”A”,”B”,”C”};
public test(){
IFigure figObj = null;
Constructor constructor[] = null;
Class generic =null;
int flag=2;
switch(flag){
case 1:
//The classical way:
A cA = new A();
cA.setName(”Manolo”);
//A dynamic way (with same result):
try{
generic = Class.forName(ArrayObjects[0]);
constructor = generic.getDeclaredConstructors();
figObj = (IFigure) constructor[1].newInstance(new Object[0]); //equals: new A();
figObj.setName(”Manolo”);
System.out.println(”A classical way: \n”+cA+”\n”);
System.out.println(”A dynamic way: \n”+figObj);
}catch(Exception e){
e.printStackTrace();
}
break;
case 2:
//The classical way:
B cB = new B(23);
cB.setName(”Manolo”);
//A dynamic way (with same result):
try{
generic = Class.forName(ArrayObjects[1]);
Constructor c = generic.getConstructor(new Class[]{int.class});
//equals new B(23);
figObj = (IFigure) c.newInstance(new Object[]{new Integer(23)});
figObj.setName(”Manolo”);
System.out.println(”A classical way: \n”+cB+”\n”);
System.out.println(”A dynamic way: \n”+figObj);
}catch(Exception e){
e.printStackTrace();
}
break;
}
}
public static void main(String args[]){
try{
//Just instantiating an object from the java.lang.String class and using its *default* constructor.
Class i = Class.forName(”java.lang.String”);
String x = (String)i.newInstance();
x += “some text”;
System.out.println(”First Example: “+x+”\n———-\n”);
test t = new test();
}catch(Exception e){
e.printStackTrace();
}
}
}
Be mad!