【问题标题】:Quickly Create A Java Class Object快速创建 Java 类对象
【发布时间】:2020-08-20 14:37:57
【问题描述】:

所以,我正在处理少量(但仍然很乏味)的课程,确切地说是 20 个课程,但这没关系。

我的程序要做的一件事是读取 2 个参数的输入,(String className, String name),并添加一个类名为 className 的新对象,并为其构造函数添加一个 name 参数。

所以,想象一下狗、猫、猪、飞蛾、老鼠、... 它们每个都采用相同的构造函数,只是不同的类。 而不是做

if (className.equalsIgnoreCase("Dog")){
     myArrayList.add(new Dog(name));
} else if (className.equalsIgnoreCase("Cat")){
     myArrayList.add(new Cat(name));
} else if (...)

有没有办法让我可以简单地做到这一点

myArrayList.add(new X(name));

还是熟悉的东西?

【问题讨论】:

    标签: java class object runtime


    【解决方案1】:

    你也可以这样做。这个例子没有使用 Spring Framework,但是使用 Spring Framework 可以简单一些。

    1. 为工厂定义接口
        public interface AnimalFactory<T extends Animal> {
            boolean isFactoryForType(String type);
            Animal createWithName(String name);
        }
    
    1. 实施工厂
        public class DogFactory implements AnimalFactory<Dog> {
    
            @Override
            public boolean isFactoryForType(String type) {
                return "dog".equalsIgnoreCase(type);
            }
    
            @Override
            public Dog createWithName(String name) {
                return new Dog(name);
            }
        }
    
        public class CatFactory implements AnimalFactory<Cat> {
    
            @Override
            public boolean isFactoryForType(String type) {
                return "cat".equalsIgnoreCase(type);
            }
    
            @Override
            public Cat createWithName(String name) {
                return new Cat(name);
            }
    
        }
    
    1. 狗的例子
        public class Dog extends Animal {
            public Dog(String name) {
                super(name);
            }
    
            @Override
            public String toString() {
                return "This is a Dog with name: " + getName();
            }
        }
    
    1. 使用示例
        public static void main(String[] args) {
            if (args.length != 2) {
                System.err.println("Expect type AND name as input arguments");
                System.exit(1);
            }
    
            String type = args[0];
            String name = args[1];
    
            List<AnimalFactory<? extends Animal>> animalFactories = new ArrayList<>();
            animalFactories.add(new DogFactory());
            animalFactories.add(new CatFactory());
    
            AnimalFactory<?> animalFactory = animalFactories.stream()
                    .filter(factory -> factory.isFactoryForType(type))
                    .findFirst()
                    .orElseThrow(() -> new IllegalArgumentException("Type " + type + " not supported"));
    
            Animal animal = animalFactory.createWithName(name);
    
            System.out.println("Created animal: " + animal);
        }
    
    1. 带参数的输出:dog Boris

    Created animal: This is a Dog with name: Boris

    1. 带参数的输出:car Bill

    Created animal: This is a Cat with name: Bill

    【讨论】:

      【解决方案2】:

      如果所有类都在同一个包中,则可以使用反射:

      Class<?> clazz = Class.forName("your.package." + className);
      Constructor<?> constructor = clazz.getConstructor(String.class);
      myArrayList.add((CommonParent) constructor.newInstance(name));
      

      【讨论】:

        猜你喜欢
        • 2016-02-23
        • 2015-09-11
        • 2016-05-20
        • 2018-03-06
        • 2011-09-28
        • 2021-05-19
        • 1970-01-01
        • 1970-01-01
        • 2016-12-01
        相关资源
        最近更新 更多