实例化一个泛型类 T 对象并返回它。

huangapple go评论81阅读模式
英文:

Instantiate a generic class T object and return it

问题

我正在编写Java Selenium测试,并尝试设置一个具有流畅/方法链接设计的代码:

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

Button.java

public class Button<T, U> {
    public T observe() {
        return new T(); // 不起作用
    }

    public U click() {
        return new U(); // 不起作用
    }
}

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(); //等等。
    }
}

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

英文:

I'm working on java selenium tests and I am trying to setup a fluent/method-chaining design code:

I have a generic button class that allows navigating from a page class to the other. Buttons are attributes of my pages classes. Method in the button class should be able to return generic page classes that were defined on button instantiation (the page you are on, the page the button leads to etc.).
But I can't figure how to do it without breaking the fluent design in the main class:

Button.java

public class Button&lt;T, U&gt; {
    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&lt;FirstPage, SecondPage&gt; buttonOnFirstPage = new Button&lt;&gt;();
}

SecondPage.java

public class SecondPage {
    public Button&lt;SecondPage, AnotherPage&gt; buttonOnSecondPage = new Button&lt;&gt;();
}

And finally what I want to be able to do without casting or mentioning types, in order to benefit from autocompletion and other fancy IDE stuff:
BrowsingTest.java

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

Any idea on how I can build that button class? Thanks a lot!

答案1

得分: 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);
}
英文:

Generic types are a compile-time notation for ensuring type safety. They are erased at runtime.

This means T and U do not exist at runtime. Which is why you can’t instantiate them.

You can, however, pass in the constructors yourself:

public class Button&lt;T, U&gt; {
    private final Supplier&lt;? extends T&gt; tConstructor;
    private final Supplier&lt;? extends U&gt; uConstructor;

    public Button(Supplier&lt;? extends T&gt; tConstructor,
                  Supplier&lt;? extends U&gt; uConstructor) {

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

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

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

And you can pass those constructors as method references:

public class FirstPage {
    public Button&lt;FirstPage, SecondPage&gt; buttonOnFirstPage =
        new Button&lt;&gt;(FirstPage::new, SecondPage::new);
}

答案2

得分: 0

不可能创建一个泛型类型的实例,而是应该寻找这些解决方法:
https://stackoverflow.com/questions/299998/instantiating-object-of-type-parameter

英文:

It's not possible to create an instance out of generic type
you should look for these workarounds instead:
https://stackoverflow.com/questions/299998/instantiating-object-of-type-parameter

huangapple
  • 本文由 发表于 2020年7月30日 01:23:36
  • 转载请务必保留本文链接:https://go.coder-hub.com/63159135.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定