有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java引用对象通过其实现的通用接口

我有一个转换器接口,看起来像这样:

public interface MyTypeConverter<T>
{
  public MyObject toMyObject(T obj);
  public T fromMyObject(MyObject mo);
}

我还有一个接口的实现:

public class ABCTypeConverter implements MyTypeConverter<ABCObject>
{
  public MyObject toMyObject(ABCObject obj)
  {
    ...do conversion...
  }
  public ABCObject fromMyObject(MyObject mo)
  {
    ...do conversion...
  }
}

以及一个工厂,用于评估对象类型,并返回适当的转换器实现:

public class MyTypeConverterFactory
{
  public static MyTypeConverter<?> create(Object source)
  {
    if ( source instanceof ABCObject )
      return new ABCTypeConverter();
    ...and so on...
  }
}

现在我遇到的问题是使用接口引用工厂返回的转换器实例:

MyTypeConverter<?> converter = MyTypeConverterFactory.create(someObject);
MyObject mo = converter.toMyObject(someObject);

最后一行给出了以下编译时错误:

The method toMyObject(capture#3-of ?) in the type MyTypeConverter<capture#3-of ?> 
  is not applicable for the arguments (ABCObject)

那么,如何以通用方式引用转换器呢

编辑

我的问题的核心是:如何在不首先转换到底层具体类型的情况下对接口引用调用方法?如果我不能,那么创建一个通用接口的意义是什么呢?即,我如何做到这一点(无论我如何获得参考):

MyTypeConverter<?> converter = MyTypeConverterFactory.create(someObject);
MyObject mo = converter.toMyObject(someObject);

不先将“转换器”浇筑到其底层混凝土类型


共 (2) 个答案

  1. # 1 楼答案

    您也可以尝试使用多态性,而不是将其设置为泛型

    只需从工厂的create()方法返回接口引用,而不是实际的对象引用。在运行时,实际对象根据重写的方法逻辑决定应该调用什么方法


    在下面的示例代码中,我创建了一个接口MyTypeConverterObject,该接口由属于MyTypeConverter接口的所有类实现

    现在只需从工厂的create()方法返回MyTypeConverterObject

    示例代码:

    interface MyTypeConverterObject {}
    
    class ABCObject implements MyTypeConverterObject {}
    class XYZObject implements MyTypeConverterObject {}
    
    class MyObject {}
    
    interface MyTypeConverter {
        public MyObject toMyObject(MyTypeConverterObject obj);
        public MyTypeConverterObject fromMyObject(MyObject mo);
    }
    
    class ABCTypeConverter implements MyTypeConverter {
        public MyObject toMyObject(MyTypeConverterObject obj) {
            return new MyObject();
        }
        public MyTypeConverterObject fromMyObject(MyObject mo) {
            return new ABCObject();
        }
    }
    
    class MyTypeConverterFactory {
        public static MyTypeConverter create(Object source) {
            if (source instanceof ABCObject) {
                return new ABCTypeConverter();
            }
            return ...;
        }
    }
    

    工厂方法应返回相同类型的产品,即实现相同接口的产品

    例如:汽车制造厂可以退回不同类型的汽车,但不能生产自行车

    enter image description here

    enter image description here

    如果您需要退回不同类型的产品,请使用抽象工厂

    enter image description here

  2. # 2 楼答案

    这是FactoryMethod模式的完全反模式方法:

    if ( source instanceof ABCObject )
      return new ABCTypeConverter();
    ...and so on...
    

    不要这样做,它将永远无法扩展,也永远无法维护

    问题是:

    TypeConverter<ABCObject> tc = new TypeConverter<ABCObject>();
    

    这就是每一个实现类似这样东西的sane框架的工作原理

    例如:

    com.google.common.base.Converter

    看看Jackson是如何为JSON序列化程序/反序列化程序实现的

    Guava有一种方法可以获取类型T的实例

    Class<T> klass = (Class<T>) new TypeToken<T>(getClass()) {}.getRawType();
    

    然后你可以做klass.newInstance();但这是哈奇做得很好