以下代码给出了该行的错误 l.add
List<? extends Number> l = new ArrayList<Integer>();
l.add(1);
Run Code Online (Sandbox Code Playgroud)
并强迫我把它写成 l.add(1, null);
为什么会这样?
考虑这个java类:
import java.util.Collection;
import java.util.Iterator;
import java.util.LinkedList;
public class NumberSet {
private Collection<? extends Number> numbers;
public NumberSet(Collection<? extends Number> numbers) {
this.numbers = numbers;
}
public NumberSet(NumberSet other) {
//copy other.numbers to this.numbers
numbers = new LinkedList<>();
for (Iterator<? extends Number> it = other.numbers.iterator(); it.hasNext();) {
numbers.add(it.next()); // Here's Syntax Error near `it.next()`
}
}
}
Run Code Online (Sandbox Code Playgroud)
for循环内部存在此语法错误:
actual argument Number cannot be converted to CAP#1 by method invocation conversion
where E is a type-variable:
E extends Object declared …Run Code Online (Sandbox Code Playgroud) 有时候,我很多时候会在文档中看到这种情况.它让我想知道要输入什么.有人可以用明确的愚蠢的文字向我解释这个含义:D.怎么样:
ArrayList(Collection<? extends E> c)
Run Code Online (Sandbox Code Playgroud)
最终用作这个:
new ArrayList<>(Arrays.asList("a","b","c"));
Run Code Online (Sandbox Code Playgroud)
所以我不需要通过谷歌搜索来问这个"问题",而是能够自己解决这个问题.
public class Stack {
private LinkedList<? extends Number> stack;
public <T extends Number> void push(T t){
stack.add(t);
}
public <T extends Number>T pop(){
return stack.removeLast();
}
}
Run Code Online (Sandbox Code Playgroud)
添加和删除最后一个方法都会给出编译时错误。请帮助我理解我在这里做错了什么?
推送时出错 -
LinkedList 类型中的方法 add(capture#1-of ? extends Number) 不适用于参数 (T)
弹出错误 -
类型不匹配:无法从 capture#2-of 转换?将 Number 扩展到 T
鉴于:
public class Testcase {
public static <E> List<List<E>> transform(List<List<E>> list) {
return list;
}
public static <E> List<List<? extends E>> transform2(List<List<? extends E>> list) {
return list;
}
public static void main(String[] args) {
List<List<Integer>> known = new ArrayList<>();
List<List<? extends Number>> unknown = new ArrayList<>();
transform(known); // works
transform(unknown); // fails
transform2(known); // fails
transform2(unknown); // works
}
}
Run Code Online (Sandbox Code Playgroud)
编译器接受transform(known)但抱怨:
cannot infer type-variable(s) E
(argument mismatch; List<List<? extends Number>> cannot be converted to List<List<E>>)
where E …Run Code Online (Sandbox Code Playgroud) 这可能是一个非常愚蠢的问题,但即使在长时间挠头之后我也无法理解这种差异.
我正在浏览scala泛型页面:https://docs.scala-lang.org/tour/generic-classes.html
据说这里
注意:泛型类型的子类型是不变的.这意味着如果我们有一堆Stack [Char]类型的字符,那么它就不能用作Stack [Int]类型的整数堆栈.这将是不合理的,因为它将使我们能够在字符堆栈中输入真正的整数.总之,Stack [A]只是Stack [B]的子类型,当且仅当B = A时.
我完全理解这一点,我无法Char在Int需要的地方使用.但是,我的Stack班级只接受A类型(即invariant).如果我把Apple,Banana或Fruit放入其中,它们都会被接受.
class Fruit
class Apple extends Fruit
class Banana extends Fruit
val stack2 = new Stack[Fruit]
stack2.push(new Fruit)
stack2.push(new Banana)
stack2.push(new Apple)
Run Code Online (Sandbox Code Playgroud)
但是,在下一页(https://docs.scala-lang.org/tour/variances.html)上,它说类型参数应该是协变的+A,那么即使是添加子类型,Fruit示例如何工作呢?invariant.
希望我对我的问题很清楚.如果有更多信息,请告诉我.需要添加.
为什么map将其输入作为 aFunction类型<? super P_OUT, ? extends R>而不是<P_OUT, ? extends R>?
例如,当我这样做时,
List<Integer> list = new ArrayList<>();
list.stream().map(xyz -> {}); // Here xyz is always of type Integer for this instance.
// Then why does it take input as "? super Integer"?
Run Code Online (Sandbox Code Playgroud)
是不是因为没有限制方法引用?这是唯一的用例吗?
我想知道用什么工具可以查看类型擦除后的代码。例如,我想看看下面的代码在类型擦除后是什么样子。我知道通用类型信息在最终编译之前被剥离,用对象或边界类型替换类型引用,创建桥接方法等。我想在擦除过程发生后查看源代码。
public static void main(String[] args) {
Predicate<Object> objPredicate = (Object c) -> c.toString().length() > 2 ;
Predicate<? super Integer> predicate = objPredicate;
Number n = Integer.valueOf(22);
System.out.println(predicate.test(n)); //this line does not compile
}
Run Code Online (Sandbox Code Playgroud)
[如果需要编译代码才能看到擦除检查工具在示例中工作,则可以省略非编译行或n可以将其转换为Integer]
我有2个不同类型的不同地图,这两个地图都是BaseClass.
我希望能够使用相同的逻辑将两个案例中的项目"保存"到地图中,使用Generics.
假设getId是一种方法BaseClass.
我需要强迫
item是的子类BaseClassmap值与该类型相同item我怎样才能做到这一点?这是一次失败的尝试,描述了我需要做的事情:
private <T><?extends BaseClass> void save(T item, Map<Long, T> map)
{
if (item.getId() == null)
{
long max = -1;
for (Long key : map.keySet())
max = Math.max(max, key);
item.setId(max + 1);
}
map.put(item.getId(), item);
}
Run Code Online (Sandbox Code Playgroud) 有几个人告诉我,Java 允许协变数组子类型化,换句话说,如果 A 是 B 的子类型,则 A[] 是 B[] 的子类型,但这是一个糟糕的特性,因为它会导致运行时错误。有人能给我一个具体的例子来说明它如何导致运行时错误以及 Java 是否/如何解决这个问题?
java ×9
generics ×6
arrays ×1
collections ×1
covariance ×1
covariant ×1
java-8 ×1
java-stream ×1
javadoc ×1
scala ×1
wildcard ×1