Java类型转换,对象类型和重载问题

时间:2014-06-26 08:24:52

标签: java casting overloading

请看下面的Class,我需要检查变量中是否有有效值。如果变量中有适当的值而不是null,则一切正常。当它变为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(varInt,varLong,varString,varObject)实现checkAll

3 个答案:

答案 0 :(得分:5)

输出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)

因此,无论abxy引用的实际对象如何,您都可以在控制台上获得正确的输出各自的对象。


  

输出2:如何使用多个/动态参数checkAll(varInt,varLong,varString,varObject)实现checkAll

好吧,如果你要通过null,你真的不可能。 null在运行时为null,并且没有与之关联的任何类型信息。 JVM无法判断一个空是" String null"或者" Object null"。它只是null。因此,您无法真正实现null输入所需的多项检查 - null instanceof ______将始终返回false,因此您始终会以默认值结束情况下。

但是,如果传递实际对象,那么 方法应该正常工作。

答案 1 :(得分:1)

<强>问题:

    Integer a = null;
    Long b =  null;
    String x = null;
    Object y = null;

你不能在空值上使用instanceof,它希望对象被实例化,从而给你错误的结果。

<强>溶液

在检查实例之前先将对象即时化。

答案 2 :(得分:1)

这里的问题是,当您在循环中检查instanceof时,您正在检查nullnull不是任何事物的实例,而是缺少实例。

如果您希望实现这样的目标,那么您必须将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}
        );
    }
}