[英]Java Type Cast, Object Type and overloading Issue
请看下面的类,我需要检查变量中是否有有效值。 如果变量中有一个适当的值而不是null
,那么一切都可以正常工作,当它为null
,行为不是我期望的(尽管Integer a = null;
可能是有意义的Integer a = null;
当作为a instanceof Integer
进行检查时,
有人可以指导我如何从上课后获得正确的结果吗?
package com.mazhar.hassan;
public class ValueChecker {
public static boolean empty(Integer value) {
System.out.println("Integer");
return (value != null && value.intValue() > 0);
}
public static boolean empty(Long value) {
System.out.println("Long");
return (value != null && value.longValue() > 0);
}
public static boolean empty(String value) {
System.out.println("String");
return (value != null && value.length() > 0);
}
public static boolean empty(Object value) {
System.out.println("Object");
return (value != null);
}
public static void checkAll(Object... args) {
for(Object o: args) {
if (o instanceof Integer) {
empty((Integer)o);
}
else if (o instanceof Long) {
empty((Long)o);
}
else if (o instanceof String) {
empty((String)o);
}
else {
empty(o);
}
}
}
public static void main (String[] args) {
Integer a = null;
Long b = null;
String x = null;
Object y = null;
if (a instanceof Integer) {
System.out.println("a is Integer");
} else {
System.out.println("a is not Integer");
}
System.out.println("/---------------------------------------------------/");
checkAll(a,b,x,y);
System.out.println("/---------------------------------------------------/");
empty(a);
empty(b);
empty(x);
empty(y);
}
}
为什么需要精确的类型检查,我必须抛出诸如“无效的整数”,“无效的长整数”等错误信息。
上一类的输出如下。
/-----------------------(Output 1)----------------------------/
a is not Integer
/-----------------------(Output 2)----------------------------/
Object
Object
Object
Object
/------------------------(Output 3)---------------------------/
Integer
Long
String
Object
输出1:a不是整数(由instanceof检查)不能识别它,但是当传递给重载函数时转到正确的函数(输出3)
输出2:如何实现checkAll
具有多个/动态PARAM checkAll(varInt,varLong,varString,varObject)
输出1的行为是由于在编译时绑定了方法重载这一事实引起的。 因此,要选择的特定重载在程序甚至运行之前就已绑定。 另一方面, instanceof
是运行时检查。
因此,在运行时, a instanceof Integer
实际上是null instanceof Integer
,这显然是false
。
但是对于每个单独的方法调用,都将调用适当的方法,因为编译器根据变量的引用类型在编译时绑定了方法的特定重载。 从而:
empty(a); // Compiled to a call to empty(Integer value)
empty(b); // Compiled to a call to empty(Long value)
empty(x); // Compiled to a call to empty(String value)
empty(y); // Compiled to a call to empty(Object value)
因此,无论a
, b
, x
和y
引用的是哪个实际对象,您都将始终在控制台上为各个对象获得正确的输出。
输出2:如何使用多个/动态参数checkAll(varInt,varLong,varString,varObject)实现checkAll
好吧,如果您要传递null
,那么您就不能做到。 null
在运行时为null
,并且没有任何与之关联的类型信息。 JVM不能说一个null是“ String null
”或“ Object null
”。 它只是null
。 因此,您不能真正实现对null
输入想要的多重检查null instanceof ______
总是返回false
,因此您总是会遇到默认情况。
但是,如果传递实际对象,则该方法应该可以正常工作。
问题:
Integer a = null;
Long b = null;
String x = null;
Object y = null;
您不能对空值使用instanceof
,它期望对象被实例化,从而给您错误的结果。
解:
在检查实例之前,先实例化对象。
这里的问题是,当您在循环中检查instanceof时,您正在检查null
。 null
不是任何实例,它是没有实例。
如果要实现这样的目标,则必须将checkAll(Object ...)
API更改为告诉函数期望的类型的东西:
public class ValueChecker {
public static boolean checkAll(Object[] args, Class<?>[] types) {
if (args == null || types == null || args.length != types.length)
throw new RuntimeException("programming error");
for (int i = 0; i < args.length; i++) {
if (types[i] == null)
throw new RuntimeException("programming error");
if (args[i] == null || !types[i].isAssignableFrom(args[i].getClass())) {
System.out.println("arg " + (i +1) + " is not " + types[i].getSimpleName());
return false;
}
}
return true;
}
public static void main(String[] args) {
Integer a = null;
Long b = null;
String x = null;
Object y = null;
checkAll(
new Object[] {a, b, x, y},
new Class<?>[] {Integer.class, Long.class, String.class, Object.class}
);
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.