【发布时间】:2018-03-23 14:27:47
【问题描述】:
我正在做一些元编程,我正在解析 JAXB bean,特别是 XmlAdapter 注释。我遇到了这样一种情况,即 Eclipse Oxygen (4.7.2) 的编译器完全满足于使用类型推断的一些方法,但 OpenJDK 编译器 (javac 1.8.0_131) 对它们感到窒息。
我已将主要结构提取到此 MWE 中:
import java.time.LocalDate;
import javax.xml.bind.annotation.adapters.XmlAdapter;
public class Main<BoundType>
{
public void parse( Class<? extends XmlAdapter<?, BoundType>> adapterClass ) throws Exception
{
process( adapterClass );
}
private <ValueType> void process( Class<? extends XmlAdapter<ValueType, BoundType>> adapterClass ) throws Exception
{
// Do something with adapterClass ...
}
private static final class SomeAdapter extends XmlAdapter<String, LocalDate>
{
@Override
public LocalDate unmarshal( String v ) throws Exception
{
return v == null ? null : LocalDate.parse( v );
}
@Override
public String marshal( LocalDate v ) throws Exception
{
return v == null ? null : v.toString();
}
}
public static void main( String[] args ) throws Exception
{
Main<LocalDate> main = new Main<>();
main.parse( SomeAdapter.class );
}
}
OpenJDK 编译器产生此错误:
/[...]/WildcardProblem/src/Main.java:21: error: method process in class Main<BoundType> cannot be applied to given types;
process( adapterClass );
^
required: Class<? extends XmlAdapter<ValueType,BoundType>>
found: Class<CAP#1>
reason: cannot infer type-variable(s) ValueType
(argument mismatch; Class<CAP#1> cannot be converted to Class<? extends XmlAdapter<ValueType,BoundType>>)
where ValueType,BoundType are type-variables:
ValueType extends Object declared in method <ValueType>process(Class<? extends XmlAdapter<ValueType,BoundType>>)
BoundType extends Object declared in class Main
where CAP#1 is a fresh type-variable:
CAP#1 extends XmlAdapter<?,BoundType> from capture of ? extends XmlAdapter<?,BoundType>
我可以通过修改方法process 来解决编译器错误,如下所示:
private <ValueType> void process( Class<? extends XmlAdapter<?, BoundType>> adapterClass ) throws Exception
{
@SuppressWarnings( "unchecked" )
Class<? extends XmlAdapter<ValueType, BoundType>> capturedAdapterClass = (Class<? extends XmlAdapter<ValueType, BoundType>>) adapterClass;
// Do something with adapterClass ...
}
当然,未经检查的演员阵容是丑陋的。我相信它应该是安全的,因为这里任意引入类型参数ValueType 只是为了捕获通配符。我只需要在我的处理过程中更进一步地实例化XmlAdapter 并在其上调用unmarshal。在运行时,不会发生异常。
所以我的问题是,首先,应该编译原始代码,其次,这是 Eclipse 编译器还是 OpenJDK 编译器错误?
【问题讨论】:
标签: java eclipse type-inference