繁体   English   中英

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

[英]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)

因此,无论abxy引用的是哪个实际对象,您都将始终在控制台上为各个对象获得正确的输出。


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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM