Java 的泛型是如何工作的?
How does Java's generics work?
谁能帮我理解 Java 的泛型是如何工作的?我理解它的概念。但是对于这个具体的代码示例,我并不清楚编译器的错误信息。
示例代码:
测试class
// Test code
public class A < ListType extends Comparable < ListType >> {
// To make the instance variable y
public int y;
// To make the instance variable s
public String s;
//Constructor Method
public A(int requiredY, String requiredS) {
y = requiredY;
s = requiredS;
}
more code here...
}
然后在不同的class我写了
List <A> a = new ArrayList<A>();
more code here...
Collections.sort(a)
我收到的错误消息是
test.java:20: error: no suitable method found for sort(List<A>)
Collections.sort(a);
^
method Collections.<T#1>sort(List<T#1>) is not applicable
(inference variable T#1 has incompatible bounds
equality constraints: A
upper bounds: Comparable<? super T#1>)
method Collections.<T#2>sort(List<T#2>,Comparator<? super T#2>) is not applicable
(cannot infer type-variable(s) T#2
(actual and formal argument lists differ in length))
其中 T#1、T#2 是类型变量:
T#1 extends Comparable<? super T#1> declared in method <T#1>sort(List<T#1>)
T#2 extends Object declared in method <T#2>sort(List<T#2>,Comparator<? super T#2>)
我不明白为什么编译器会抱怨类型参数。集合不应该起作用吗?因为类型参数都是可以相互比较的。
您应该检查如何使用 Comparator Interface。
要比较自定义 类 你需要实现你自定义的比较器,然后你才能使用集合接口提供的排序方法。
大家可以参考一下here
您的问题是 A
不是 Comparable
。注意你的类型签名:
public class A<ListType extends Comparable<ListType>>
这表示 A
(这是具体 class 的糟糕名称,单字母类型通常为泛型类型保留)具有泛型类型 ListType
,并且ListType
是 Comparable
与其他 ListType
个对象。
Collections.sort()
的签名期望传递 List<T>
,其中 T
是实现 Comparable
的通用类型。因为 A
没有实现 Comparable
你不能把它传递给 Collections.sort()
.
您可能并不打算按照您的方式定义 A
。您可能打算做这样的事情:
public class A<ListType> implements Comparable<A<ListType>>
这表示 A
有一个名为 ListType
的通用类型,并且 A
实现了 Comparable
,因此可以与其他实例进行比较(和排序) A
.
因为 A
现在实现了 Comparable
接口,你需要定义一个
compareTo()
A
.
方法
要么您为了隐藏 class 名称而写错了问题,或者您错误地表示了泛型。
如果你想做的是制作一个可以排序的 class,你可以在 class A 正如其他人所建议的那样。
public class A < ListType extends Comparable < ListType >> {
...
}
上面的代码需要 class A
接受 extends/implements Comparable
的 class,并使用 ListType
作为其类型擦除。
由于您没有说明如何使用 ListType
来绑定类型,因此我认为这不是您想要的。
通常泛型用于绑定您可以在 class 中使用的参数类型,以便在编译时提供类型安全的操作。
import java.lang.Override;
public class A <ListType extends Comparable<ListType>>{
ListType lt;
A(ListType b){
this.lt = b;
}
static class B implements Comparable<B>{
B(){};
@Override
public int compareTo(B b){
return 0;
}
}
static class C implements Comparable<B>{
C(){};
@Override
public int compareTo(B c){
return 0;
}
}
public static void main(String[] args){
A<B> a = new A<B>(new B()); //OK
A<C> _a = new A<C>(new C()); //ERROR: is not within bound
System.out.println("");
}
}
因为 class C
本身没有实现 Comparable
class,所以不能将 class C
变量传递给 class A
构造函数。
如果你想创建一个类型来接受任何扩展 Comparable
的 classes,你可以使用通配符 ?
.
public class A <ListType extends Comparable<?>>
或使用单个大写字母作为类型以获得更好的代码样式
public class A <T extends Comparable<?>>
谁能帮我理解 Java 的泛型是如何工作的?我理解它的概念。但是对于这个具体的代码示例,我并不清楚编译器的错误信息。
示例代码: 测试class
// Test code
public class A < ListType extends Comparable < ListType >> {
// To make the instance variable y
public int y;
// To make the instance variable s
public String s;
//Constructor Method
public A(int requiredY, String requiredS) {
y = requiredY;
s = requiredS;
}
more code here...
}
然后在不同的class我写了
List <A> a = new ArrayList<A>();
more code here...
Collections.sort(a)
我收到的错误消息是
test.java:20: error: no suitable method found for sort(List<A>)
Collections.sort(a);
^
method Collections.<T#1>sort(List<T#1>) is not applicable
(inference variable T#1 has incompatible bounds
equality constraints: A
upper bounds: Comparable<? super T#1>)
method Collections.<T#2>sort(List<T#2>,Comparator<? super T#2>) is not applicable
(cannot infer type-variable(s) T#2
(actual and formal argument lists differ in length))
其中 T#1、T#2 是类型变量:
T#1 extends Comparable<? super T#1> declared in method <T#1>sort(List<T#1>)
T#2 extends Object declared in method <T#2>sort(List<T#2>,Comparator<? super T#2>)
我不明白为什么编译器会抱怨类型参数。集合不应该起作用吗?因为类型参数都是可以相互比较的。
您应该检查如何使用 Comparator Interface。
要比较自定义 类 你需要实现你自定义的比较器,然后你才能使用集合接口提供的排序方法。
大家可以参考一下here
您的问题是 A
不是 Comparable
。注意你的类型签名:
public class A<ListType extends Comparable<ListType>>
这表示 A
(这是具体 class 的糟糕名称,单字母类型通常为泛型类型保留)具有泛型类型 ListType
,并且ListType
是 Comparable
与其他 ListType
个对象。
Collections.sort()
的签名期望传递 List<T>
,其中 T
是实现 Comparable
的通用类型。因为 A
没有实现 Comparable
你不能把它传递给 Collections.sort()
.
您可能并不打算按照您的方式定义 A
。您可能打算做这样的事情:
public class A<ListType> implements Comparable<A<ListType>>
这表示 A
有一个名为 ListType
的通用类型,并且 A
实现了 Comparable
,因此可以与其他实例进行比较(和排序) A
.
因为 A
现在实现了 Comparable
接口,你需要定义一个
compareTo()
A
.
要么您为了隐藏 class 名称而写错了问题,或者您错误地表示了泛型。
如果你想做的是制作一个可以排序的 class,你可以在 class A 正如其他人所建议的那样。
public class A < ListType extends Comparable < ListType >> {
...
}
上面的代码需要 class A
接受 extends/implements Comparable
的 class,并使用 ListType
作为其类型擦除。
由于您没有说明如何使用 ListType
来绑定类型,因此我认为这不是您想要的。
通常泛型用于绑定您可以在 class 中使用的参数类型,以便在编译时提供类型安全的操作。
import java.lang.Override;
public class A <ListType extends Comparable<ListType>>{
ListType lt;
A(ListType b){
this.lt = b;
}
static class B implements Comparable<B>{
B(){};
@Override
public int compareTo(B b){
return 0;
}
}
static class C implements Comparable<B>{
C(){};
@Override
public int compareTo(B c){
return 0;
}
}
public static void main(String[] args){
A<B> a = new A<B>(new B()); //OK
A<C> _a = new A<C>(new C()); //ERROR: is not within bound
System.out.println("");
}
}
因为 class C
本身没有实现 Comparable
class,所以不能将 class C
变量传递给 class A
构造函数。
如果你想创建一个类型来接受任何扩展 Comparable
的 classes,你可以使用通配符 ?
.
public class A <ListType extends Comparable<?>>
或使用单个大写字母作为类型以获得更好的代码样式
public class A <T extends Comparable<?>>