通用对象获取器

时间:2017-04-26 23:46:20

标签: java generics

我有以下类结构:

public class BasePage {
    ...
}

public class PageA extends BasePage {
    ...
    public void doStuffA() {}
}

public class PageB extends BasePage {
    ...
    public void doStuffB() {}
}

然后我有另一个包含一些getter / setter的类:

public class TestBase {

private static BasePage currentPage;

public static <T extends BasePage> T getCurrentPage() {
    return (T) currentPage;
}

public static void <T extends BasePage> setBasePage(T page) {
    currentPage = page
}

在我的测试中,我喜欢使用这样的方法:

TestBase.getCurrentPage<PageA>().doStuffA()

但IntelliJ似乎不喜欢最后一种语法。我究竟做错了什么?

  

它说:无法解析符号&#39; getCurrentPage&#39;

似乎可以解析TestBase.getCurrentPage(),但我无法访问doStuff方法。

2 个答案:

答案 0 :(得分:3)

(PageA)TestBase.getCurrentPage().doStuffA()

答案 1 :(得分:0)

快速修复

正如@Andrew所指出的,这就是为静态方法指定泛型类型的方法:

TestBase.<PageA>getCurrentPage().doStuffA();

这与我们在Collections.emptyList()使用的语法完全相同:

Collections.<String>emptyList();

重新设计

我有点担心这不是你真正需要的。即您可以为getCurrentPage()指定一种类型,为setCurrentPage()指定另一种类型。在这两种情况下,您都是<T extends BasePage>。但是,这是一种方法级别的类型,因此您可以通过每次调用来更改它们。比如说,这会传递编译器。另一方面,它会给你一个ClassCastException

TestBase.<PageB>setBasePage(new PageB());
TestBase.<PageA>getCurrentPage().doStuffA(); // Fine for the compiler. Throws an Exception though

我会将currentPage重写为非静态字段,我会在这种情况下使用类级别类型:

public class TestBase <T extends BasePage> {

    private T currentPage;

    public T getCurrentPage() {
        return currentPage;
    }

    public void setBasePage(T page) {
        currentPage = page;
    }

}

它使语法简单:

TestBase<PageA> testBase = new TestBase<>(); // specify the page type
testBase.setBasePage(new PageA());
testBase.getCurrentPage().doStuffA(); // easy-peasy

此外,编译器会为您发现类型错误:

TestBase<PageA> testBase = new TestBase<>(); // specify the page type
testBase.setBasePage(new PageB()); // compiler error