Java 使用参数指定有效的泛型类型

Java 使用参数指定有效的泛型类型,java,generics,Java,Generics,考虑以下几类 public interface SortBy<S> { } public class CommentSortBy<S> implements SortBy<S> { public static CommentSortBy<Date> CREATION = new CommentSortBy<Date>(); public static CommentSortBy<Integer> VOTES

考虑以下几类

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
    }
}
虽然这样做有效,但问题是
createCommentQueryUnsafe()
没有指定
sortBy
的限制。用户可以自由地通过
UserSortBy.NAME
,即使在这种情况下这没有意义

但是我不知道如何写这个,因为仅仅向类签名添加
意味着我失去了在方法中限制
min
参数的能力。我不能使用像
这样的东西。其他使用通配符魔术的尝试只会导致更大的复杂性和编译器错误。将排序移动到
createCommentQuery()
方法意味着每个查询都需要两个方法,这是大量重复的代码


我如何编写泛型以便
createCommentQuery()
sortBy
参数限制为仅
CommentSortBy
,同时仍将
min
限制为sortBy类中的S参数?

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

对于泛型类型限制,使用
SortBy
实现的继承层次结构似乎特别导致了这种僵局。我尝试在
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
}
静态类注释{}
静态类用户{}
接口排序为{}
静态类CommentSortBy实现SortBy{
静态最终CommentSortBy CREATION=新建CommentSortBy();
静态最终评论票数=新评论票数();
}
静态类UserSortBy实现SortBy{
静态final UserSortBy NAME=new UserSortBy();
}
静态类查询{
公共无效设置排序(排序,最小M){
//设置相关值
}
}
公共静态void main(字符串[]args){
new Query().setSort(CommentSortBy.CREATION,new Date());
new Query().setSort(UserSortBy.NAME,“Joe”);//编译器错误
}

()

首先,有许多“创建”方法:
createUserQuery()
createCommentQuery()
,等等。每个方法都需要创建一个查询,将排序值限制在其特定的上下文中。您所做的只是让create方法返回泛型版本,它仍然允许
createCommentQuery()
接受
UserSortBy.NAME
,这是一个对注释完全无效的值。理想情况下,
createCommentQuery()
将返回类似于
SomeQuery
,这意味着sortBy将只接受
sortBy(CommentSortBy.CREATION,someDate)
sortBy(CommentSortBy.voces,5L)
,但不是
sortBy(UserSortBy.NAME,“Sam”)
Wow,这是一个非常巧妙的解决方案,所以+1(如果没有更多的答案,一两天内接受)这显然是我以后要保存的东西。在我的情况下,我不能这样做的唯一原因是我正在使用的排序API(StackExchange API)的复杂性,其中一些返回
注释的查询具有不同的可接受
排序值。对象图开始与您的解决方案变得非常复杂。非常感谢您的想法,我非常感谢。很可能我将使用发布问题后的想法:移动设置
min
max
CommentSortBy
类对
CommentSortBy的值。这允许更大的灵活性(和更少的泛型)以牺牲更笨拙的api为代价。这是我试图避免的事情,但现在看来似乎没有其他选择,当然,
S
是不必要的。上面的
setSort
可以声明为
public void setSort(SortBy SortBy,M min)
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
}