我试图实现一些使用泛型的示例类,但我注意到我的代码中有一部分突出显示以下警告:


  信息:java:SomethingAbstract.java使用未经检查或不安全的方法
  操作。


这是在这段代码converter.convert(this)上发生的。

我怀疑问题实际上出在我的ConverterFactory.getConverter(...)的返回类型上。我试图更改它返回Converter,然后我得到


  错误:(6,20)java:不兼容的类型:org.test.AtoBConverter无法
  转换为org.test.Converter


我尝试查看AtoBConverter或BtoAConverter来了解如何更改它们,但无法弄清楚。

我应该添加/更改什么才能使警告消失?

这是我的示例类:

public interface Something {
    <R extends Something> R convertTo(Class<R> to);
}

public class SomethingAbstract implements Something {
    @Override
    public <R extends Something> R convertTo(Class<R> to) {
        Converter converter = ConverterFactory.getConverter(this.getClass(), to);
        return to.cast(converter.convert(this)); // <<< warning on this line
    }
}

public class SomethingA  extends SomethingAbstract {}

public class SomethingB extends SomethingAbstract {}


然后使用Something类型进行某些工作的类:

// Convert T to R
public interface Converter<T extends Something, R extends Something> {
    R convert(T toConvert);
}

public class AtoBConverter implements Converter<SomethingA, SomethingB> {
    @Override
    public SomethingB convert(SomethingA toConvert) {
        SomethingB somethingB = new SomethingB();
        // Do some stuff to convert
        return somethingB;
    }
}

public class BtoAConverter implements Converter<SomethingB, SomethingA> {
    @Override
    public SomethingA convert(SomethingB toConvert) {
        SomethingA somethingA = new SomethingA();
        // Do some stuff to convert
        return somethingA;
    }
}


以及用于获得正确转换器的工厂:

public class ConverterFactory {
        public static <T extends Something, R extends Something> Converter getConverter(Class<T> from, Class<R> to) {
            if (from.equals(SomethingA.class) && to.equals(SomethingB.class)) {
                return new AtoBConverter();
            } else if (from.equals(SomethingB.class) && to.equals(SomethingA.class)) {
                return new BtoAConverter();
            }
            throw new UnsupportedOperationException("No converter found to convert from " + from + " to" + to);
        }
    }


最后,它应按以下方式使用:

SomethingA a = new SomethingA();
SomethingB b = a.convertTo(SomethingB.class);

最佳答案

您的Converter接口是通用的,因此ConverterFactory#getConverter()的返回类型也应该是通用的。

但是,真正的问题还有另一个:


AtoBConverter extends Converter<SomethingA, SomethingB>
BtoAConverter extends Converter<SomethingB, SomethingA>


即使这两种类型都扩展了Converter,它们在运行时也不扩展同一超类,因为(例如)AtoBConverter将公开带有签名SomethingA convert(SomethingB toConvert)的方法,而另一个将公开具有签名SomethingB convert(SomethingA toConvert)的方法。签名AtoBConverter。但是,编译器会检测到此错误,并正确引发错误,因为BtoAConvertergetConverter无法通过Converter<?, ?>方法生成。匹配它们的唯一可能的返回类型是AtoBConverter,但是我认为这不适用于您的情况。

但是,有一个简单的解决方法-您可以在工厂类中引入两个单独的方法,分别产生BtoAConverterSomethingA

public class ConverterFactory {

    public static AtoBConverter getAToBConverter() {
        return new AtoBConverter();
    }

    public static BtoAConverter getBToAConverter() {
        return new BtoAConverter();
    }

}


然后,我相信SomethingBSomething#convertTo()不应将自己转换为其他内容-这应该是转换器所做的,这就是为什么我发现SomethingAbstract方法是多余的(以及类的原因) )。

最后,您将可以执行以下操作:

SomethingA a = new SomethingA();
AtoBConverter converter = ConverterFactory.getAToBConverter();
SomethingB b = converter.convert(a);

08-05 01:01