我在阅读泛型时遇到了PECS(制片extends人和消费者的super简称).
能否给我一个人解释如何使用佩奇之间解决困惑extends和super?
来自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,我无法遵循.
我有一个List<SubClass>我想要作为一个List<BaseClass>.看起来它应该不是一个问题,因为将a转换SubClass为a BaseClass是一个快照,但我的编译器抱怨演员表是不可能的.
那么,获取对相同对象的引用的最佳方法是List<BaseClass>什么?
现在我只是制作一个新列表并复制旧列表:
List<BaseClass> convertedList = new ArrayList<BaseClass>(listOfSubClass)
Run Code Online (Sandbox Code Playgroud)
但据我了解,必须创建一个全新的列表.如果可能的话,我想参考原始列表!
今天,我在Java中阅读了一些关于Covariance,Contravariance(和Invariance)的文章.我阅读了英文和德文维基百科的文章,以及IBM的一些其他博客文章和文章.
但我对这些究竟是什么有点困惑?有人说,它是关于类型和子类型之间的关系,也有人说,它是关于类型转换和一些说,它是用来决定一个方法是否重载或超载.
所以我正在用简单的英语寻找一个简单的解释,它向初学者展示了Covariance和Contravariance(和Invariance).加上一点简单的例子.
刚遇到这个问题:
List<DataNode> a1 = new ArrayList<DataNode>();
List<Tree> b1 = a1; // compile error: incompatible type
Run Code Online (Sandbox Code Playgroud)
DataNode类型是Tree的子类型.
public class DataNode implements Tree
Run Code Online (Sandbox Code Playgroud)
令我惊讶的是,这适用于数组:
DataNode[] a2 = new DataNode[0];
Tree[] b2 = a2; // this is okay
Run Code Online (Sandbox Code Playgroud)
这有点奇怪.谁能对此作出解释?
我一直在打击这个问题一段时间,并认为可能会有一些新鲜的眼睛看到这个问题; 谢谢你的时间.
import java.util.*;
class Tbin<T> extends ArrayList<T> {}
class TbinList<T> extends ArrayList<Tbin<T>> {}
class Base {}
class Derived extends Base {}
public class Test {
public static void main(String[] args) {
ArrayList<Tbin<? extends Base>> test = new ArrayList<>();
test.add(new Tbin<Derived>());
TbinList<? extends Base> test2 = new TbinList<>();
test2.add(new Tbin<Derived>());
}
}
Run Code Online (Sandbox Code Playgroud)
使用Java 8.在我看来,直接创建容器test就等同于容器test2,但编译器说:
Test.java:15: error: no suitable method found for add(Tbin<Derived>)
test2.add(new Tbin<Derived>());
^
Run Code Online (Sandbox Code Playgroud)
我怎么写Tbin,TbinList所以最后一行是可以接受的?
请注意,我实际上将添加类型Tbins,这就是我Tbin<Derived>在最后一行中指定的原因.
我无法理解源代码Arrays.copyOf.
public static <T,U> T[] copyOf(U[] original, int newLength, Class<? extends T[]> newType) {
T[] copy = ((Object)newType == (Object)Object[].class)
? (T[]) new Object[newLength]
: (T[]) Array.newInstance(newType.getComponentType(), newLength);
System.arraycopy(original, 0, copy, 0,
Math.min(original.length, newLength));
return copy;
}
Run Code Online (Sandbox Code Playgroud)
这行检查是什么?
(Object)newType == (Object)Object[].class
Run Code Online (Sandbox Code Playgroud)(T[]) new Object[newLength]和之间有什么区别(T[]) Array.newInstance(newType.getComponentType(), newLength)?为什么Array.newInstance两种情况都不够好?
以下行编译,但在运行时崩溃(如预期的那样).我什么时候应该使用这种方法?
Integer[] nums = Arrays.copyOf(new String[]{"a", "b"}, 2, Integer[].class)
Run Code Online (Sandbox Code Playgroud)Object[] o = "a;b;c".split(";");
o[0] = 42;
Run Code Online (Sandbox Code Playgroud)
投
java.lang.ArrayStoreException: java.lang.Integer
Run Code Online (Sandbox Code Playgroud)
而
String[] s = "a;b;c".split(";");
Object[] o = new Object[s.length];
for (int i = 0; i < s.length; i++) {
o[i] = s[i];
}
o[0] = 42;
Run Code Online (Sandbox Code Playgroud)
没有.
有没有其他方法来处理该异常而不创建临时String[]数组?
java ×10
generics ×7
arrays ×3
casting ×2
covariance ×2
inheritance ×2
collections ×1
pecs ×1
super ×1