最近在写代码时由于对于Permitive类型和内置Wrapper类型使用不当,导致调试程序调试过程中出现了许多问题,在这里简单总结一下。
1.传参
Permitive作形参时,若函数调用时使用Wrapper类型作实参,需要保证实参被初始化不为null。
/**
* Created by chuang on 15-8-12.
*/
public class PermitiveWrapperTest {
public void testWrapperArg(Long param){
}
public void testPermitiveArg(long param){
}
public static void main(String[] argc){
PermitiveWrapperTest test = new PermitiveWrapperTest();
Long param = null;
try {
test.testWrapperArg(param);
}
catch (NullPointerException e){
System.out.println("testWrapperArg :");
e.printStackTrace();
}
try {
test.testPermitiveArg(param);
}
catch (NullPointerException e){
System.out.println("testPermitiveArg :");
e.printStackTrace();
}
}
}
上面这段代码的运行结果:
testPermitiveArg :
java.lang.NullPointerException
at com.xiaomi.browser.utils.PermitiveWrapperTest.main(PermitiveWrapperTest.java:29)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:134)
Process finished with exit code 0
可以看到,由于实参Long作为被初始化为null,导致调用函数形参为long型的函数时,出现空指针异常。
当把代码中的实参初始化改为
Long param = 1L;或者
long param = 1;
则程序运行正常,不会有任何异常抛出。
2.判等
代码如下:long eqTestPrimitive = 1;运行结果:
Long eqTestWrapper = new Long(1);
if(eqTestWrapper.equals(eqTestPrimitive)) {
System.out.println("equals primitive variable true");
}
if(eqTestWrapper.equals(1)) {
System.out.println("equals primitive constant true");
}
if(eqTestWrapper == eqTestPrimitive){
System.out.println(" == primitive variable true");
}
if(eqTestWrapper == 1){
System.out.println(" == primitive const true");
}
testPrimitiveArg :我们看到只有第二个判断语句没有返回true,即
equals primitive variable true
== primitive variable true
== primitive const true
if(eqTestWrapper.equals(1)) { System.out.println("equals primitive constant true"); }
为什么呢,我们看一下Long.equals的源码:
/**首先明确一点,Long.equals是为两个Long型对象判等使用的,其内部还是用==判断两个对象内部所存储的值是否相等。
* Compares this object to the specified object. The result is
* <code>true</code> if and only if the argument is not
* <code>null</code> and is a <code>Long</code> object that
* contains the same <code>long</code> value as this object.
*
* @param obj the object to compare with.
* @return <code>true</code> if the objects are the same;
* <code>false</code> otherwise.
*/
public boolean equals(Object obj) {
if (obj instanceof Long) {
return value == ((Long)obj).longValue();
}
return false;
}
返回我们最初遇到的问题,很容易就发现,之所以
eqTestWrapper.equals(1)
返回false是因为,我们传递给equals函数的参数被作为Integer类型解析了,由此在equals函数内不第一个if类型判断时就返回false了。将参数改为1L就返回true了,因为Java会内部装箱,将参数升级为Long型。
Java中类似的问题还有好多,如Map的Key值问题,还是在实际代码中总结吧,这里不多说。