不明白Arrays.copyOf的源代码
我无法理解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; } 
- 
这一行是什么检查? (Object)newType == (Object)Object[].class
- 
(T[]) new Object[newLength]和(T[]) Array.newInstance(newType.getComponentType(), newLength)之间有什么区别。 为什么Array.newInstance对两种情况都不够好?
- 
下面这行代码编译,但在运行时崩溃(如预期的那样)。 我应该什么时候使用这种方法? Integer[] nums = Arrays.copyOf(new String[]{"a", "b"}, 2, Integer[].class)
这行检查是什么?
(Object)newType == (Object)Object[].class
这是检查简单的平等(可能是为了微观优化的目的,但稍后更多)。
 因为Class<Object[]> ( Object[].class )和Class<? extends T[]>  Class<? extends T[]>是无与伦比的types。 基本上,为了与==进行等式比较来进行编译,其中一方必须是另一方的子types或超types。 
即我们不能这样做:
 // doesn't compile // this expression can never evaluate to true (new Integer(0) == new Float(0f)) 
genericstypes的规则有点复杂,有些情况下比较不能编译,但是仍然可以评估为真。
  Class<Object[]>不是Class<? extends T[]>的超types的原因 尽pipeObject[]是所有对象数组types的超types,但Class<? extends T[]>是因为没有通配符, Javagenerics是不变的。 
另一种做比较的方法是:
 (newType == (Class<? extends Object[]>)Object[].class) 
(T[]) new Object[newLength]和(T[]) Array.newInstance(newType.getComponentType(), newLength)什么(T[]) Array.newInstance(newType.getComponentType(), newLength)?
-   new Object[...]创build一个静态已知types的常规方法。 请记住,代码刚刚检查过T[]是Object[]。
-   Array.newInstance(...)使用reflection来dynamic创build一个传入的Classtypes的数组。
为什么
Array.newInstance对两种情况都不够好?
使用reflection的操作通常比其非reflection对应物慢 。
反思教程说:
由于reflection涉及dynamicparsing的types,因此无法执行某些Java虚拟机优化。 因此,reflection操作的性能要比非reflection操作的性能要差,应该在对性能敏感的应用程序中频繁调用的代码段中避免。
Java SE充满了这样的微型优化。 SE的作者试图挤出所有可能的东西。
 但在这种情况下,我不会担心性能问题: newInstance和copyOf是HotSpot内在函数 。 这意味着理想情况下这些方法的调用将被机器特定的组件所取代。 有趣的是,我运行了一些testing,发现new Object[...]和Array.newInstance(...)之间的差异可以忽略不计。 问题中的代码可能是遗留的,尽pipe它可能在装备不足的JVM上仍然有用。 
也可以通过严格的安全性(如小应用程序)在某些情况下禁用reflection,但通常不能用于正常的桌面应用程序。
我应该什么时候使用这种方法?
一般来说,你可能永远不会使用这个过载。 这个重载只有在你想改变数组的types时才有用。
- 
拓宽: Object[] a = Arrays.copyOf( new String[] { "hello", "world" }, 3, Object[].class); a[2] = Character.valueOf('!'); System.out.println(Arrays.toString(a));
- 
缩小: String[] a = Arrays.copyOf( new Object[] { "hello", "world" }, 2, String[].class); System.out.println(String.join(" ", a));
 使用Arrays.copyOf(T[], int)更为典型。 
- 这一行是什么检查?
 (Object)newType == (Object)Object[].class 
 它检查variablesnewType是否保存对表示Object[]types的java.lang.Class实例的引用。 演员是不需要的。 
(T[]) new Object[newLength]和(T[]) Array.newInstance(newType.getComponentType(), newLength)之间有什么区别。 为什么Array.newInstance对两种情况都不够好?
 据我所知,在这两种情况下都可以使用Array.newInstance() ,但是非reflection的普通数组构造可能会快一点。 因此,我认为由于性能的原因, Object[]被称为特例,但我不知道这种情况是否被频繁执行,以使优化变得重要。 
- 下面这行代码编译,但在运行时崩溃(如预期的那样)。 我应该什么时候使用这种方法?
 Integer[] nums = Arrays.copyOf(new String[]{"a", "b"}, 2, Integer[].class) 
 当需要将一个数组复制到一个可能不同(但兼容)元素types的数组时,应该使用它,特别是当元素types不是静态的时候。 如果您知道您希望副本具有与原始副本相同的元素types,那么使用原始数组的clone()方法会更容易。 
- 
它检查newType是否是Object的数组: Object[] a1 = new Object[100]; -- array of Objects String[] a2 = new String[100]; -- array of Strings
为什么这样做? 因为新的Object [n]比Array.newInstance快
- 
Array.newInstance(Class<?> componentType, int... dimensions)创build由第一个参数定义的types数组,例如String.class– >String[]。 请注意,String[].class.getComponentType()返回String.class
- 
你不能像这样使用它,但它可以是这样的 Integer[] nums = Arrays.copyOf(new Object[]{1, 2}, 2, Integer[].class);
在这种情况下,它仅取决于实际types的元素,例如
  Arrays.copyOf(new Object[]{1L, 2}, 2, Integer[].class); 
 会失败,你不能在Integer[]写入Integer 
首先,在这一行中投
 ((Object)newType == (Object)Object[].class) 
是absobuletly需要的。 删除它们将导致编译错误:
 incomparable types: Class<CAP#1> and Class<Object[]> where CAP#1 is a fresh type-variable: CAP#1 extends T[] from capture of ? extends T[] 
现在回答你的问题这是什么行检查?
 它只是validation给定的数组是否是对象types,这是你的其他问题的答案的一部分为什么Array.newInstance不够好的两种情况? 
 在第一种情况下,我们已经知道该数组是Objecttypes的,所以调用newInstance方法来检索正确的types没有意义,这只会导致性能损失。 
至于你最后的例子,
 Integer[] nums = Arrays.copyOf(new String[]{"a", "b"}, 2, Integer[].class) 
 它确实编译,这是真的。 因为这个方法的参数都是valids。 它肯定会在运行时失败; 将“a”转换为Integertypes的预期输出是什么? 
 现在,什么时候使用copyOf ? 当你已经知道这两种types,并已知道他们在一起有效。 
它的主要用法是返回一个副本,但截断或用[null /默认值]填充到原始数组。
让我试着回答这个问题:
为了回答你的第一个问题,它检查newTypetypes是否与数组中的types相同。 两者都将types转换为对象types。 也就是说,它试图查看数组的父types是否是对象。 在上传和下载中看到这个问题 。 我的猜测是,这不是因为检查types安全性。 尽pipeJava中的所有对象都是作为超类派生的。
注意到这将是有帮助的
  T[] copy = ((Object)newType == (Object)Object[].class) ? (T[]) new Object[newLength] : (T[]) Array.newInstance(newType.getComponentType(), newLength); 
实际上是一条线。 即它实际上是一个if-else条件。
 result = (condition) ? (doThisIfTrue) : (elseDoThisIfFalse) 
简单的例子
所以基本上这条线将是相同的:
 T[] copy; Boolean condition = ((Object)newType == (Object)Object[].class) if(condition) copy = (T[]) new Object[newLength]; else copy = (T[]) Array.newInstance(newType.getComponentType(), newLength); 
在Array.newInstance中创build一个新实例的原因可能是性能的select,如果程序总是需要创build新的实例,那么比直接初始化一个通用对象数组和复制东西要花费更多。
Arrays.copyOf将创build一个新的数组(引用旧数组),但是具有更新的长度,并将未使用的位置用空对象填充。 这就是它在一个int数组上进行的操作,它用零填充未使用的索引。
Arrays.CopyOf用于提供对象的浅拷贝,即它指的是旧项目,但在一个新的数组中 。 这个问题有更多的信息。