java - 一种查找 Java 对象初始化为什么而不是声明类型的方法?

标签 java visitor-pattern

我不知道我是否遗漏了什么,但我在将对象转换为其实际的初始化类型时遇到了问题。基本上,如果我用“SuperClass sc = new SubClass()”创建一个对象,然后我在 sc 上调用一个方法,我希望该方法能够调用方法(子类)而不是方法(父类(super class))。示例如下:

public class Example
{
    public static void act(SuperClass a) {
        System.out.println("SuperClass");
    }

    public static void act(SubClass a) {
        System.out.println("SubClass");
    }

    public static void main(String[] args) {
        SuperClass sc = new SubClass();

        // want to find a way to call act(SubClass) instead of act(SuperClass)
        act(sc);
   }
}

class SuperClass {}
class SubClass extends SuperClass {}

我现在正在使用访问者模式,但我想知道是否有其他方法可以做到这一点,也许是通过 Java 反射 API?

提前致谢!

== 编辑 ==

我知道一般来说,对于 OO 来说,最好将功能粘回到父类(super class)/子类本身,但对于我的特定用例,我有一堆子类是不可变的模型类,应该传递给不同类型的执行引擎(想想不同的“示例”类)。子类/模型类应该只包含不可变信息,仅此而已,实际的真正功能在于执行引擎(示例类)。这就是为什么我想知道访问者模式的替代方案。有没有人有办法恢复 Java 中实际的“初始化”信息?如果是这样,非常感谢。

而且由于问题的性质,我不能使用直接转换... 想象一下,如果我有一个 SuperClass 的数组列表,其中每个元素可能是 SubClass1、SubClass2、SubClass3,它们都是从 SuperClass 扩展而来的。

现在,当您从 Arraylist 中提取内容时,您会得到一个 SuperClass 对象,即使它们实际上可能是 SubClass1、SubClass2、SubClass3 等。

接下来,我想调用 act(SubClass1),并能够对当前类型调用正确的 act() 方法。所以我想结束调用 act(SubClass1)、act(SubClass2)、act(SubClass3),而不是 act(SuperClass)。

== 再次编辑==

我想出了一种通过 Java 反射 API 实现此目的的方法,方法是使用 Class.forName(classname) 查找子类的实际基础类型,然后使用正确的方法签名动态调用该方法。对于对此问题感兴趣的人,我已将其以答案形式写在本页下方的某个位置。请注意,这不是完成我在这里尝试做的事情的非常有效的方法,如果您遇到我的情况,您最好使用访问者模式或 if-else 语句。


所以 Nicola Musatti 给出的答案最接近于回答我的问题,尽管正如他也指出的那样,随着子类数量的增加,if-else 语句列表会变得很长。我会选择他的答案作为接受答案,因为我没有在我的问题中明确说明我希望避免 if-else 检查。

无论如何,所以我今天对 Java Reflection API 进行了一些尝试并想出了这个:

SuperClass sc = new SubClass();

// Get the actual class of sc. actualClass now is SubClass.
Class actualClass = Class.forName(sc.getClass().getCanonicalName());

// Basically invoking act(SubClass sc) instead of act(SuperClass sc)
Class parameters[] = {actualClass};
Method method = Example.class.getMethod("act", parameters);
Object arguments[] = {sc};
method.invoke(null, arguments);

这肯定不是做事的好方法,特别是因为 Java 反射 API 强加的性能损失。这可能比访问者模式或 if-else 检查你是否有一百万个子类要好,因为它可能需要更少的代码来管理,但是我现在会坚持使用访问者模式,因为我没有一百万个子类要管理.

无论如何,只是想我会在这里发布这个来证明它是可以做到的,只是为了那些好奇的人。

最佳答案

你不应该在 SuperClassSubClass 中定义 act() 吗?这样,无论对象引用的类型如何,都会调用正确的方法。

编辑:如果我没记错的话,访问者模式在要访问的元素上定义了类似 accept() 的方法,它允许访问者以多态方式访问所访问元素中它感兴趣的任何内容。

关于java - 一种查找 Java 对象初始化为什么而不是声明类型的方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6899326/

相关文章:

java - 数组未正确打印

java - 我可以通过常规 J​​ava main 方法从 Android 项目运行纯 Java 代码的子集吗?

java - 如何使底部工作表对话框的角变圆?

design-patterns - 访问者模式和编译器代码生成,如何获取子属性?

JavaParser 不更新源文件

Java Wicket (6.19) IVisitor 参数传递

c++ - 需要一个虚拟模板成员解决方法

php - 访客柜台

java - 如何在约束布局中创建容器以便设置背景?

java - 如果包含在特定的结尾列表中,则删除单词结尾