Java creating instance of class

Creating an instance using the class name and calling constructor

Is there a way to create an instance of a particular class given the class name (dynamic) and pass parameters to its constructor. Something like:

Object object = createInstance("mypackage.MyClass","MyAttributeValue"); 

10 Answers 10

Class clazz = Class.forName(className); Constructor ctor = clazz.getConstructor(String.class); Object object = ctor.newInstance(new Object[] < ctorArgument >); 

That will only work for a single string parameter of course, but you can modify it pretty easily.

Note that the class name has to be a fully-qualified one, i.e. including the namespace. For nested classes, you need to use a dollar (as that’s what the compiler uses). For example:

package foo; public class Outer < public static class Nested <>> 

To obtain the Class object for that, you’d need Class.forName(«foo.Outer$Nested») .

newInstance() is a varargs method (just as GetConstructor() ), there’s no need for explicit Object -array creation.

@Joachim: I know it’s varargs, but as it can get tricky when you have an Object[] argument, I prefer to create the array explicitly in this case.

@JonSkeet I understand where you are coming from, however it’s not quite that simple — I did look at the docs but was confused, but also if I tested it and it worked — ok then it worked — but if it didn’t work then I would have been unsure if the problem was due to some lack of configuration or something on my part — often when asking such simple questions, people throw in useful tidbits that really help. That’s why a simple «yes that would work — if you do it this way» or «no there’s no way», really helps. But my understanding now is that there’s no way

Читайте также:  Подключение шрифта css montserrat

You can use Class.forName() to get a Class object of the desired class.

Then use getConstructor() to find the desired Constructor object.

Finally, call newInstance() on that object to get your new instance.

Class c = Class.forName("mypackage.MyClass"); Constructor cons = c.getConstructor(String.class); Object object = cons.newInstance("MyAttributeValue"); 
return Class.forName(className).getConstructor(String.class).newInstance(arg); 

If using default constructor, remove the String.class parameter value e.g. return Class.forName(className).getConstructor().newInstance(arg);

If class has only one empty constructor (like Activity or Fragment etc, android classes):

Class myClass = Class.forName("com.example.MyClass"); Constructor constructor = myClass.getConstructors()[0]; 

This is what helped me. Constructor ctor = clazz.getConstructor(String.class) didn’t seem to work for me.

when using (i.e.) getConstructor(String.lang) the constructor has to be declared public. Otherwise a NoSuchMethodException is thrown.

if you want to access a non-public constructor you have to use instead (i.e.) getDeclaredConstructor(String.lang) .

If anyone is looking for a way to create an instance of a class despite the class following the Singleton Pattern, here is a way to do it.

// Get Class instance Class clazz = Class.forName("myPackage.MyClass"); // Get the private constructor. Constructor cons = clazz.getDeclaredConstructor(); // Since it is private, make it accessible. cons.setAccessible(true); // Create new object. Object obj = cons.newInstance(); 

This only works for classes that implement singleton pattern using a private constructor.

return Class.forName(**complete classname**) .getConstructor(**here pass parameters passed in constructor**) .newInstance(**here pass arguments**); 

In my case, my class’s constructor takes Webdriver as parameter, so used below code:

return Class.forName("com.page.BillablePage") .getConstructor(WebDriver.class) .newInstance(this.driver); 

Very Simple way to create an object in Java using Class with constructor argument(s) passing:

Case 1:- Here, is a small code in this Main class:

import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; public class Main < public static void main(String args[]) throws ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException < // Get class name as string. String myClassName = Base.class.getName(); // Create class of type Base. ClassmyClass = Class.forName(myClassName); // Create constructor call with argument types. Constructor ctr = myClass.getConstructor(String.class); // Finally create object of type Base and pass data to constructor. String arg1 = "My User Data"; Object object = ctr.newInstance(new Object[] < arg1 >); // Type-cast and access the data from class Base. Base base = (Base)object; System.out.println(base.data); > > 

And, here is the Base class structure:

public class Base < public String data = null; public Base() < data = "default"; System.out.println("Base()"); >public Base(String arg1) < data = arg1; System.out.println("Base("+arg1+")"); >> 

Case 2:- You, can code similarly for constructor with multiple argument and copy constructor. For example, passing 3 arguments as parameter to the Base constructor will need the constructor to be created in class and a code change in above as:

Constructor ctr = myClass.getConstructor(String.class, String.class, String.class); Object object = ctr.newInstance(new Object[] < "Arg1", "Arg2", "Arg3" >); 

And here the Base class should somehow look like:

Note:- Don’t forget to handle the various exceptions which need to be handled in the code.

Источник

Creating New Class Instances

There are two reflective methods for creating instances of classes: java.lang.reflect.Constructor.newInstance() and Class.newInstance() . The former is preferred and is thus used in these examples because:

  • Class.newInstance() can only invoke the zero-argument constructor, while Constructor.newInstance() may invoke any constructor, regardless of the number of parameters.
  • Class.newInstance() throws any exception thrown by the constructor, regardless of whether it is checked or unchecked. Constructor.newInstance() always wraps the thrown exception with an InvocationTargetException .
  • Class.newInstance() requires that the constructor be visible; Constructor.newInstance() may invoke private constructors under certain circumstances.

Sometimes it may be desirable to retrieve internal state from an object which is only set after construction. Consider a scenario where it is necessary to obtain the internal character set used by java.io.Console . (The Console character set is stored in a private field and is not necessarily the same as the Java virtual machine default character set returned by java.nio.charset.Charset.defaultCharset() ). The ConsoleCharset example shows how this might be achieved:

import java.io.Console; import java.nio.charset.Charset; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import static java.lang.System.out; public class ConsoleCharset < public static void main(String. args) < Constructor[] ctors = Console.class.getDeclaredConstructors(); Constructor ctor = null; for (int i = 0; i < ctors.length; i++) < ctor = ctors[i]; if (ctor.getGenericParameterTypes().length == 0) break; >try < ctor.setAccessible(true); Console c = (Console)ctor.newInstance(); Field f = c.getClass().getDeclaredField("cs"); f.setAccessible(true); out.format("Console charset : %s%n", f.get(c)); out.format("Charset.defaultCharset(): %s%n", Charset.defaultCharset()); // production code should handle these exceptions more gracefully >catch (InstantiationException x) < x.printStackTrace(); >catch (InvocationTargetException x) < x.printStackTrace(); >catch (IllegalAccessException x) < x.printStackTrace(); >catch (NoSuchFieldException x) < x.printStackTrace(); >> >

Class.newInstance() will only succeed if the constructor is has zero arguments and is already accessible. Otherwise, it is necessary to use Constructor.newInstance() as in the above example.

Example output for a UNIX system:

$ java ConsoleCharset Console charset : ISO-8859-1 Charset.defaultCharset() : ISO-8859-1

Example output for a Windows system:

C:\> java ConsoleCharset Console charset : IBM437 Charset.defaultCharset() : windows-1252

Another common application of Constructor.newInstance() is to invoke constructors which take arguments. The RestoreAliases example finds a specific single-argument constructor and invokes it:

import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.util.HashMap; import java.util.Map; import java.util.Set; import static java.lang.System.out; class EmailAliases < private Setaliases; private EmailAliases(HashMap h) < aliases = h.keySet(); >public void printKeys() < out.format("Mail keys:%n"); for (String k : aliases) out.format(" %s%n", k); >> public class RestoreAliases < private static MapdefaultAliases = new HashMap(); static < defaultAliases.put("Duke", "duke@i-love-java"); defaultAliases.put("Fang", "fang@evil-jealous-twin"); >public static void main(String. args) < try < Constructor ctor = EmailAliases.class.getDeclaredConstructor(HashMap.class); ctor.setAccessible(true); EmailAliases email = (EmailAliases)ctor.newInstance(defaultAliases); email.printKeys(); // production code should handle these exceptions more gracefully >catch (InstantiationException x) < x.printStackTrace(); >catch (IllegalAccessException x) < x.printStackTrace(); >catch (InvocationTargetException x) < x.printStackTrace(); >catch (NoSuchMethodException x) < x.printStackTrace(); >> >

This example uses Class.getDeclaredConstructor() to find the constructor with a single argument of type java.util.HashMap . Note that it is sufficient to pass HashMap.class since the parameter to any get*Constructor() method requires a class only for type purposes. Due to type erasure, the following expression evaluates to true :

HashMap.class == defaultAliases.getClass()

The example then creates a new instance of the class using this constructor with Constructor.newInstance() .

$ java RestoreAliases Mail keys: Duke Fang

Источник

Is there a way to instantiate a class by name in Java?

I was looking as the question : Instantiate a class from its string name which describes how to instantiate a class when having its name. Is there a way to do it in Java? I will have the package name and class name and I need to be able to create an object having that particular name.

The answer is yes, but I think you should ask if its a good idea. With great power (reflection) comes great responsibility and you should only use it if you understand and have considered the consequences.

9 Answers 9

Method 1 — only for classes having a no-arg constructor

If your class has a no-arg constructor, you can get a Class object using Class.forName() and use the newInstance() method to create an instance (though beware that this method is often considered evil because it can defeat Java’s checked exceptions).

Class clazz = Class.forName("java.util.Date"); Object date = clazz.newInstance(); 

Method 2

An alternative safer approach which also works if the class doesn’t have any no-arg constructors is to query your class object to get its Constructor object and call a newInstance() method on this object:

Class clazz = Class.forName("com.foo.MyClass"); Constructor constructor = clazz.getConstructor(String.class, Integer.class); Object instance = constructor.newInstance("stringparam", 42); 

Both methods are known as reflection. You will typically have to catch the various exceptions which can occur, including things like:

  • the JVM can’t find or can’t load your class
  • the class you’re trying to instantiate doesn’t have the right sort of constructors
  • the constructor itself threw an exception
  • the constructor you’re trying to invoke isn’t public
  • a security manager has been installed and is preventing reflection from occurring
MyClass myInstance = (MyClass) Class.forName("MyClass").newInstance(); 

It’s worth mentioning that this doesn’t work if the class has no parameterless constructor (and has other constructors), or if the parameterless constructor is inaccessible.

Using newInstance() directly is deprecated as of Java 8. You need to use Class.getDeclaredConstructor(. ).newInstance(. ) with the corresponding exceptions.

To make it easier to get the fully qualified name of a class in order to create an instance using Class.forName(. ) , one could use the Class.getName() method. Something like:

class ObjectMaker < // Constructor, fields, initialization, etc. public Object makeObject(Classclazz) < Object o = null; try < o = Class.forName(clazz.getName()).newInstance(); >catch (ClassNotFoundException e) < // There may be other exceptions to throw here, // but I'm writing this from memory. e.printStackTrace(); >return o; > > 

Then you can cast the object you get back to whatever class you pass to makeObject(. ) :

Data d = (Data) objectMaker.makeObject(Data.class); 

use Class.forName(«String name of class»).newInstance();

This will cause class named A initialized.

Use java reflection

Creating New Objects There is no equivalent to method invocation for constructors, because invoking a constructor is equivalent to creating a new object (to be the most precise, creating a new object involves both memory allocation and object construction). So the nearest equivalent to the previous example is to say:

import java.lang.reflect.*; public class constructor2 < public constructor2() < >public constructor2(int a, int b) < System.out.println( "a = " + a + " b = " + b); >public static void main(String args[]) < try < Class cls = Class.forName("constructor2"); Class partypes[] = new Class[2]; partypes[0] = Integer.TYPE; partypes[1] = Integer.TYPE; Constructor ct = cls.getConstructor(partypes); Object arglist[] = new Object[2]; arglist[0] = new Integer(37); arglist[1] = new Integer(47); Object retobj = ct.newInstance(arglist); >catch (Throwable e) < System.err.println(e); >> > 

which finds a constructor that handles the specified parameter types and invokes it, to create a new instance of the object. The value of this approach is that it’s purely dynamic, with constructor lookup and invocation at execution time, rather than at compilation time.

Источник

Оцените статью