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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4423026/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-14 17:18:28  来源:igfitidea点击:

About error using Java generics: "type parameter S is not within its bound"

javagenericssyntax-error

提问by user539694

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.

我正在使用泛型编写一些类,但我找不到类 SolutionsSubset 的解决方案,因此我收到错误“类型参数 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?

我需要 Subset 扩展 Comparable。在 SolutionsSubset 中,类 MathSubset 存储解决方案对象。我必须如何更改这些定义才能使其工作?

Thanks you in advance

提前谢谢你

回答by EboMike

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>

首先,这是完整的错误(特定于 MathSubset 没有获得正确的参数): 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>.

问题是 MathSubset 期望 a <T extends Comparable<T>,但您给了它S extends Solution<?>- 这些类型彼此无关,因为解决方案不继承或实现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.

不幸的是,这仍然不起作用,因为 MathSubset 实现了 Iterable,但 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?

一个简单的解决方法是解决方案不扩展 Iterable,但对我来说,这听起来确实像是您正在尝试使用比您需要的更复杂的方法。可能是“has-a”而不是“is-a”设计在这里可能更有益?

回答by Bert F

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.

不是教程,而是很多有用的信息。它是您阅读可以理解的部分的参考资料之一,但随着您获得更多掌握并且更多内容开始变得有意义,将来会一遍又一遍地返回。

回答by Tom Hawtin - tackline

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

为了用作 中的类型参数MathSubsetSolutionsSubsetsS必须extend Comparable<S>。作为一个可编译的例子:

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

一些评论:这是一个非常抽象的例子,所以不容易思考。布置代码以便您不需要滚动是好的。这里有大量的继承,可能是 compose 而不是,比如说,extending TreeSet。很难区分标识符SolutionsSolution