施工期间未知通用的安全方法返回类型

时间:2014-08-20 16:35:15

标签: java generics methods

我有一个课程如下

public class GenericObjectBuilder {

    private Class<?> classType;

    public GenericObjectBuilder(Class<?> classType) {
       this.classType = classType;
    }
}

我希望能够向此类添加一个方法(例如getObject),该方法将返回类型为“?”的对象,以便构造函数确定此方法的返回类型。例如

GenericObjectBuilder gc1 = new GenericObjectBuilder(String.class);
String value = gc1.getObject();

GenericObjectBuilder gc2 = new GenericObjectBuilder(Integer.class);
Integer value = gc2.getObject();

在这种情况下,我无法使用正确的泛型。例如我不能做

GenericObjectBuilder<String> gc1 = new GenericObjectBuilder<>();
String value = gc1.getValue();

这是否可以使用构造函数参数?

1 个答案:

答案 0 :(得分:1)

如果没有Generics,我不确定你能达到目标。

根据您与第三方图书馆的联系程度,您可以尝试围绕它进行设计。

  • 传入包装器对象。

    如果您可以控制构造函数和GenericObjectBuilder的实现,则可以传入包装器对象。

    GenericObjectResult<String> result = new GenericObjectResult<>(String.class);
    GenericObjectBuilder builder = new GenericObjectBuilder(result);
    builder.build();
    String object = result.getObject();
    

    这很难看,但也许会让你前进。

  • 只有getObject方法通用。

    您应该可以进行以下实施。

    GenericObjectBuilder builder = new GenericObjectBuilder();
    String value = builder.getObject(String.class)
    

    最后一个实现更清晰,但您仍然需要为getObject方法使用泛型。但是,这个类本身并不是通用的。也许这对第三方库来说没问题。

  • 制作包装器构建器

    最后一种方法在GenericObjectBuilder

    之上创建了一个包装器构建器
    GenericObjectBuilder builder = new GenericObjectBuilder(String.class); // We don't actually care what the constructor is
    GenericObjectBuilderWrapper wrapper = new GenericObjectBuilderWrapper(builder, String.class); // You could try and get the class from the `builder` if it has the proper API
    String value = wrapper.getObject();
    

    包装器在内部会做什么,就会出现这种情况。

    class GenericObjectBuilderWrapper<T> {
        private Class<T> clazz;
        private GenericObjectBuilder delegate;
    
        public GenericObjectBuilderWrapper(GenericObjectBuilder delegate, Class<T> clazz) {
            this.clazz = clazz;
            this.delegate = delegate;
        }
    
        public <T> getObject() {
            final Object value = delegate.getObject();
            return clazz.cast(value);
        }
    
    }  
    

如果你真的不能在项目的任何地方使用任何类型的泛型,因为你使用的是旧版本的Java,那么你将不得不依赖于显式的转换。

String value = (String)builder.getObject();