我试图实现一些使用泛型的示例类,但我注意到我的代码中有一部分突出显示以下警告:
信息: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
。但是,编译器会检测到此错误,并正确引发错误,因为BtoAConverter
和getConverter
无法通过Converter<?, ?>
方法生成。匹配它们的唯一可能的返回类型是AtoBConverter
,但是我认为这不适用于您的情况。
但是,有一个简单的解决方法-您可以在工厂类中引入两个单独的方法,分别产生BtoAConverter
和SomethingA
:
public class ConverterFactory {
public static AtoBConverter getAToBConverter() {
return new AtoBConverter();
}
public static BtoAConverter getBToAConverter() {
return new BtoAConverter();
}
}
然后,我相信
SomethingB
和Something#convertTo()
不应将自己转换为其他内容-这应该是转换器所做的,这就是为什么我发现SomethingAbstract
方法是多余的(以及类的原因) )。最后,您将可以执行以下操作:
SomethingA a = new SomethingA();
AtoBConverter converter = ConverterFactory.getAToBConverter();
SomethingB b = converter.convert(a);