关于使用Java泛型的错误:“类型参数S不在其范围内”

时间:2021-12-15 16:28:59

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.

我正在用泛型写一些类,但是我找不到类solution tions子集的解决方案,所以我得到了一个错误“类型参数S不在它的范围内”。我之前读过关于同样错误的问题,但是我不能解决我的问题。谁能帮助我提高我的泛型知识?任何对一本好书的引用(我可以在谷歌中找到很多信息,但是如果有人能推荐一本书、教程等,将会受到欢迎)。虽然我试图记住问问题的规则,但如果我的问题不符合这些规则,我道歉。

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?

我需要那个子集扩展可比。在solutions子集中,类math子集存储解决方案对象。我要如何改变这些定义才能让它生效?

Thanks you in advance

提前谢谢你

3 个解决方案

#1


6  

In order to be used as the type argument in MathSubset, SolutionsSubsets S must extend Comparable<S>. As a compilable example:

为了在math子集中用作类型参数,SolutionsSubsets S必须扩展可比的。作为一个compilable的例子:

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


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

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


1  

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>

首先,这里有一个完整的错误(针对math子集没有得到合适的参数):绑定不匹配:类型S不是有界参数 > 扩展的有效替代,类似于qiffixer>

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>.

问题是math子集期望 ,但是你给它一个S扩展解 ——这些类型之间没有任何关系,因为解决方案不会继承或实现类似的 扩展可比的

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.

不幸的是,这仍然不能工作,因为math子集实现可迭代,解决方案也是如此。

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?

一个简单的解决方案应该是不扩展可迭代的,但在我看来,您确实在尝试使用比您需要的更复杂的方法。也许是一个“has-a”而不是“is-a”的设计在这里可能更有益?

#1


6  

In order to be used as the type argument in MathSubset, SolutionsSubsets S must extend Comparable<S>. As a compilable example:

为了在math子集中用作类型参数,SolutionsSubsets S必须扩展可比的。作为一个compilable的例子:

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


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

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


1  

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>

首先,这里有一个完整的错误(针对math子集没有得到合适的参数):绑定不匹配:类型S不是有界参数 > 扩展的有效替代,类似于qiffixer>

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>.

问题是math子集期望 ,但是你给它一个S扩展解 ——这些类型之间没有任何关系,因为解决方案不会继承或实现类似的 扩展可比的

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.

不幸的是,这仍然不能工作,因为math子集实现可迭代,解决方案也是如此。

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?

一个简单的解决方案应该是不扩展可迭代的,但在我看来,您确实在尝试使用比您需要的更复杂的方法。也许是一个“has-a”而不是“is-a”的设计在这里可能更有益?