Java 为什么NPE使用DatatypeConverter的静态方法?
我盯着这段短代码看得太久了,我一辈子都看不出它怎么会在第6行抛出Java 为什么NPE使用DatatypeConverter的静态方法?,java,string,nullpointerexception,base64,type-conversion,Java,String,Nullpointerexception,Base64,Type Conversion,我盯着这段短代码看得太久了,我一辈子都看不出它怎么会在第6行抛出NullPointerException。为什么是NPE class ConvertTest { public static void main(String[] args) throws Exception { byte[] b = "Ha".getBytes("UTF-8"); System.out.println("bytes: " + b.length); javax
NullPointerException
。为什么是NPE
class ConvertTest {
public static void main(String[] args) throws Exception {
byte[] b = "Ha".getBytes("UTF-8");
System.out.println("bytes: " + b.length);
javax.xml.bind.DatatypeConverter.printBase64Binary(b); // NPE!
}
}
输出
更新
虽然许多错误报告都指向1.7版本,但我惊讶地看到Eclipse被配置为使用1.6.0\u 32
&TextPad发现了1.6.0-b105
(甚至没有意识到安装了该版本!)
两个JRE都会因该NPE而失败
public static String printBase64Binary( byte[] val ) {
return theConverter.printBase64Binary( val );
}
JAXB提供程序需要在以下位置调用setDatatypeConverter api:
第一次封送或解封送操作之前的某个点(可能是
在调用JAXBContext.newInstance时)。这一步是必要的
配置用于执行打印和打印的转换器
解析功能
首先尝试设置转换器
/**
* This method is for JAXB provider use only.
* <p>
* JAXB Providers are required to call this method at some point before
* allowing any of the JAXB client marshal or unmarshal operations to
* occur. This is necessary to configure the datatype converter that
* should be used to perform the print and parse conversions.
*
* <p>
* Calling this api repeatedly will have no effect - the
* DatatypeConverterInterface instance passed into the first invocation is
* the one that will be used from then on.
*
* @param converter an instance of a class that implements the
* DatatypeConverterInterface class - this parameter must not be null.
* @throws IllegalArgumentException if the parameter is null
*/
public static void setDatatypeConverter( DatatypeConverterInterface converter ) {
if( converter == null ) {
throw new IllegalArgumentException(
Messages.format( Messages.CONVERTER_MUST_NOT_BE_NULL ) );
} else if( theConverter == null ) {
theConverter = converter;
}
}
/**
*此方法仅供JAXB提供程序使用。
*
*JAXB提供程序需要在之前的某个时间调用此方法
*允许执行任何JAXB客户端封送或解组操作
*发生。这是配置所需的数据类型转换器所必需的
*应用于执行打印和分析转换。
*
*
*重复调用此api将无效-
*传递到第一个调用的DatatypeConverterInterface实例为
*从那时起将使用的一个。
*
*@param converter实现
*DatatypeConverterInterface类-此参数不能为null。
*如果参数为null,则@引发IllegalArgumentException
*/
公共静态无效setDatatypeConverter(DatatypeConverterInterface converter){
if(converter==null){
抛出新的IllegalArgumentException(
Messages.format(Messages.CONVERTER_必须不为空);
}else if(converter==null){
转换器=转换器;
}
}
现在JDK7中的JAXB中似乎存在bug,驼峰上的这个问题就证明了这一点:
它最终链接到java.net上的JAXB项目中的这个问题
我不完全确定你是否遇到了同样的事情,但是,也许可以尝试将JDK6与最新的JAXB版本一起使用,看看是否会发生相同的NPE。如果没有环境的细节,我无法确定是否会发生这种情况,但如果您使用的是JAXB RI,则可能会遇到此JAXB错误所描述的问题: 虽然该bug没有专门解决您遇到的问题(它与
parseDate
方法有关),但根本原因可能是相同的。它是在JAXB的2.2.1版本中检测到的,但在2.1.x版本中可能已经存在,JAXB 2.1.1似乎是集成到1.6中的最新版本(集成在1.6u14中)
该问题表示,它是通过JAXB2.2.4解决的,JAXB2.2.4集成到1.7中
附加说明-当尝试使用1.6u31时,记录了一个有关
parseBoolean
的NPE的相关问题,这可能会引起兴趣(尽管帮助不大,但描述非常简短):。这表明这可能仍然是一个持续的问题,这取决于您是使用RI还是其他JAXB实现。Whoa!安德鲁·汤普森在问一个问题:我没有得到任何NPE。输出字节:2。在Netbeans中运行了完全相同的代码。@Eng.Fouad你不认为我建立了50K代表。你认为我是白费力气吗?我用它来奖励我的问题这可能与jdk源代码有关吗?在jdk源代码中,DatatypeConverter使用内部impl。impl为空是唯一可能导致NPE的因素。这似乎与@RoddyOfFrozenpeas的建议一致,即问题与混乱/冲突的jaxb库有关。您不应该自己打这个电话。jaxb提供程序应该这样做,但此时可能没有正确初始化/配置jaxb提供程序。
/**
* This method is for JAXB provider use only.
* <p>
* JAXB Providers are required to call this method at some point before
* allowing any of the JAXB client marshal or unmarshal operations to
* occur. This is necessary to configure the datatype converter that
* should be used to perform the print and parse conversions.
*
* <p>
* Calling this api repeatedly will have no effect - the
* DatatypeConverterInterface instance passed into the first invocation is
* the one that will be used from then on.
*
* @param converter an instance of a class that implements the
* DatatypeConverterInterface class - this parameter must not be null.
* @throws IllegalArgumentException if the parameter is null
*/
public static void setDatatypeConverter( DatatypeConverterInterface converter ) {
if( converter == null ) {
throw new IllegalArgumentException(
Messages.format( Messages.CONVERTER_MUST_NOT_BE_NULL ) );
} else if( theConverter == null ) {
theConverter = converter;
}
}