【问题标题】:How to build a generic Factory [duplicate]如何建立一个通用工厂[重复]
【发布时间】:2018-09-13 22:38:54
【问题描述】:

目前我正在尝试构建一个能够创建随机对象的 Java 类。 我用工厂模式尝试过,抽象的产品接口就像:

public interface ObjectFactory<T>
{
    T createObject();
}

但是当我尝试实现一个具体的通用产品时它不起作用。 这是我的具体产品的代码:

public class GenericFactory implements ObjectFactory<T> {

    @Override
    public T createObject()
    {
        return new T();
    } 
}

IntelliJ 说:“无法解析符号 T”

【问题讨论】:

  • 它应该如何知道要创建哪个“随机对象”?
  • 使用GenericFactory&lt;T&gt;public &lt;T&gt; T
  • 为什么需要这个,而不是使用标准的Supplier&lt;T&gt; class
  • "IntelliJ 说:"无法解析符号 T"" 因为 T 需要是您导入的类名(或在同一个包中),或者是您指定的类型变量在GenericFactory 上声明。

标签: java generics factory


【解决方案1】:

Java 将type erasure 用于泛型。因此JVM在运行时无法知道T实际上是哪个类型。

您可以使用反射创建一个通用工厂,但这真的很难看。如果您想在生产中使用通用工厂,请选择 Spring 或类似的东西。

public interface ObjectFactory<T> {

    T createObject(Class<? extends T> type);

}

public class GenericFactory<T> implements ObjectFactory<T> {

    public T createObject(Class<? extends T> type) {
        try {
            Constructor<? extends T> constructor = type.getDeclaredConstructor();

            constructor.setAccessible(true);

            return constructor.newInstance();
        } catch (Throwable e) {
            throw new InstantiationError("Can not create an object of class " + type.getName());
        }
    }

}

public class Main {

    public static void main(String[] args) {
        GenericFactory<Car> carFactory = new GenericFactory<>();
        Car car = carFactory.createObject(Car.class); // works

        GenericFactory<Car> bikeFactory = new GenericFactory<>();
        Bike bike = bikeFactory.createObject(Bike.class); // throws exception
    }

    private static class Car {}

    private static class Bike {

        private String color;

        Bike(String color) {
            this.color = color;
        }

    }

}

【讨论】:

    【解决方案2】:

    这不是泛型类的有效实现。

    具体类需要指定类型变量T是哪个对象。

    代码应该看起来更像这样:

    public class GenericFactory implements ObjectFactory<MyClass> {
    
        @Override
        public MyClass createObject() {
            return new MyClass();
        }
    
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-01-27
      • 1970-01-01
      • 2010-12-17
      • 2020-03-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多