这个方法声明有什么区别:
public static <E extends Number> List<E> process(List<E> nums){
Run Code Online (Sandbox Code Playgroud)
和
public static List<Number> process(List<Number> nums){
Run Code Online (Sandbox Code Playgroud)
你会在哪里使用前者?
我理解集合的get和put原则:如果一个方法接受一个集合,它将写入一个类型T,参数必须是Collection<? super T>,而如果它将读取一个类型T,参数必须是Collection<? extends T>.
但有人可以解释Collections.max()签名:
public static <T> T max(Collection<? extends T> coll,
Comparator<? super T> comp)
Run Code Online (Sandbox Code Playgroud)
特别是为什么它Comparator<? super T>而不是Comparator<? extends T>?
为什么必须使用泛型类型Map<?, ? extends List<?>>而不是更简单Map<?, List<?>>的test()方法?
public static void main(String[] args) {
Map<Integer, List<String>> mappy =
new HashMap<Integer, List<String>>();
test(mappy);
}
public static void test(Map<?, ? extends List<?>> m) {}
// Doesn't compile
// public static void test(Map<?, List<?>> m) {}
Run Code Online (Sandbox Code Playgroud)
注意到以下工作,并且三种方法无论如何都具有相同的擦除类型.
public static <E> void test(Map<?, List<E>> m) {}
Run Code Online (Sandbox Code Playgroud) 假设我有一个包含泛型类型的两个实例变量的类,我该如何强制这些类型相同?
我没有在其他地方找到任何类似的问题(更不用说答案了),这可能是因为我使用了错误的术语.有这个问题,但我不确定如何将它应用到我的情况.
简而言之,如何才能使最后一行代码无法编译?
class Foo<T> {
private T value;
}
class Bar {
private Foo var1;
private Foo var2;
public Bar(Foo var1, Foo var2) {
this.var1 = var1;
this.var2 = var2;
}
public static void main(String[] args) {
Foo<String> var1 = new Foo<>();
Foo<Integer> var2 = new Foo<>();
Bar b = new Bar(var1, var2); // this should not work
}
}
Run Code Online (Sandbox Code Playgroud) 我想知道泛型如何在这种情况下工作,为什么
Set<? extends Foo<?>> set3 = set1;允许但Set<Foo<?>> set2 = set1;不是?
import java.util.HashSet;
import java.util.Set;
public class TestGenerics {
public static <T> void test() {
Set<T> set1 = new HashSet<>();
Set<?> set2 = set1; // OK
}
public static <T> void test2() {
Set<Foo<T>> set1 = new HashSet<>();
Set<Foo<?>> set2 = set1; // COMPILATION ERROR
Set<? extends Foo<?>> set3 = set1; // OK
}
}
class Foo<T> {}
Run Code Online (Sandbox Code Playgroud) 谁能解释我,编程语言理论中协方差和逆变的概念?
还有一个新手,试图理解Java Generics.我发现,我观察了所有主题,但我仍然有很多问题.能否请你解释一下以下事项:
<? extends SomeClass>意思?是"任何类型",并且extends SomeClass意味着任何类型都只能是它的子类SomeClass.好的,我写了两个小学课:abstract class Person {
private String name;
public Person(String name) {
this.name = name;
}
}
class Student extends Person {
public Student(String name) {
super(name);
}
}
Run Code Online (Sandbox Code Playgroud)
类Student将?在我们的示例中.? extends Person确切地说.然后我试图将新学生添加到ArrayList,正如我从上面所写的那样,它应用所有类,它们是Person的子类:
Student clarissa = new Student("Clarissa Starling");
List<? extends Person> list = new ArrayList<>();
list.add(clarissa); //Does not compile
Run Code Online (Sandbox Code Playgroud)
Eclipse说:
"类型List中的方法add(捕获#3-of?extends Person)不适用于参数(Student)"
Student当我们声明List <? extends Person>,参数化并Student完全扩展类时,类怎么可能不适用Person? …
我是Java新手.在本 文档中,他们将此作为使用通配符的用例:
static void printCollection(Collection c) {
Iterator i = c.iterator();
for (int k = 0; k < c.size(); k++) {
System.out.println(i.next());
}
}
Run Code Online (Sandbox Code Playgroud)
这是他们的解决方案:
static void printCollection(Collection<?> c) {
for (Object e : c) {
System.out.println(e);
}
}
Run Code Online (Sandbox Code Playgroud)
但是我可以在没有外卡的情况下做同样的事情:
static <T> void printCollection(Collection<T> c) {
Iterator i = c.iterator();
for (int k = 0; k < c.size(); k++) {
System.out.println(i.next());
}
}
Run Code Online (Sandbox Code Playgroud)
有人可以告诉我一个简单的用例,常规的泛型不起作用,但外卡会吗?
更新:此处的答案何时在Java Generics中使用通配符?不要告诉我们需要通配符.事实上,它是另一种方式.
我想知道以下是否有一个有效的用例:
class Base {}
class A implements Comparable<Base> {
//...
}
Run Code Online (Sandbox Code Playgroud)
这似乎是一个常见的模式(见集合了大量的实例)接受类型的集合T,其中T extends Comparable<? super T>.
但是在技术上似乎不可能compareTo()在与基类进行比较时履行合同,因为没有办法确保另一个类不会通过相互矛盾的比较扩展基础.请考虑以下示例:
class Base {
final int foo;
Base(int foo) {
this.foo = foo;
}
}
class A extends Base implements Comparable<Base> {
A(int foo) {
super(foo);
}
public int compareTo(Base that) {
return Integer.compare(this.foo, that.foo); // sort by foo ascending
}
}
class B extends Base implements Comparable<Base> {
B(int foo) {
super(foo);
}
public int …Run Code Online (Sandbox Code Playgroud) 我知道已经发布了类似的问题,虽然我认为我的情况有所不同......
假设您有两种方法:
// Bounded type parameter
private static <T extends Number> void processList(List<T> someList) {
}
// Upper bound wildcard
private static void processList2(List<? extends Number> someList) {
// ...
}
Run Code Online (Sandbox Code Playgroud)
据我所知,这两种方法接受参数,是List类型Number或List的亚型的Number.
但毕竟这两种方法有什么区别?