Utku
Utku

Reputation: 43

Create instances of dynamically given classes in Java

I need a function to create instances of a dynamically given class in java.

I had found many samples but in all of them, the class to be instantiated was known before runtime.

There are user defined classes:

class Student { //some code }
class Teacher { //some code }
class Course { //some code }

What I need is

List<class> MyFunction(<class>) {

  List<class> items = new ArrayList<class>();

  for(int i = 0; i < 5; i++) {

    create_a_new_class_instance;

    items.add(new_created_instance);
  }

  return items;

}

How will I use

List<Student> students = MyFunction(Student);
List<Teacher> teachers = MyFunction(Teacher);
List<Course> courses = MyFunction(Course);

Hope someone helps.

This is my first question in Stackoverflow, sorry for any inconvenience.

Utku

Upvotes: 4

Views: 5111

Answers (5)

Apolinaire Nguemo
Apolinaire Nguemo

Reputation: 67

you can use a pattern stategy like this :

///interface package strategy;

public interface IStrategy { public void appliquerStrategy();

}

package tpdesignpattern2.strategy;

public class StrategyImpl1 implements IStrategy{

@Override
public void appliquerStrategy() {
    System.out.println("Appliquer la strategy 1");
    
}

}

package tpdesignpattern2.strategy;

public class StrategyImpl2 implements IStrategy{

@Override
public void appliquerStrategy() {
    System.out.println("Appliquer la strategy 2");
    
}

}

/////// Context class package tpdesignpattern2.strategy;

public class Context { /*** * injection de l'interface */

private IStrategy iStrategy = new StrategyImpl1() ;

/**
 * @param iStrategy
 */

public void setiStrategy(IStrategy iStrategy) {
    this.iStrategy = iStrategy;
}

public void appliquerStrategy() {
    iStrategy.appliquerStrategy();

}

}

///Application package tpdesignpattern2.strategy;

import java.util.Scanner;

import strategy.IStrategy;

public class App {

public static void main(String[] args)   {
    Context context = new Context();
    
    Scanner scanner = new Scanner(System.in);
    
    while(true) {
        System.out.print("Entrer le nom de la calss : ");
        String nom = "tpdesignpattern2.strategy."+scanner.nextLine();

                tpdesignpattern2.strategy.IStrategy strategy;
                try {
                    strategy = (tpdesignpattern2.strategy.IStrategy) Class.forName(nom).newInstance();
                    context.setiStrategy(strategy);
                    context.appliquerStrategy();
                } catch (Exception e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                };                  
        }
}

}

Upvotes: 0

castletheperson
castletheperson

Reputation: 33476

In Java 8, you can use a method reference or lambda expression in order to create instances of classes dynamically without using reflection.

public static <T> List<T> myFunction(Supplier<T> supplier) {
    return Stream.generate(supplier)
                 .limit(5)
                 .collect(Collectors.toList());
}

You would call it like:

List<Student> students = myFunction(Student::new);

If you're not familiar with streams, the imperative equivalent is:

public static <T> List<T> myFunction(Supplier<T> supplier) {
    int size = 5;
    List<T> list = new ArrayList<>(size);
    for (int i = 0; i < size; i++) {
        list.add(supplier.get());
    }
    return list;
}

Upvotes: 7

MichaelBadgett
MichaelBadgett

Reputation: 51

You could use reflection to do this each class you pass must have a default no-argument constructor. for this specific application you will likely need all 3 classes to share an interface so that you can properly send a list back

public interface Unit {
    //Put any common functionality method stubs here
}

public class Teacher implements Unit {
}
//....etc for the other classes
List<Unit> MyFunction(Class<Unit> clazz) {
    List<Unit> items = new ArrayList<Unit>();

    for(int i = 0; i < 5; i++) {
        items.add(clazz.newInstance());
    }

    return items;
}

when you assign your list to a list variable you will have to cast it.

such as:

List<Student> students = (List<Student>) MyFunction(Student.class);

Upvotes: 1

Paul Back
Paul Back

Reputation: 1319

This should work.

import java.util.ArrayList;
import java.util.List;

public class DynamicClassList {

    public <T> List<T> myFunction(Class<T> inputClass) {

        List<T> items = new ArrayList<T>();

        for(int i = 0; i < 5; i++) {

            try {
                T myT = inputClass.getConstructor().newInstance();
                items.add(myT);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        return items;

    }

    public static void main(String[] args) {
        DynamicClassList dynamicClassList = new DynamicClassList();
        List<Student> s = dynamicClassList.myFunction(Student.class);
        List<Teacher> t = dynamicClassList.myFunction(Teacher.class);
        List<Course> c = dynamicClassList.myFunction(Course.class);
    }
}

Upvotes: 4

PNS
PNS

Reputation: 19905

Assuming that the classes supplied to MyFunction have a default constructor, a simple implementation would be

  public static <T> List<T> MyFunction(Class<T> clazz) {
    if (clazz == null) {
      return null;
    }
    T item;
    List<T> items = new ArrayList<T>();
    for (int i = 0; i < 5; i++) {
      try {
        item = clazz.newInstance();
      } catch (Exception e) {
        item = null;
      }
      if (item != null) {
        items.add(item);
      }
    }
    return items;
  }

and the above method could be called like

List<Student> student = MyFunction(Student.class);

For increased transparency, the exception thrown inside the method could be handled in another way (e.g., added to the method signature).

Upvotes: 3

Related Questions