【问题标题】:Instantiate a generic class T object and return it [duplicate]实例化一个通用类 T 对象并返回它[重复]
【发布时间】:2020-11-19 08:53:16
【问题描述】:

我正在进行 java selenium 测试,我正在尝试设置一个流畅/方法链接的设计代码:

我有一个通用按钮类,它允许从一个页面类导航到另一个。按钮是我的页面类的属性。按钮类中的方法应该能够返回在按钮实例化时定义的通用页面类(您所在的页面、按钮指向的页面等)。 但是如果不破坏主类中的流畅设计,我不知道该怎么做:

Button.java

public class Button<T, U> {
    public T observe() {
        return new T(); // Does not work
    }

    public U click() {
        return new U(); // Does not work
    }
}

FirstPage.java

public class FirstPage {
    public Button<FirstPage, SecondPage> buttonOnFirstPage = new Button<>();
}

SecondPage.java

public class SecondPage {
    public Button<SecondPage, AnotherPage> buttonOnSecondPage = new Button<>();
}

最后,我希望能够在不强制转换或提及类型的情况下做些什么,以便从自动完成和其他花哨的 IDE 东西中受益: BrowsingTest.java

public class BrowsingTest {
    public static void main(String[] args) {
        new FirstPage()
            .buttonOnFirstPage.observe()
            .buttonOnFirstPage.click()
            .buttonOnSecondPage.observe()
            .buttonOnSecondPage.click(); //etc.
    }
}

关于如何构建该按钮类的任何想法?非常感谢!

【问题讨论】:

  • 令人讨厌的是,这已关闭以重定向到十年前的一些难以辨认的答案,这无疑会阻止您尝试。在您的情况下,这完全可行。提示:为每个按钮(new Button&lt;&gt;(){})创建一个匿名子类以锁定泛型,在构造函数中使用 GuavaTypeToken 轻松提取Class&lt;T&gt;

标签: java generics return-value method-chaining fluent-interface


【解决方案1】:

泛型类型是一种用于确保类型安全的编译时表示法。它们在运行时被擦除。

这意味着TU 在运行时不存在。这就是为什么你不能实例化它们。

但是,您可以自己传入构造函数:

public class Button<T, U> {
    private final Supplier<? extends T> tConstructor;
    private final Supplier<? extends U> uConstructor;

    public Button(Supplier<? extends T> tConstructor,
                  Supplier<? extends U> uConstructor) {

        this.tConstructor = tConstructor;
        this.uConstructor = uConstructor;
    }

    public T observe() {
        return tConstructor.get();
    }

    public U click() {
        return uConstructor.get();
    }
}

您可以将这些构造函数作为方法引用传递:

public class FirstPage {
    public Button<FirstPage, SecondPage> buttonOnFirstPage =
        new Button<>(FirstPage::new, SecondPage::new);
}

【讨论】:

  • 这个解决方案没有问题但是泛型在运行时不会被删除,具体子类型将它们锁定。请参阅 TypeToken 了解如何利用这一事实。 stackoverflow.com/questions/38046880/…
  • @drekbour 请注意,TypeToken 子类是非泛型类。
  • 同意,但您明确表示,当有一个完美的解决方案时,没有解决 T 的解决方案(假设设计可以继承)。
  • @drekbour 你可能想自己写答案。
  • 像魅力一样工作:)
【解决方案2】:

不可能从泛型类型中创建实例 您应该寻找这些解决方法: Instantiating object of type parameter

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多