Java - 在编译时不知道结果类型的情况下,方法如何返回变量类型对象?

标签 java generics interface

假设您有一个接口(interface)和两个实现该接口(interface)的类:

public interface IElement {
    boolean isDisplayed();
}

public class Button implements IElement  {
    @Override
    public boolean isDisplayed() {
        // checks if displayed
        return false;
    }

    public void click() {
        // clicks
    }
}

public class Textbox implements IElement  {
    @Override
    public boolean isDisplayed() {
        // checks if displayed
        return false;
    }

    public void enterText(String text) {
        // enters text
    }
}

在一个完全独立的类中,我们有一个方法,它希望根据提供的参数的值返回按钮或文本框。像这样的东西:

public class WhichElement {

    public <T extends IElement> T getElement(String elementName) {

        if (elementName.equalsIgnoreCase("button")) {
            return new Button();
        }
        else if (elementName.equalsIgnoreCase("textbox")) {
            return new Textbox();
        }
    }
}

但是失败了,因为返回的对象不是 T 类型。 我尝试过返回这样的界面:

public IElement getElement(String elementName)

但是我无法做我真正想做的事情,那就是:

WhichElement picker = new WhichElement();
picker.getElement("button").click();  <-- errors here because it's an IElement not a Button :(

我可以将其转换为正确的对象,并相信该方法会返回与我将其转换为相同的对象......但这似乎很危险。我更希望该方法确定所需对象的类型并直接返回该对象。 有办法做我正在尝试的事情吗?

最佳答案

您可以在返回之前将 getElement() 的结果强制转换为 T,这将产生编译器警告。

出现警告是因为编译器将在调用站点插入强制转换,如果运行时结果不是正确的类型,则会从以下位置抛出 ClassCastException没有明显的 Actor 阵容。本质上,编译器生成的代码与您在 getElement() 不是泛型时编写的代码相同,只是返回 IElement

不要使用一种工厂方法来生成多种类型,而是为每种类型创建不同的工厂方法。这将为您提供类型安全性,确保实际提供应用程序所需的每个元素,帮助重构,并将 getElement("buttton") 等运行时错误更改为编译时错误。

依赖注入(inject)是另一种方法:为应用程序提供一个按钮,而不是定位按钮本身。

关于Java - 在编译时不知道结果类型的情况下,方法如何返回变量类型对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39521517/

相关文章:

Fortran 中的接口(interface)类型绑定(bind)过程

c++ - 公开组合成员对象是个好主意吗?

java - 如何让 maven appassembler 在生成的脚本中使用 javaw 而不是 java

java - 如何在 android 应用程序的 gridview 单元格中心设置文本?

具有静态工厂方法的 Java 泛型

c# - 是否可以将 DataAnnotations 与接口(interface)继承一起使用?

java - 在 Tomcat 服务器上部署独立的 jar

java - Android Java - 解析 "76"时出现 NumberFormatException

swift - 通用 Controller 内的通用 Swift 协议(protocol)

java - 什么是 PECS(生产者扩展消费者 super )?