来自Joshua Bloch的Effective Java,
协变只是意味着如果X是Y的子类型,那么X []也将是Y []的子类型.数组是协变的因为字符串是Object So的子类型
String[] is subtype of Object[]
不变量仅仅意味着X不是Y的子类型,
List<X> will not be subType of List<Y>.
Run Code Online (Sandbox Code Playgroud)我的问题是为什么决定在Java中使数组协变?还有其他SO帖子,例如为什么阵列不变,但列出协变?,但他们似乎专注于Scala,我无法遵循.
这是一个我想知道的问题,因为lambdas是用Java引入的,并且受到相关问题的启发,我想我可以在这里提出它,看看是否有任何想法.
(附注:C#有一个类似的问题,但是我没有找到一个用于Java的问题.关于"将lambda存储在变量中"的Java问题总是指变量类型被修复的情况 - 这正是我想要绕过的东西)
Lambda表达式通过目标类型推断接收它们所需的类型.这全都由编译器处理.例如,功能
static void useF(Function<Integer, Boolean> f) { ... }
static void useP(Predicate<Integer> p) { ... }
Run Code Online (Sandbox Code Playgroud)
可以使用相同的 lambda表达式调用它们:
useF(x -> true);
useP(x -> true);
Run Code Online (Sandbox Code Playgroud)
表达式将一度表现为实现Function<Integer,Boolean>接口的类,并且一次作为实现Predicate<Integer>接口的类.
但遗憾的是,没有办法将lambda表达式存储为适用于这两种函数的类型,例如
GenericLambdaTypelambda = x -> true;
这个"通用λ型"将具有以编码的方法的类型可以由给定的λ表达式来实现.所以在这种情况下,它会
(Ljava.lang.Integer)Ljava.lang.Booleanlambda = x -> true;
(基于标准类型签名,用于说明).(这不是完全不合理的:C++ lambda表达式基本上就是这样......)
那么有什么方法可以防止lambda表达式被解析为一种特定的类型?
特别是,是否有任何技巧或解决方法允许使用相同的对象调用上面描绘的useF和useP方法,如
useF(theObject);
useP(theObject);
Run Code Online (Sandbox Code Playgroud)
这是不太可能的,所以我假设答案显然是:"不",但是:有没有办法写一个通用的,魔术适应方法,如
useF(convertToRequiredTargetType(theObject)); …Run Code Online (Sandbox Code Playgroud)