70

Is there a way to create a new class from a String variable in Java?

String className = "Class1";
//pseudocode follows
Object xyz = new className(param1, param2);

Also, if possible does the resulting object have to be of type Object?

There may be a better way, but I want to be able to retrieve values from an XML file, then instantiate the classes named after those strings. Each of these classes implement the same interface and are derived from the same parent class, so I would then be able to call a particular method in that class.

jpaugh
  • 6,634
  • 4
  • 38
  • 90
jW.
  • 9,280
  • 12
  • 46
  • 50

6 Answers6

125

This is what you want to do:

String className = "Class1";
Object xyz = Class.forName(className).newInstance();

Note that the newInstance method does not allow a parametrized constructor to be used. (See Class.newInstance documentation)

If you do need to use a parametrized constructor, this is what you need to do:

import java.lang.reflect.*;

Param1Type param1;
Param2Type param2;
String className = "Class1";
Class cl = Class.forName(className);
Constructor con = cl.getConstructor(Param1Type.class, Param2Type.class);
Object xyz = con.newInstance(param1, param2);

See Constructor.newInstance documentation

Dawie Strauss
  • 3,706
  • 3
  • 23
  • 26
  • 6
    You can use getConstructor for a parameterized constructor. – CodeGoat Aug 12 '09 at 21:44
  • You are right CodeGoat, I did not know that. I'll edit my answer to reflect the better way. – Dawie Strauss Aug 12 '09 at 21:53
  • I think that using getConstuctor is better than using the init method. As using a constructor allows for final fields to be assigned. – pjp Aug 12 '09 at 21:55
  • Change line 7 to: Constructor con = cl.getConstructor(new Class[] {Param1Type.class, Param2Type.class}); – macio.Jun Jul 23 '13 at 19:39
  • So, once we create the `object xyz`, can we cast it to our own object? – Sam YC Mar 14 '14 at 02:49
  • 1
    You should also be aware if you use: Object xyz = Class.forName(className).newInstance(); you will silently convert checked exceptions to unchecked exceptions. More details in this answer: http://stackoverflow.com/a/7495850/411401 – diadyne Dec 02 '14 at 00:19
  • Is this code possible for a class which is never defined in the system, and it makes a dynamic class in the memory?? – Abdeali Chandanwala Dec 16 '17 at 11:24
14

Yes, you can load a class on your classpath given the String name using reflection, using Class.forName(name), grabbing the constructor and invoking it. I'll do you an example.

Consider I have a class:

com.crossedstreams.thingy.Foo

Which has a constructor with signature:

Foo(String a, String b);

I would instantiate the class based on these two facts as follows:

// Load the Class. Must use fully qualified name here!
Class clazz = Class.forName("com.crossedstreams.thingy.Foo");

// I need an array as follows to describe the signature
Class[] parameters = new Class[] {String.class, String.class};

// Now I can get a reference to the right constructor
Constructor constructor = clazz.getConstructor(parameters);

// And I can use that Constructor to instantiate the class
Object o = constructor.newInstance(new Object[] {"one", "two"});

// To prove it's really there...
System.out.println(o);

Output:

com.crossedstreams.thingy.Foo@20cf2c80

There's plenty of resources out there which go into more detail about this, and you should be aware that you're introducing a dependency that the compiler can't check for you - if you misspell the class name or anything, it will fail at runtime. Also, there's quite a few different types of Exception that might be throws during this process. It's a very powerful technique though.

brabster
  • 42,504
  • 27
  • 146
  • 186
  • Question: Now that we have created an object of `Foo`, how can we call a public function of `Foo` using that object? How can we cast it into a `Foo` reference? – Bugs Happen Mar 07 '17 at 15:59
  • You can just cast as you would any object. `(Foo)o` or `Foo.class.cast(o)`. You probably don't want to do that, though, as it'd be pointless going through this if you know what the implementation class is - you could just import it! What you'd actually do is cast to an interface that the implementation must implement, which you *have* imported. – brabster Mar 09 '17 at 09:57
2

This should work:

import java.lang.reflect.*;

FirstArgType arg1;
SecondArgType arg2;
Class cl = Class.forName("TheClassName");
Constructor con = cl.getConstructor(FirstArgType.class, SecondArgType.class);
Object obj = con.newInstance(arg1, arg2);

From there you can cast to a known type.

CodeGoat
  • 1,186
  • 8
  • 6
2

This worked a little more cleanly for me in JDK7, while the answers above made things a bit more difficult than they needed to be from a newbie perspective: (assumes you've declared 'className' as a String variable passed as a method parameter or earlier in the method using this code):

Class<?> panel = Class.forName( className );
JPanel newScreen = (JPanel) panel.newInstance();

From this point you can use properties / methods from your dynamically-named class exactly as you would expect to be able to use them:

JFrame frame = new JFrame(); // <<< Just so no-one gets lost here
frame.getContentPane().removeAll();
frame.getContentPane().add( newScreen );
frame.validate();
frame.repaint();

The examples in other answers above resulted in errors when I tried to .add() the new 'Object' type object to the frame. The technique shown here gave me a usable object with just those 2 lines of code above.

Not exactly certain why that was - I'm a Java newbie myself.

Ragdata
  • 1,156
  • 7
  • 16
0

Another one:

import java.lang.reflect.Constructor;

public class Test {

 public Test(String name) {
    this.name = name;
 }

 public String getName() {
    return name;
 }

 public String toString() {
    return this.name;
 }

 private String name;

 public static void main(String[] args) throws Exception {
    String className = "Test";
    Class clazz = Class.forName(className);
    Constructor tc = clazz.getConstructor(String.class);
    Object t = tc.newInstance("John");
    System.out.println(t);
 }
}
rodrigoap
  • 7,405
  • 35
  • 46
0

A Sample Program to Get Instance of a class using String Object.

public class GetStudentObjectFromString
{
    public static void main (String[] args) throws java.lang.Exception
    {
        String className = "Student"; //Passed the Class Name in String Object.

         //A Object of Student will made by Invoking its Default Constructor.
        Object o = Class.forName(className).newInstance(); 
        if(o instanceof Student) // Verify Your Instance that Is it Student Type or not?
        System.out.println("Hurrey You Got The Instance of " + className);
    }
}
class Student{
    public Student(){
        System.out.println("Constructor Invoked");
    }

}

Output :-

 Constructor Invoked
 Hurrey You Got The Instance of Student
Vikrant Kashyap
  • 6,398
  • 3
  • 32
  • 52