Java多态和向下转换

问题描述

| 我正在使用Java的反射API,并且正在编写检查给定对象并描述其字段,方法等的方法。 我正在使用
getFields()
方法来迭代不同的属性显示对象内容
public static void display(Integer i)
{
    System.out.println(\"An integer: \" + i);
}

// Basically a method for each primitive type wrapper

public static void display(Object o)
{
    for (Field f : c.getFields())
    {
        System.out.println(\"A \" + o.getClass() + \" which is composed of:\");
        display(f.get(o));
    }
}
(为简单起见,省略了其他原始类型和数组。) 尽管
Field
\的
get
方法返回了
Object
,但我认为将为原始类型包装器(整数,字符串等)调用正确的方法,但实际上,仅叫
display(Object o)
(不执行隐式向下转换)。 就目前而言,我发现的唯一解决方案是,如果可能的话,将对象残酷地向下转换:
public static void display(Object o)
{
    if (o instanceof Integer)
    {
        display((Integer) o);
        return;
    }
    else if (o instanceof String 
    {
        ... 
    } // And so on

    for (Field f : c.getFields())
    {
        System.out.println(\"A \" + o.getClass() + \" which is composed of:\");
        display(f.get(o));
    }
}
但是,这看起来确实很丑陋,我想知道是否有更优雅的方法来确保调用正确的方法。 有任何想法吗? 在此先感谢StackOverflow的好人!     

解决方法

        您想要的就是所谓的“双重调度”,Java不支持。 您可以通过反射来模拟它:检查所有
display
方法及其参数类型,并根据对象的运行时类型动态调用其中之一。 对于这个问题,这是不必要的聪明。您的if-else连锁店很好。     ,        好问题。我昨天晚上也想知道;) 因此,答案是有两种不同类型的多态:编译时和运行时多态。 当您使用超类型的方法和sybtypes的替代方法时,这是运行时多态。 当您将超类型和子类型用作不同重载方法的参数时,这就是编译时多态。 因此,在您的情况下,编译器必须在编译时知道要执行哪种方法(/重载),它不会在运行时做出此决定。 如果您可以控制字段类,则一种解决方案是使用泛型,以便您定义一个
class Field<T> 
用一种方法
T get( Object o )
这样,编译器将能够在编译时知道在编译时使用哪种方法进行显示,就像在编译时知道field.get返回的是哪种类型。 但是,根据您的评论,您将使用JDK的类java.lang.reflect.Field,因此,您无法对其进行控制以使其通用。在这种情况下,是的,唯一的解决方案是拥有一个处理field.get的所有可能类型的显示方法。但是确实,String.valueOf方法可以在这里提供很大的帮助,因为它提供了Java中任何类型的字符串表示形式,已经完成了您要查找的重载工作。 来源在这里。 问候,  斯特凡     ,        Java不支持“多重多态”。您可能想看看Visitor模式。这几乎是“访客”的教科书示例。