我得到这个编译错误"required T, found UseCaseTest"当我试图返回INSTANCE类UseCaseTest的方法keepStateBetweenTests。我知道我可以很容易地将它转换为T,但是
另外,我不知道为什么这行
if (INSTANCE == null) INSTANCE = getInstance(activityTestRule);
可以编译,因为前面的错误。
我再提供两个类来提供特定的上下文。
UseCaseTest
public abstract class UseCaseTest {
private static UseCaseTest INSTANCE;
public abstract static class Builder<T extends UseCaseTest> {
private final ActivityTestRule activityTestRule;
protected Builder(ActivityTestRule activityTestRule) {
this.activityTestRule = activityTestRule;
}
public T keepStateBetweenTests() {
if (INSTANCE == null) INSTANCE = getInstance(activityTestRule);
return INSTANCE; //compile error: required T, found UseCaseTest
}
public T releaseStateBetweenTests() {
return getInstance(activityTestRule);
}
protected abstract T getInstance(ActivityTestRule activityTestRule);
}
private final ActivityTestRule activityTestRule;
public UseCaseTest(ActivityTestRule activityTestRule) {
this.activityTestRule = activityTestRule;
}
}
SessionUseCaseTest
public final class SessionUseCaseTest extends UseCaseTest {
public static Builder<SessionUseCaseTest> with(ActivityTestRule activityTestRule) {
return new Builder<SessionUseCaseTest> (activityTestRule) {
@Override protected SessionUseCaseTest getInstance(ActivityTestRule activityTestRule) {
return new SessionUseCaseTest(activityTestRule);
}
};
}
private SessionUseCaseTest(ActivityTestRule activityTestRule) {
super(activityTestRule);
}
public void signUp() {}
public void logout() {}
}
SessionTest
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class SessionTest extends BaseTest {
@Test public void _1_SingUp() {
SessionUseCaseTest.with(mActivityRule)
.keepStateBetweenTests()
.signUp();
}
@Test public void _2_Logout() {
SessionUseCaseTest.with(mActivityRule)
.keepStateBetweenTests()
.logout();
}
}
静态方法/字段与泛型结合的主题在这篇文章中有很好的描述
尽管如此,一个简单的类型转换似乎使编译器很高兴,同时允许保留某种级别的泛型:
public T keepStateBetweenTests() {
if (INSTANCE == null)
INSTANCE = getInstance(activityTestRule);
return (T)INSTANCE;
}
你的问题的一部分是为什么这可以编译,虽然有错误:
if (INSTANCE == null) INSTANCE = getInstance(activityTestRule);
根据我的理解,编译器知道INSTANCE
本身实际上是UseCaseTest
,它满足了Builder
类上定义的限制:<T extends UseCaseTest>
你需要让你的类意识到类型T,即
public abstract class UseCaseTest <T> {
你可以这样做:-
class UseCaseTest<T> {
final Class<T> useCaseTestType;
public UseCaseTest(Class<T> useCaseTestType) {
this.useCaseTestType = useCaseTestType;
}
//Then write your methods which are generic
}