复制数组
1.颜老师,如何复制数组呢?除了for遍历以外,有高效的方法吗?
答:如果数组的元素数量不多,任何一种复制数组的方式都没什么差别。如果数组中包含了大量元素,就确实得考虑效率问题了。有哪些方式呢?
(1)使用你提到的for,以及while等循环遍历赋值(中规中矩,性能一般)
(2)思考,如何才能高效?之所以说for等循环性能一般,是因为java在执行时必然会借助于jvm虚拟机,而jvm是介于操作系统和java代码之间的一个媒介。这个jvm媒介的最大好处就是使得java可以跨语言,但缺点也很明显:多了一道媒介,性能就会减弱一些。因此,要想提高效率,就要想办法绕过这个jvm媒介,怎么绕呢?native,native修改的方法就是操作系统底层自带的方法(java只负责调用,真正由操作系统来执行),因此就得找那些native修饰的方法来提高数组复制的效率。常见有以下三种:
①使用克隆(就是平时说的“深克隆”、“浅克隆”中的那个克隆)
protected native Object clone() throws CloneNotSupportedException;
但clone()方法的返回值是Object,还需要强制转换成具体的数据类型,而强制转换也会耗费那么一些性能。但整体而言,如果数组元素非常多的话,使用clone()性能已经非常不错了
②使用System.arraycopy()
public static native void arraycopy(Object src, int srcPos,Object dest, int destPos,int length);
System.arraycopy()是native修饰的,并且从名字就能知道它可以用于复制数组,完美。
③使用Arrays.copyOf()
public static <T,U> T[] copyOf(U[] original, int newLength, Class<? extends T[]> newType) {
@SuppressWarnings("unchecked")
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;
}
Arrays.copyOf()也是native修饰的,但从源码可知它实际又调用了System.arraycopy(),并且也存在着强制类型转换,因此性能稍微比System.arraycopy()低了点。
综上,如果数组中存在着大量元素,System.arraycopy()就是推荐的选择了。
主函数
2.老师,这个main()方法没有static修饰,为什么在编译时也不报错?
public void main(String[] args) {
System.out.println("hello world");
}
答:有static的main()是程序的入口。没有static修饰的main()就是一个普通的方法而已。编译一个普通的方法为什么要报错?
super
3.super不是调用父类的意思吗?为什么这个题的运行结果是practice01.Demo01
package practice01;
...
public class Demo01 extends Date { private void test(){ System.out.println(super.getClass().getName()); } public static void main(String[]args){ new Demo01().test(); } }
答:本题有两点需要注意:
(1)本题中,如果把super.getClass().getName()改成getClass().getName(),运行结果是完全一样的,都是practice01.Demo01。明白了吗?
如果子类重写了父类的某个方法/属性,则可以使用super调用父类的方法/属性。但本题中Demo01并没有重写任何Date的方法,因此写不写super是无所谓的。
(2)【本题考点】getClass()是谁定义的?既不是Demo01,也不是Date类。也就是说,本题的extends Date是个障眼法,你把extends Date删除后,运行结果也是一样的,结果仍然会是practice01.Demo01。本题实际就是在考getClass()方法,getClass()是Object类中定义的方法,该类的作用就是:返回运行期间,当前类的名字。显然,本题在运行期间使用的类是Demo01,因此结果就是practice01.Demo01,就这么简单。
- 完 -
推荐阅读