转载原文地址:

http://blog.csdn.net/guopengzhang/article/details/5497875

一.             Incident

import java.util.ArrayList;

import java.util.List;

public class Test {

public static void main(String[] args) {

List<String> list = new ArrayList<String>();

list.add("1");

list.add("2");

String[] tt =(String[]) list.toArray(new String[0]);

}

}

这段代码是没问题的,但我们看到String[] tt =(String[]) list.toArray(new String[0]) 中的参数很奇怪,然而去掉这个参数new String[0]却在运行时报错。。。

二.             Root Cause Analysis

经研究发现toArray有两个方法:

public Object[] toArray() {

Object[] result = new Object[size];

System.arraycopy(elementData, 0, result, 0, size);

return result;

}

不带参数的toArray方法,是构造的一个Object数组,然后进行数据拷贝,此时进行转型就会产生ClassCastException,这也就是上述问题的root cause了。

public Object[] toArray(Object a[]) {

if (a.length < size)

a = (Object[])java.lang.reflect.Array.newInstance(a.getClass().getComponentType(), size);       System.arraycopy(elementData, 0, a, 0, size);

if (a.length > size)

a[size] = null;

return a;

}

而带参数的toArray方法,则是根据参数数组的类型,构造了一个对应类型的,长度跟ArrayList的size一致的空数组,虽然方法本身还是以 Object数组的形式返回结果,不过由于构造数组使用的ComponentType跟需要转型的ComponentType一致,就不会产生转型异常。

三.             Solutions

因此在使用toArray的时候可以参考以下三种方式

1. Long[] l = new Long[<total size>];

list.toArray(l);

2. Long[] l = (Long[]) list.toArray(new Long[0]);

3. Long[] a = new Long[<total size>];

Long[] l = (Long[]) list.toArray(a);

四.Further Consideration

该容器中的元素已经用泛型限制了,那里面的元素就应该被当作泛型类型的来看了,然而在目前的java中却不是的,当直接String[] tt =(String[]) list.toArray()时,运行报错。回想一下,应该是java中的强制类型转换只是针对单个对象的,想要偷懒,将整个数组转换成另外一种类型的数组是不行的,这和数组初始化时需要一个个来也是类似的。

以上From:    http://hi.baidu.com/%B4%CB%D6%D0%D3%D0%D5%E6%B5%C0/blog/item/8add93ec812dc9deb31cb1b0.html

  1. import java.util.*;
  2. class testList{
  3. public static void main(String[] args){
  4. //List<Character> list = new ArrayList<Character>();
  5. String[] str = "a b c".split(" ");
  6. System.out.println("字符串数组str,长度为:" + str.length);
  7. for(String c : str)
  8. System.out.println(c);
  9. List<Integer> list = new ArrayList<Integer>();
  10. list.add(1);
  11. list.add(2);
  12. list.add(3);
  13. list.add(4);
  14. Iterator<Integer> it = list.iterator();
  15. System.out.println("整型List list");
  16. while(it.hasNext())
  17. {
  18. System.out.println(it.next());
  19. }
  20. //数组转换成List
  21. List<String> li = new ArrayList<String>();
  22. li = Arrays.asList(str);
  23. Iterator<String> its = li.iterator();
  24. System.out.println("数组str -> list:");
  25. while(its.hasNext())
  26. {
  27. System.out.println(its.next());
  28. }
  29. //List转换成数组
  30. Integer[] b = (Integer[])list.toArray(new Integer[0]);
  31. System.out.println("List list -> 数组b");
  32. for(Integer i : b)
  33. System.out.println(i);
  34. //数组的fill方法
  35. int[] a = new int[5];
  36. Arrays.fill(a,0);
  37. System.out.println("数组a被0填充");
  38. for(int i : a)
  39. System.out.println(i);
  40. }
  41. }

Java中toArray的用法探究(java数组与list转换)的更多相关文章

  1. java中this的用法?

    2008-07-28 08:10cztx5479 | 分类:JAVA相关 | 浏览4533次 java中this的用法? import java.awt.*; import java.awt.even ...

  2. Java 中 synchronized的用法详解(四种用法)

    Java语言的关键字,当它用来修饰一个方法或者一个代码块的时候,能够保证在同一时刻最多只有一个线程执行该段代码.本文给大家介绍java中 synchronized的用法,对本文感兴趣的朋友一起看看吧 ...

  3. 转:十八、java中this的用法

    http://blog.csdn.net/liujun13579/article/details/7732443 我知道很多朋友都和我一样:在JAVA程序中似乎经常见到“this”,自己也偶尔用到它, ...

  4. java成神之——java中string的用法

    java中String的用法 String基本用法 String分割 String拼接 String截取 String换行符和format格式化 String反转字符串和去除空白字符 String获取 ...

  5. java中stringBuilder的用法

    java中stringBuilder的用法 String对象是不可改变的.每次使用 System.String类中的方法之一时,都要在内存中创建一个新的字符串对象,这就需要为该新对象分配新的空间.在需 ...

  6. 第一篇 网站基础知识 第4章 Java中Socket的用法

    第4章 Java中Socket的用法 4.1 普通Socket的用法 Java中的网络通信是通过Socket实现的,Socket分为ServetSocket和Socket两大类,ServetSocke ...

  7. Java中的Socket用法

    转发链接:https://www.cnblogs.com/zhanglei93/p/6217384.html (1)Java中的Socket用法 Java中的Socket分为普通的Socket和Nio ...

  8. Java中Synchronized的用法

    原文:http://blog.csdn.net/luoweifu/article/details/46613015 作者:luoweifu 转载请标名出处 <编程思想之多线程与多进程(1)——以 ...

  9. java中synchronized的用法详解

    记下来,很重要. Java语言的关键字,当它用来修饰一个方法或者一个代码块的时候,能够保证在同一时刻最多只有一个线程执行该段代码. 一.当两个并发线程访问同一个对象object中的这个synchron ...

随机推荐

  1. CustomProgressBar

    https://github.com/eltld/CustomProgressBar-master

  2. Linux文件空洞与稀疏文件 转

      1.Linux文件空洞与稀疏文件 2.文件系统数据存储 3.文件系统调试   文件空洞   在UNIX文件操作中,文件位移量可以大于文件的当前长度在这种情况下,对该文件的下一次写将延长该文件,并在 ...

  3. IOS中类和对象还有,nil/Nil/NULL的区别

    转自:http://blog.sina.com.cn/s/blog_5fb39f910101akm1.html 类与对象的概念 类是对同一类事物高度的抽象,类中定义了这一类对象所应具有的静态属性(属性 ...

  4. C语言第八节函数

    什么是函数 任何一个C语言程序都是由一个或者多个程序段(小程序)构成的,每个程序段都有自己的功能,我们一般称这些程序段为"函数".所以,你可以说C语言程序是由函数构成的. 比如你用 ...

  5. Mosaic HDU 4819 二维线段树入门题

    Mosaic Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 102400/102400 K (Java/Others)Total S ...

  6. 2.1.4 扫描器X-Scan查本机隐患

    X-Scan是由安全焦点开发的一个功能强大的扫描工具.它采用多线程方式对指定IP地址段(或单机)进行安全漏洞检测,支持插件功能. 1.用X-Scan查看本机IP地址 利用X-Scan扫描器来查看本机的 ...

  7. 5. Android框架和工具之 ZXing(二维码)

    Android进阶笔记06:Android 实现扫描二维码实现网页登录

  8. 转js contains 方法

    function Jcontains(root, el) { if (root.compareDocumentPosition) return root === el || !!(root.compa ...

  9. Android使用MVP时应该注意的问题

    生命周期:因为Presenter是View创建的,我们需要确保完全地理解View的生命周期,特别是因为它将最有可能去处理状态更新和异步数据.举个例子,每一个Presenter应该在View destr ...

  10. Session共享的简单总结

    1.同服务器.同一域名.不同应用(端口.虚拟目录等) 这种很简单,把sessionState保存到SQLServer,aspnet_regsql之后,修改存储过程TempGetAppID,把 SET ...