问题
I am writing some classes using Generics but I can't find a solution for the class SolutionsSubset and so I a getting the error "type parameter S is not within its bound". I have read previous questions about the same error but I can't solve it for my case. Could anybody help me to improve my knowledge about generics? Any reference to a good book (I can find in google a lot of information but if someone can reccommend a book, tutorial, etc. will be welcome). Although I tried to keep in mind the rules to ask a question but I apologize if my question doesn't fulfill these rules.
I have the following classes and interfaces:
public interface Subset<T extends Comparable<T>> extends Comparable<Subset<T>>
public class MathSubset<T extends Comparable<T>> extends TreeSet<T> implements Subset<T>
public interface Solution<T extends Comparable<T>>
public interface Solutions<S extends Solution<?>> extends Iterable<S>
public class SolutionsSubset<S extends Solution<?>> extends MathSubset<S> implements Solutions<S>
I need that Subset extends Comparable. In SolutionsSubset, the class MathSubset stores Solution objects. How do I have to change these definition to make it work?
Thanks you in advance
回答1:
In order to be used as the type argument in MathSubset
, SolutionsSubset
s S
must extend Comparable<S>
. As a compilable example:
import java.util.TreeSet;
interface Subset<T extends Comparable<T>>
extends Comparable<Subset<T>> { }
class MathSubset<T extends Comparable<T>>
extends TreeSet<T>
implements Subset<T>
{
public int compareTo(Subset<T> other) { throw new Error(); }
}
interface Solution<T extends Comparable<T>> { }
interface Solutions<S extends Solution<?>> extends Iterable<S> { }
class SolutionsSubset<S extends Solution<?> & Comparable<S>>
extends MathSubset<S>
implements Solutions<S>
{ }
A few comments: This is very abstract example, and so not easy to think about. Laying out the code so you don't need to scroll is good. There's an awful lot of inheritance going on here, perhaps compose rather than, say, extending TreeSet
. It's difficult to distinguish between the identifiers Solutions
and Solution
.
回答2:
Generics are something that can quickly get out of hand, especially if you try to "be all generic" all at once. Less is more. What always helps me is to start concrete (including the implementation) and then slowly substitute generic parameters in, one parameter and class at a time.
Could anybody help me to improve my knowledge about generics?
http://www.angelikalanger.com/GenericsFAQ/JavaGenericsFAQ.html
Not a tutorial, but lots of useful info. Its one of those references that you read the parts you can understand, but come back to over and over again in the future as you gain more mastery and more of it begins to make sense.
回答3:
First of all, here is the full error (which is specific to MathSubset not getting a proper parameter): Bound mismatch: The type S is not a valid substitute for the bounded parameter <T extends Comparable<T>> of the type QifFixer.MathSubset<T>
The problem is that MathSubset expects a <T extends Comparable<T>
, but you're giving it a S extends Solution<?>
- those types having nothing to do with each other, because a Solution does not inherit or implement Comparable<T>
.
If anything, you could try this:
public class SolutionsSubset<S extends Comparable<S>> extends
MathSubset<S> implements Solutions<Solution<S>>;
Unfortunately, this will STILL not work because MathSubset implements Iterable, but so does Solutions.
An easy fix would be for Solutions to not extend Iterable, but it really sounds to me like you're trying to use a more complex approach than you need to. May be a "has-a" instead of "is-a" design might be more beneficial here?
来源:https://stackoverflow.com/questions/4423026/about-error-using-java-generics-type-parameter-s-is-not-within-its-bound