Java 多态性和向下转型

6
我正在使用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));
    }
}

(为简化起见,其他原始类型和数组被省略。)
尽管 Fieldget 方法返回一个 Object,但我认为适当的方法会被调用来处理原始类型包装器(Integers、Strings 等),但实际上,只有 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的好心人!


这似乎是一个典型的解决方案,继承和多态性可以解决您的问题。但我不确定如何在不为所有可显示类型扩展子类的情况下实现它。 - ashes999
1
@Steven:(Integer)o 是向下转型。 - Oliver Charlesworth
@Oli:哇,真不敢相信我这么长时间以来一直都是反过来命名的。:O 谢谢。 - Steven Jeuris
3个回答

3

很好的问题。昨晚我也在想这个问题 ;)

答案是有两种不同类型的多态性:编译时多态性和运行时多态性。

当您使用超类型的方法和子类型的重写方法时,这是运行时多态性。

当您将超类型和子类型用作不同重载方法的参数时,这是编译时多态性。

因此,在您的情况下,编译器必须在编译时知道要执行哪个方法/重载,它不会在运行时做出此决定。

如果您有控制字段类,则解决方案是使用泛型,以便定义一个

class Field<T> 

使用一种方法

T get( Object o )

然后编译器就能够在编译时知道要使用哪个方法进行显示,因为它可以在编译时知道field.get返回的类型。

但是,根据您的评论,您使用了JDK的类java.lang.reflect.Field,因此无法控制它使其通用。在这种情况下,是的,唯一的解决方案是创建一个处理field.get所有可能类型的显示方法。但是,String.valueOf方法可以极大地帮助您,因为它为Java中的任何类型提供了字符串表示形式,并已经完成了您寻找的重载工作。

来源在此

祝好, Stéphane


对于除了关于泛型的部分之外的所有内容,给予+1。但是对于关于泛型的部分,给予-1(至少在你澄清你的意思之前!我不确定你建议在这里如何使用泛型...) - Oliver Charlesworth
除非我没有正确理解你的意思,否则我无法控制由反射API提供的“get”方法。因此,我无法将其变为通用方法。 - executifs

1
你想要的是所谓的“双重分派”,而Java不支持它。
你可以通过反射来模拟它:检查所有的display方法及其参数类型,并根据对象的运行时类型动态调用其中之一。
对于这个问题来说,这种方法过于聪明了。你的if-else链已经足够好了。

0
Java不支持“多态性”。您可能想看一下访问者模式。这几乎是访问者模式的一个典型例子。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接