在我看来它应该有效,但事实并非如此.为什么?源代码:
package javaapplication1;
import java.util.*;
class A
{
public static <K,V> Map<K,V> map()
{
return new HashMap<K,V>();
}
}
class Person {}
class Dog {}
public class JavaApplication1
{
static void f(Map<Person, List<? extends Dog>> peopleDogList) {}
public static void main(String[] args)
{
f(A.<Person, List<Dog>>map());
}
}
Run Code Online (Sandbox Code Playgroud)
非常简单的代码.编译器错误:类JavaApplication1中的方法f不能应用于给出类型; required:Map<Person, List<? extends Dog>
found:Map<Person, List<Dog>>
reason:实际参数Map<Person, List<Dog>>无法Map<Person, List<? extends Dog>通过方法调用转换转换为.
Map<Person, List<? extends Dog> 更一般,所以编译器应该能够转换?
这也是:Map<Person, List<? extends Dog>> peopleDogList = A.<Person, List<Dog>>map();不起作用. …
这是Collections复制方法(部分):
public static <T> void copy(List<? super T> dst, List<? extends T> src) {
for (int i = 0; i < src.size(); i++) {
dst.set(i, src.get(i));
}
}
Run Code Online (Sandbox Code Playgroud)
有4个样本电话:
List<Object> objs = Arrays.<Object>asList(2, 3.14, "four");
List<Integer> ints = Arrays.asList(5, 6);
1. Collections.copy(objs, ints);
2. Collections.<Object>copy(objs, ints);
3. Collections.<Number>copy(objs, ints);
4. Collections.<Integer>copy(objs, ints);
Run Code Online (Sandbox Code Playgroud)
以上呼叫如何运作?
我们还可以使用几种可能的签名声明该方法
1. public static <T> void copy(List<T> dst, List<T> src)
2. public static <T> void copy(List<T> dst, List<? extends T> src)
3. public static <T> void copy(List<? …Run Code Online (Sandbox Code Playgroud) 我正在使用来自第三方库(Reflection)的方法,该方法应该找到给定类型的子类型并且看起来像
public <T> Set<Class<? extends T>> getSubTypesOf(final Class<T> type) {
...
Run Code Online (Sandbox Code Playgroud)
当调用者代码看起来像
Class<?> type = ...
Set<Class<?>> subTypes = reflections.getSubTypesOf(type);
Run Code Online (Sandbox Code Playgroud)
我收到编译错误:" cannot convert from Set<Class<? extends capture#19-of ?>> to Set<Class<?>>".以下修复了这种情况:
Class<?> type = ...
Set<?> subTypes = reflections.getSubTypesOf(ht);
Run Code Online (Sandbox Code Playgroud)
所以看起来不正确的唯一可能的补救措施Set<Class<? extends ?>>是Set<?>,但不是Set<Class<?>>.为什么会这样?谢谢你对此有任何解释.
我正在读关于函数式编程的讨论,我有一个非常基本的问题:
如果我在Java中有两个函数
int add(int x, int y){
return x+y;
}
Run Code Online (Sandbox Code Playgroud)
我创建了另一种方法
int increment(int y){
return add(1, y);
}
Run Code Online (Sandbox Code Playgroud)
在上面的代码中,当我写increment函数时,我实际上是在做咖喱add吗?
我想知道使用的?在java泛型中.通过研究占位符T和通配符?,我想知道?,经历了几个网站/页面和书籍,但没有理解它.所以我创建了下面的课来研究差异.
import java.util.List;
public class Generics2 {
public <T> void method1(List<T> list){
System.out.println(list);
}
public <T extends Number> void method2(List<T> list){
System.out.println(list);
}
/*public <T super Integer> void method3(List<T> list){
}*///super does not work.
public void method4(List<?> list){
System.out.println(list);
}
public void method5(List<? extends Number> list){
System.out.println(list);
}
public void method6(List<? super Integer> list){
System.out.println(list);
}
public <T> void copy1(List<T> list1, List<T> list2){
//copy elements from list1 to list2
}//It does not span well with copy of one type of …Run Code Online (Sandbox Code Playgroud) 我在一些奇怪的代码中一直在做一些代码考古学,我遇到了类似的东西:
public abstract class Outer<T>
{
protected Outer(Inner<?> inner)
{
// ...
}
public static abstract class Inner<U extends Outer>
{
// ...
}
}
Run Code Online (Sandbox Code Playgroud)
让我印象深刻Inner的是,在Outer类型(<U extends Outer>位)的使用上没有无界的通配符类型.
使用Inner<U extends Outer<?>>vs. 的含义是Inner<U extends Outer>什么?
我可以使用两种类型的版本成功编译和运行测试,但是我很难理解幕后发生的事情.
这是我阅读的有关scala中的逆变和协方差的文章之一的代码片段.但是,我无法理解scala编译器抛出的错误消息"错误:协变类型A出现在值pet2的类型A中的逆变位置
class Pets[+A](val pet:A) {
def add(pet2: A): String = "done"
}
Run Code Online (Sandbox Code Playgroud)
我对这段代码片段的理解是,Pets是协变的并且接受A的子类型的对象.但是,函数add仅接受A类型的参数.Being covariant意味着Pets可以获取A类及其子类型的参数.那怎么会抛出错误呢.从哪里出现逆变问题.
对上述错误消息的任何解释都将非常有用.谢谢
types functional-programming scala covariance contravariance
<? extends T>形成只读集合
<? super T>形成只写集合
我以某种方式明白为什么使用只读集合,例如在多线程环境中使用它(还有其他情况吗?)
但为什么要使用只写集合呢?如果您无法在某些时候读取它并使用它的值,那还有什么意义呢?我知道你可以从中获取一个对象,但这违反了类型安全。
编辑:@Thomas 链接的问题(Java 中 <? super T> 和 <? extends T> 之间的差异)确实展示了如何创建只写集合,但没有回答“为什么”你首先需要一个集合。所以它不是重复的
任何人都可以解释我们?在Collection泛型中使用的原因.
例如:
List<? extends Number> numberlist;
List<? super Integer> numberlist;
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.
希望我对我的问题很清楚.如果有更多信息,请告诉我.需要添加.