Consider the following classes
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) {
Currently used as:
public SomeQueryUnsafe createCommentQueryUnsafe() { return new SomeQueryUnsafe(); } public void test() { createCommentQueryUnsafe().setSort(CommentSortBy.CREATION, new Date()); }
While this works, the problem is that createCommentQueryUnsafe() does not indicate a restriction on sortBy . Users can pass UserSortBy.NAME , although this does not make sense in this context.
I cannot figure out how to do this because simply adding <B extends SortBy> to the class signature means that I am losing the ability to limit the min parameter in the method. I cannot use something like <M, S extends B & SortBy<M>> as its compiler error . Other attempts using wildcard magic lead to significant complication and compiler errors. Moving the sort to the createCommentQuery() method would mean that 2 methods are required for each query, which is an insane amount of duplicated code
How can I write generalizations, so createCommentQuery() restricts the sortBy parameter sortBy only CommentSortBy , but CommentSortBy min limit it to the S parameter in the SortBy class?
Thelq source share