How to instantiate class from String?

instantiate class from string

I have the car class

class car {
...
}

how can I do

ArrayList <Object> cars = new ArrayList <Object> (); // Create an ArrayList object

String s = "car"

cars.add (new s())

I tried this but it gives me an error

 
    try {     
   cars.add(  Class.forName( getClass().getName() +"$car").newInstance() );
    
 } catch ( Exception e) {print(e);}
java.lang.InstantiationException: car_game$car

what I mean is instantiate a class from a string
something like new “car” (), not new car ()
I have a .txt file with the name of several classes.

txt file cars.txt
------
car_mo
car_sd
car_dave
----

and when loading the .txt I want to instantiate the classes that the .txt has written.

ej

String[]  txt=loadString("cars.txt")
cars.add (new txt[0]())  //instead of   cars.add (new car_mo())
cars.add (new txt[1]())  //instead of   cars.add (new car_sd())

i am using ide processing , windows7

Do

cars.add (new car(s) ) ;

And you need your constructor to look like this

class car {
   String name;
   car(String s) {
      name = s;
   } 
}

Also your arraylist should now be

ArrayList <car> cars = new ArrayList <car> ();
2 Likes

what I mean is instantiate a class from a string
something like new “car” (), not new car ()
I have a .txt file with the name of several classes and when loading the .txt I create the classes that have the txt written.

I would not suggest to use reflection for that. You have a limited number of classes you want to instantiate, so what you usually do in software engineering is using a factory pattern.

Just create a factory that takes in a string and creates your class. The advantage over reflection is speed and also it is less error prone.

Or try to think about, if the car characteristic “mo, sd, dave” could not be an attribute of the class? Why does it have to be it’s own class (does it even have it’s own behaviour)? The need to use reflection usually is an indicator of a problem in your object oriented architecture and not the solution to it.

4 Likes

What is the difference between these classes?

Hi,

I looked at :

And tried this in plain Java and can’t figure how to get it work :

// Test.java

public class Test {

  class TestA {
    TestA() {}
  }

  class TestB {
    TestB() {}
  }

  class TestC {
    TestC() {}
  }

  public static void main(String[] args) {
    try {
      Object test = Class.forName("Test$TestA").newInstance();
    } catch(Exception e) {
      System.out.println(e);
    }
  }
}
$ javac Test.java && java Test
java.lang.InstantiationException: Test$TestA

But as mentioned by others, the factory pattern seems more adapted to your situation.

If you have to deal with a large amount of different cars that you want to read from files, you should use JSON or Java’s serializing system to read and write objects to files as described here :

Hello,
Hope the following information will help …

I’m using a factory pattern to create different polygon instances.
The polygons inherit an abstract class.

// Define this global variables
Class self;
 // if your sketch is called sample.pde, use sample as type for that
sample that;

// Add this to your sketch setup()
self = getClass();
that = this;

// The abstract class from which all polygons will inherit
abstract class Shape {
    float x = 0; float y = 0;
    Shape(String type, float _x, float _y) {
      this.x = _x;
      this.y = _y;
    }
}

// The classes for the different polygons
class ShapeA extends Shape {
  ShapeA(float x, float y) {
    super("ShapeA", x, y);
  }
}
class ShapeB extends Shape {
  ShapeB(float x, float y) {
    super("ShapeB", x, y);
  }
}
...
// Probably the most important. 
// Create instances based on the class name
class Factory {
  Shape newShape(String type, float x, float y) {
    Shape shape = null;
    try {
      Class<?> shapeClass = Class.forName(self.getName() + "$" + type);
      Constructor<?>[] constructors = shapeClass.getDeclaredConstructors();
      Constructor instance = constructors[0]; // use first constructor
      instance.setAccessible(true);
      shape = (Shape) instance.newInstance(that, x, y);  
    }
    catch (ClassNotFoundException e) {
      e.printStackTrace();
    } 
    catch (Exception e) {
      e.printStackTrace();
    }
}

// Create an instance using the class name
shape = factory.newShape("ShapeA", x, y);
2 Likes