92

I would like to instantiate an object from its Class object, using the constructor that accepts a single String argument.

Here is some code that approaches what I want:

Object object = null;
Class classDefinition = Class.forName("javax.swing.JLabel");
object = classDefinition.newInstance();

However, it instantiates the JLabel object with no text. I would like to use the JLabel constructor that accepts a string as the initial text. Is there a way to select a specific constructor from a Class object?

Ravindra babu
  • 37,698
  • 11
  • 250
  • 211
HAMID
  • 965
  • 1
  • 7
  • 7

4 Answers4

141

Class.newInstance invokes the no-arg constructor (the one that doesn't take any parameters). In order to invoke a different constructor, you need to use the reflection package (java.lang.reflect).

Get a Constructor instance like this:

Class<?> cl = Class.forName("javax.swing.JLabel");
Constructor<?> cons = cl.getConstructor(String.class);

The call to getConstructor specifies that you want the constructor that takes a single String parameter. Now to create an instance:

Object o = cons.newInstance("JLabel");

And you're done.

P.S. Only use reflection as a last resort!

mwittrock
  • 2,871
  • 1
  • 17
  • 20
  • 8
    "as a last resort". There are actually problems where it's the first and only option so not sure why you decided to qualify your post like that. – gshauger May 07 '19 at 16:39
  • 1
    @gshauger That's exactly why he said "as a last resort" and not "never". Sometimes, it's the only option. But most of the time, there are alternate options that are going to have better performance, more clear code, and less exception handling. – cdgraham Sep 26 '22 at 18:25
16

The following will work for you. Try this,

Class[] type = { String.class };
Class classDefinition = Class.forName("javax.swing.JLabel"); 
Constructor cons = classDefinition .getConstructor(type);
Object[] obj = { "JLabel"};
return cons.newInstance(obj);
Răzvan Petruescu
  • 685
  • 1
  • 8
  • 16
Jothi
  • 14,720
  • 22
  • 68
  • 93
3

Class.forName("className").newInstance() always invokes no argument default constructor.

To invoke parametrized constructor instead of zero argument no-arg constructor,

  1. You have to get Constructor with parameter types by passing types in Class[] for getDeclaredConstructor method of Class
  2. You have to create constructor instance by passing values in Object[] for
    newInstance method of Constructor

Example code:

import java.lang.reflect.*;

class NewInstanceWithReflection{
    public NewInstanceWithReflection(){
        System.out.println("Default constructor");
    }
    public NewInstanceWithReflection( String a){
        System.out.println("Constructor :String => "+a);
    }
    public static void main(String args[]) throws Exception {

        NewInstanceWithReflection object = (NewInstanceWithReflection)Class.forName("NewInstanceWithReflection").newInstance();
        Constructor constructor = NewInstanceWithReflection.class.getDeclaredConstructor( new Class[] {String.class});
        NewInstanceWithReflection object1 = (NewInstanceWithReflection)constructor.newInstance(new Object[]{"StackOverFlow"});

    }
}

output:

java NewInstanceWithReflection
Default constructor
Constructor :String => StackOverFlow
Ravindra babu
  • 37,698
  • 11
  • 250
  • 211
2

Some times it's not necessary to create object for the class to call is constructors and methods. You can call methods of class without creating direct object. It's very easy to call a constructor with parameter.

import java.lang.reflect.*;
import java.util.*;

class RunDemo
{
    public RunDemo(String s)
    {
        System.out.println("Hello, I'm a constructor. Welcome, "+s);
    }  
    static void show()
    {
        System.out.println("Hello.");
    }
}
class Democlass
{
    public static void main(String args[])throws Exception
    {
        Class.forName("RunDemo");
        Constructor c = RunDemo.class.getConstructor(String.class);  
        RunDemo d = (RunDemo)c.newInstance("User");
        d.show();
    }
}

the output will be:

Hello, I'm a constructor. Welcome, User

Hello.

Class.forName("RunDemo"); will load the RunDemo Class.

Constructor c=RunDemo.class.getConstructor(String.class); getConstructor() method of Constructor class will return the constructor which having String as Argument and its reference is stored in object 'c' of Constructor class.

RunDemo d=(RunDemo)c.newInstance("User"); the method newInstance() of Constructor class will instantiate the RundDemo class and return the Generic version of object and it is converted into RunDemo type by using Type casting.

The object 'd' of RunDemo holds the reference returned by the newInstance() method.

AustinWBryan
  • 3,249
  • 3
  • 24
  • 42