首页 > 解决方案 > 取决于实际对象类型的动态引用转换

问题描述

我有类层次结构,例如

ChildA extends Parent
ChildB extends Parent
ChildC extends Parent

然后在我的应用程序中,我通过 Parent 引用获取任何这个孩子的方法。

问题是所有这些孩子都有相同的方法,但他们的父母没有

所以,ChildA, ChildB, and ChildC都有getSomeValue()吸气剂,但Parent没有。

现在我需要解析来自任何这个孩子的值,但是 Parent 参考没有为我提供 API,所以我需要将 Parent 转换为特定的孩子类型。

下面是代表我正在尝试做的片段:

private void processChildren(Parent parent) {
    ChildA childA = null;
    ChildB childB = null;
    ChildC childC = null;

    if (parent instanceof ChildA) {
        childA = parent;
    }

    if (parent instanceof ChildB) {
        childB = parent;
    }

    if (parent instanceof ChildC) {
        childC = parent;
    }

    String someValue;

    if (Objects.nonNull(childA)) {
        someValue = childA.getSomeValue();
    } // and the same checks and extracts for each of childs and for many methods

}

正如您所看到的,为了仅提取一个值,我需要创建 3 个引用,然后检查它们以强制转换为特定类型,然后检查实际创建的类型以调用该方法。

问题是如何在运行时正确地将引用转换为特定子引用?我想可以使用反射来编写,尽管即使使用反射我也无法解决它。

此外,即使可能 - 可以这样做吗?

仅供参考:我正在开发一个遗留应用程序,所以我不能更改以前编写的代码,所以我不能在父类中添加这个 API。此外,这些类是从外部 jar 提供的。

标签: javadynamicreflection

解决方案


作为一种可能的解决方案,您可以创建一个由特定子类参数化的映射作为键,供应商作为值。每个供应商都负责铸造和处理特定的方法。

Map<Class<? extends Parent>, Supplier> getValueMap = new HashMap<>();

getValueMap.put(ChildA.class, () -> { return ((ChildA) parent).getValue(); });
getValueMap.put(ChildB.class, () -> { return ((ChildB) parent).getValue(); });
getValueMap.put(ChildC.class, () -> { return ((ChildC) parent).getValue(); });

getValueMap.get(parent.getClass()).get();

推荐阅读