尝试使用泛型返回值时出错

时间:2015-09-04 17:49:13

标签: java generics

当我尝试返回 INSTANCE 时,我收到此编译错误“需要T,找到UseCaseTest” 在类 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();
    }

}

2 个答案:

答案 0 :(得分:1)

你需要让你的班级知道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
}

答案 1 :(得分:1)

静态方法/字段与泛型相关的主题已经很好地描述了in this post

尽管如此,这似乎是一个简单的转换使编译器开心,同时允许保持某种程度的泛型:

public T keepStateBetweenTests() {
    if (INSTANCE == null)
        INSTANCE = getInstance(activityTestRule); 

    return (T)INSTANCE;
}

<强>更新

你的部分问题是为什么这可以编译,尽管有错误:

if (INSTANCE == null) INSTANCE = getInstance(activityTestRule);

根据我的理解,编译器知道INSTANCE本身实际上是UseCaseTest,它符合Builder类定义的限制:<T extends UseCaseTest>