Reputation: 43
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
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
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
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
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
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