【问题标题】:Create instances of dynamically given classes in Java在 Java 中创建动态给定类的实例
【发布时间】:2017-08-20 21:09:09
【问题描述】:

我需要一个函数来在 java 中创建动态给定类的实例。

我找到了很多示例,但在所有示例中,要实例化的类在运行时之前就知道了。

有用户定义的类:

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

我需要的是

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;

}

我将如何使用

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

希望有人帮忙。

这是我在 Stackoverflow 上的第一个问题,如有不便,敬请原谅。

优酷

【问题讨论】:

标签: java class dynamic instance


【解决方案1】:

假设提供给MyFunction 的类有一个默认构造函数,一个简单的实现将是

  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;
  }

上面的方法可以这样调用

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

为了提高透明度,方法内抛出的异常可以用另一种方式处理(例如,添加到方法签名中)。

【讨论】:

  • 我认为在MyFunction 方法中简单地捕获异常并返回一个空的List 是很危险的;相反,我要么抛出异常,要么返回null
  • 虽然基本上是正确的,但我想知道你为什么要打扰 if (item != null) { 块,而只是在 try-catch 块中添加项目
  • 两个 cmets 都是有效的,但答案只是显示了一些示例代码。根据我那里的cmets,可能会有变化。谢谢。 :-)
  • 我想我们只是想呈现“完美”的答案:P
【解决方案2】:

这应该可行。

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);
    }
}

【讨论】:

  • 好的,朝着正确的方向前进,但它不会编译
  • 我修复了占位符类型,不错!
【解决方案3】:

在 Java 8 中,您可以使用 method referencelambda expression 以便在不使用反射的情况下动态创建类实例。

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

你可以这样称呼它:

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

如果您不熟悉流,命令式等效项是:

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;
}

【讨论】:

  • 这太棒了。但是我使用了另一种解决方案,我会尽快将我的代码更新为这个示例。谢谢...
【解决方案4】:

你可以使用反射来做到这一点 您传递的每个类都必须有一个默认的无参数构造函数。 对于这个特定的应用程序,您可能需要所有 3 个类来共享一个接口,以便您可以正确地发回一个列表

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;
}

当您将列表分配给列表变量时,您必须对其进行强制转换。

如:

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

【讨论】:

    【解决方案5】:

    您可以使用这样的模式策略:

    ///接口 打包策略;

    公共接口 IStrategy { public void appliquerStrategy();

    }

    打包 tpdesignpattern2.strategy;

    公共类 StrategyImpl1 实现 IStrategy{

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

    }

    打包 tpdesignpattern2.strategy;

    公共类 StrategyImpl2 实现 IStrategy{

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

    }

    /////// 上下文类 包 tpdesignpattern2.strategy;

    公共类上下文{ /*** * 注入 de l'interface */

    private IStrategy iStrategy = new StrategyImpl1() ;
    
    /**
     * @param iStrategy
     */
    
    public void setiStrategy(IStrategy iStrategy) {
        this.iStrategy = iStrategy;
    }
    
    public void appliquerStrategy() {
        iStrategy.appliquerStrategy();
    
    }
    

    }

    ///应用 包 tpdesignpattern2.strategy;

    导入 java.util.Scanner;

    导入策略.IStrategy;

    公共类应用程序{

    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();
                    };                  
            }
    }
    

    }

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-12-17
      • 2020-05-11
      • 1970-01-01
      • 1970-01-01
      • 2020-06-22
      • 1970-01-01
      相关资源
      最近更新 更多