Create New Object from a String in Java

Create new object from a string in Java

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

Creating an instance from String in Java

Class c= Class.forName(className);
return c.getDeclaredConstructor().newInstance();//assuming you aren't worried about constructor .
  • javadoc

For invoking constructor with argument

 public static Object createObject(Constructor constructor,
Object[] arguments) {

System.out.println("Constructor: " + constructor.toString());
Object object = null;

try {
object = constructor.newInstance(arguments);
System.out.println("Object: " + object.toString());
return object;
} catch (InstantiationException e) {
//handle it
} catch (IllegalAccessException e) {
//handle it
} catch (IllegalArgumentException e) {
//handle it
} catch (InvocationTargetException e) {
//handle it
}
return object;
}
}

have a look

How to create a new type of object based on a String?

So many answers, all missing one core point:

Java is a statically typed language. Doing everything on string basis is not the way to go in Java. You try to avoid such code!

In other words: your first mistake is to create those different classes and carry around a "name" String. You could do something like:

abstract class Fruit {
@Override
public final String toString() {
return getClass().getSimpleName() + getSize();
}

abstract String getSize();

instead. This will make sure that the string representation of any fruit simply gives the (short) class name (without package information) and whatever the subclasses implementation of getSize() returns.

You can use that like:

class Orange extends Fruit {
private String size;
Orange(String size) { this.size = size; };
String getSize() { return size; }

For Oranges, that can have different sizes; but also

class Apple extends Fruit {
String getSize() { return "always the same"; }

which in my examples are using the same size!

For creating objects, you rather go for a factory method, like:

Fruit createByName(String fruitName) {
switch (fruitName) {
case "Orange": return new Orange();
case ...
default: throw new IllegalArgumentException("unknown fruit: " + fruitName);
}
}

Create new Objects based on a String with Java Stream

You don't want to do that inline in a stream. Instead, write a helper method that does just that:

private static Product createByString(String name) {
// I assume Product is a common superclass
// TODO: implement
}

Now the question is: How should this method be implemented?

  1. Use a big switch statement.

    private static Product createByString(String name) {
    switch (name) {
    case "productA": new productA();
    case "productB": new productB();
    // ... maybe more?
    default: throw new IllegalArgumentException("name " + name + " is not a valid Product");
    }
    }

    Pro: a switch on a string is compiled into a jumptable, so you won't have n string comparisons.

    Con: You can't extend it at runtime, and you have to keep this method in sync.

  2. Use a HashMap<String,Supplier<Product>>.

    private static final Map<String,Supplier<Product>> productConstructors = new HashMap<>();
    static {
    productConstructors.put("productA", productA::new);
    productConstructors.put("productB", productB::new);
    }
    private static Product createByString(String name) {
    Supplier<Product> constructor = productConstructors.get(name);
    if (constructor == null) {
    // Handle this?
    throw new IllegalArgumentException("name " + name + " is not a valid Product");
    }
    return constructor.get();
    }

    Pro: with some easy modifications you can add new products to this implementation, or even replace them.

    Con: has some moderate overhead, and you still need to maintain a the mapping between "productA" and it's type.

  3. Use reflection.

    The good old hammer where every problem looks like a nail.

    private static Product createByString(String name) {
    try {
    return Class.forName("your.pkgname. " + name).asSubclass(Product.class).getConstructor().newInstance();
    } catch (ReflectiveOperationException e) {
    throw new RuntimeException(e);
    }
    }

    Pro: You don't need to do the binding.

    Con: It's slow.

Where is the new Object of String created when we concat using + operator

First of all String s = new String("abs"); It will create two objects, one object in the pool area and another one in the non-pool area because you are using new and as well as a string literal as a parameter.

String str1 = "Hello";
String str2 = "World";
String str3 = new String("HelloWorld");
String str4 = str1 + str2;

Till now you have five String objects, four in String Constant Pool and one in Heap. So your str4 is a new object altogether inside the String Pool,
Please check the below code also,

 String str5="HelloWorld"; //This line will create one more String Constant Pool object because we are using the variable name as str5.
String str6="HelloWorld";////This line will not create any object, this will refer the same object str5.

For test

System.out.println(str3==str4); //false
System.out.println(str4==str5);//false
System.out.println(str5==str6);//true

How java create objects implicitly? Like in case of String class

No, String instantiation is handled implicitly by the compiler. Only the String and Array classes have this property.

String greeting = "Hello world!";
char[] helloArray = { 'h', 'e', 'l', 'l', 'o', '.' };

Autoboxing allows you to implicitly instantiate objects of primitive wrapper types, but that's also a special case handled by the compiler. You can't create your own classes with this ability.

Boolean b = false;
Integer i = 0;
Double pi = 3.1416;

Take in String and create object from class of that name

You can do just that, if I understand you correctly:

String className = "com.mypackage.Dog";
Class<?> myClass = Class.forName(className);
Dog dog = (Dog) myClass.newInstance();

Strings are objects in Java, so why don't we use 'new' to create them?

In addition to what was already said, String literals [ie, Strings like "abcd" but not like new String("abcd")] in Java are interned - this means that every time you refer to "abcd", you get a reference to a single String instance, rather than a new one each time. So you will have:

String a = "abcd";
String b = "abcd";

a == b; //True

but if you had

String a = new String("abcd");
String b = new String("abcd");

then it's possible to have

a == b; // False

(and in case anyone needs reminding, always use .equals() to compare Strings; == tests for physical equality).

Interning String literals is good because they are often used more than once. For example, consider the (contrived) code:

for (int i = 0; i < 10; i++) {
System.out.println("Next iteration");
}

If we didn't have interning of Strings, "Next iteration" would need to be instantiated 10 times, whereas now it will only be instantiated once.



Related Topics



Leave a reply



Submit