【问题标题】:Java Type Cast, Object Type and overloading IssueJava 类型转换、对象类型和重载问题
【发布时间】:2014-06-26 08:24:51
【问题描述】:

请看下面的类,我需要检查变量中是否有有效值。如果变量中有适当的值而不是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

【问题讨论】:

  • 我认为你应该提出一个通用的空指针错误,比如“该字段不能为空”,如果有任何数据,那么验证具体格式(在这种情况下你不需要甚至需要的实例)。这也将避免粘合代码(如果 xxx!=null 则复制并粘贴)。让我知道这是否符合您的需求。

标签: java casting overloading


【解决方案1】:

输出 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 checkAll(varInt, varLong, varString, varObject)

好吧,如果你要通过null,你真的不能。 null 在运行时是 null,并且没有任何与之关联的类型信息。 JVM 无法判断一个 null 是“String null”还是“Object null”。只是null。所以你不能真正实现对null输入的多重检查——null instanceof ______总是会返回false,所以你总是会得到你的默认情况。

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

【讨论】:

  • @NetSurgeon 谢谢!有趣的事实:如果将任何empty(_) 替换为empty(null),则会出现编译器错误,因为编译器无法确定要绑定的方法。不过,无法想象这会很有帮助。
  • 哦,是的,如果 null 直接传递给它一个编译器错误。很好,谢谢。
【解决方案2】:

问题:

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

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

解决方案:

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

【讨论】:

  • 正确,这是我从上面的经验中了解到的。但是如果您看到第三个输出,则重载函数正在识别这些空变量的类型。我需要知道他们是怎么做到的?
  • 那不是我(-ve)
  • @NetSurgeon 嗯,因为您在检查之前打印了它。
【解决方案3】:

这里的问题是,当您在循环中检查 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}
        );
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-10-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多