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
}