4

考虑以下类

public interface SortBy<S> {
}

public class CommentSortBy<S> implements SortBy<S> {
    public static CommentSortBy<Date> CREATION = new CommentSortBy<Date>();
    public static CommentSortBy<Integer> VOTES = new CommentSortBy<Integer>();
}

public class SomeQueryUnsafe {
    public <M, S extends SortBy<M>> void setSort(S sortBy, M min) {
        //Set relevant values
    }
}

这目前用作:

public SomeQueryUnsafe createCommentQueryUnsafe() {
    return new SomeQueryUnsafe();
}

public void test() {
    createCommentQueryUnsafe().setSort(CommentSortBy.CREATION, new Date());
}

虽然这可行,但问题是createCommentQueryUnsafe()没有指定对sortBy. 用户可以自由通过UserSortBy.NAME,即使在这种情况下这没有任何意义

我不知道如何写这个,因为只是添加<B extends SortBy>到类签名意味着我失去了限制min方法中参数的能力。我不能使用诸如<M, S extends B & SortBy<M>>编译器错误之类的东西。其他使用通配符魔法的尝试只会导致更多的复杂性和编译器错误。将排序转移到createCommentQuery()方法意味着每个查询都需要 2 个方法,这是大量重复的代码

我怎么可能编写泛型,从而createCommentQuery()sortBy参数限制为仅CommentSortBy同时仍然min限制为 SortBy 类中的 S 参数?

4

1 回答 1

3

由于您指出的原因,这确实是一个棘手的问题。我尝试了各种方法,但都被您引用的泛型限制打败了。最终,如果您想要指定的类型安全性,您似乎需要进行一些设计更改。

对泛型类型限制使用实现的继承层次结构SortBy似乎特别导致了这种僵局。我尝试将该限制解耦为一个新的类型参数 on SortBy,它代表被查询的对象本身,例如Comment,User等。这是我想出的设计:

static class Comment { }

static class User { }

interface SortBy<T, M> { }

static class CommentSortBy<M> implements SortBy<Comment, M> {

    static final CommentSortBy<Date> CREATION = new CommentSortBy<Date>();
    static final CommentSortBy<Integer> VOTES = new CommentSortBy<Integer>();
}

static class UserSortBy<M> implements SortBy<User, M> {

    static final UserSortBy<String> NAME = new UserSortBy<String>();
}

static class Query<T> {

    public <M> void setSort(SortBy<T, M> sortBy, M min) {
        //Set relevant values
    }
}

public static void main(String[] args) {

    new Query<Comment>().setSort(CommentSortBy.CREATION, new Date());
    new Query<Comment>().setSort(UserSortBy.NAME, "Joe"); //compiler error
}

想法

于 2013-07-15T16:53:28.417 回答