Reputation: 596
I have the following class structure:
public class BasePage {
...
}
public class PageA extends BasePage {
...
public void doStuffA() {}
}
public class PageB extends BasePage {
...
public void doStuffB() {}
}
Then I have another class that contains some getters/setters:
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
}
And inside my tests I'd like use the methods like so:
TestBase.getCurrentPage<PageA>().doStuffA()
But IntelliJ does not seem to like that last syntax. What am I doing wrong?
It says: Cannot resolve symbol 'getCurrentPage'
It does seem to be able to resolve TestBase.getCurrentPage()
but I can't access either doStuff
methods.
Upvotes: 1
Views: 1189
Reputation: 7166
As @Andrew pointed out, this is how you can specify a generic type for a static method:
TestBase.<PageA>getCurrentPage().doStuffA();
This is the very same syntax we use at Collections.emptyList()
:
Collections.<String>emptyList();
I'm a little concerned that this isn't really what you need. I.e. you can specify a type for the getCurrentPage()
, and another for setCurrentPage()
. In both of the cases you're <T extends BasePage>
. However, this is a method-level type, so you can change them by each invocation. Say for instance, this passes the compiler. On the other hand, it will give you a ClassCastException
:
TestBase.<PageB>setBasePage(new PageB());
TestBase.<PageA>getCurrentPage().doStuffA(); // Fine for the compiler. Throws an Exception though
I would rewrite currentPage
as a non-static field and I'd use a class-level type for this case:
public class TestBase <T extends BasePage> {
private T currentPage;
public T getCurrentPage() {
return currentPage;
}
public void setBasePage(T page) {
currentPage = page;
}
}
It makes the syntax easy:
TestBase<PageA> testBase = new TestBase<>(); // specify the page type
testBase.setBasePage(new PageA());
testBase.getCurrentPage().doStuffA(); // easy-peasy
Also, the compiler will spot type errors for you:
TestBase<PageA> testBase = new TestBase<>(); // specify the page type
testBase.setBasePage(new PageB()); // compiler error
Upvotes: 0