V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Adia
V2EX  ›  Java

请问这里为什么不支持类型转换?

  •  
  •   Adia · 2017-02-12 19:23:53 +08:00 · 2562 次点击
    这是一个创建于 2826 天前的主题,其中的信息可能已经有所发展或是发生改变。
    	public static void main(String[]args){
    		List<String> x = new ArrayList<String>();
    		x.add("sherlock");
    		//Exception in thread "main" java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to [Ljava.lang.String;
    		String[] y = (String[]) x.toArray();
    		//为什么这样就 ok 了
    		String[] y1 = x.toArray(new String[0]);
    	}
    

    有点难以理解。麻烦各位大大不吝赐教,先谢过为敬。

    9 条回复    2017-02-13 11:20:56 +08:00
    hexzhou
        1
    hexzhou  
       2017-02-12 19:59:32 +08:00
    `bArr = new B[]; A[] aArr = (A[]) bArr;`

    "works" at runtime if and only if B is a subtype of A (or A itself). Whether B actually only contains As is irrelevant and the compile-time type of bArr is not used either (what matters is the runtime type):
    MartinDai
        2
    MartinDai  
       2017-02-12 20:09:12 +08:00
    在 SF 问的也是楼主吧
    SoloCompany
        3
    SoloCompany  
       2017-02-12 20:21:51 +08:00
    你这个问题应该精简为

    Object[] x = new Object[1];
    String[] y = (String[]) x;

    为什么编译不通过(或者多加一些隐式转换后,是运行时 ClassCastException)

    但这不是明显的吗,这两个类型就是不相容的啊

    假如 Java 规范允许这种强制类型转换(假设每个 item 都能转换)

    那么你考虑以下以下语句执行是什么后果

    x[0] = new Object();

    ClassCastException 显然不合适,然后为了这个异常再加一种运行时异常?
    ReisenZ
        4
    ReisenZ  
       2017-02-12 20:24:06 +08:00
    看源码....里面有这么一句...
    T[] copy = ((Object)newType == (Object)Object[].class)
    ? (T[]) new Object[newLength]
    : (T[]) Array.newInstance(newType.getComponentType(), newLength);
    无参方法创建的是一个 Object 数组,强转当然会失败
    Adia
        5
    Adia  
    OP
       2017-02-12 20:26:02 +08:00
    @MartinDai 不,因为我也不懂。那时还没人答出来,好奇心驱使了我- -
    akking
        6
    akking  
       2017-02-12 22:32:52 +08:00 via iPhone   ❤️ 1
    Java Geneirc 的坑, 以及 Java 中 array 是 covariant 两个原因造成的。
    sorra
        7
    sorra  
       2017-02-12 22:53:51 +08:00   ❤️ 1
    array 是特殊的,不支持泛型, Object[]和 String[]不兼容
    要调用 toArray(new String[]{})得到 String[]
    leafin
        8
    leafin  
       2017-02-13 11:09:00 +08:00
    List.toArray()返回的是 Object[], List.toArray(String[])返回的是 String[], Object[]不能强转为 String[],很好懂
    leafin
        9
    leafin  
       2017-02-13 11:20:56 +08:00   ❤️ 1
    如果你的疑问是,明明声明的是 List<String>,为什么 toArray()里面不能得到<String>而将结果输出为 String[],

    因为 List<String>跟 List<Object>是同一个类型,你没法检测一个 List 被限定为只能存储什么元素,这个是运行时才知道的,但是这段代码你现在就得写完。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   942 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 20:57 · PVG 04:57 · LAX 12:57 · JFK 15:57
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.