Java泛型 - 允许混合类型? [英] Java generics - mixing types allowed?

查看:278
本文介绍了Java泛型 - 允许混合类型?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我之前正在运行一些测试,并且找不到解释为什么这段代码会执行它的功能:

  public class Test {
public static void main(String [] args){
List< Integer> list = new ArrayList(Arrays.asList(Double.valueOf(0.1234)));
System.out.println(list.get(0)); //打印0.1234
Object d = list.get(0);
System.out.println(d.getClass()); //打印类java.lang.Double
System.out.println(list.get(0).getClass()); // ClassCastException
}
}

这提出了几个问题: p>


  • 为什么List< Integer>首先接受Double(应该编译)?
  • 为什么第二个印刷工作而不是第三个印刷工作,虽然看起来他们正在做同样的事情?


编辑

我了解以下两条语句:

  List aList = new ArrayList(); //我可以在其中添加任何对象
List< Integer> aList = new ArrayList< Integer>(); //我只能添加一些在那里扩展Integer的东西

但我不明白为什么这个是被授权的,为什么它在运行时会在某种程度上起作用,尽管一些操作产生了一个ClassCastException异常 - 我期望在上面发布的代码的第一行发现一个ClassCastException异常:

 列表与LT;整数> aList = new ArrayList(); //我可以在那里有任何对象


解决方案



  ...新的ArrayList<整数>(... 

代替它会导致编译器异常。



为什么它有效:

  System.out.println(list.get(0)); //打印0.1234 
$ b

方法 Object.toString() Double中是一样的整数(并且因为 System.out.println()期望一个Object不会被转换为 Integer (编译器优化了抛出))

  Object d = list .get(0); 
System.out.println(d.getClass()); //打印类java.lang.Double

.getClass()同样如此,优化器再次放弃了演员表。

  System.out.println(list.get(0).getClass()); // ClassCastException 

这实际上是从列表中创建一个整数并且失败。它执行的演员,因为优化器认为它需要做到这一点,因为它并不明显,它不需要。



如果您要将最后一行更改为:

  System.out.println(((Object)list.get(0))。getClass()); 

它的工作原理:)


I was running some tests earlier and could not find an explanation as to why this code does what it does:

public class Test {
    public static void main(String[] args) {
        List<Integer> list = new ArrayList(Arrays.asList(Double.valueOf(0.1234)));
        System.out.println(list.get(0)); //prints 0.1234
        Object d = list.get(0);
        System.out.println(d.getClass()); // prints class java.lang.Double
        System.out.println(list.get(0).getClass()); // ClassCastException
    }
}

That raises a few questions:

  • why does the List<Integer> accept a Double in the first place (should it compile at all)?
  • why does the second print work and not the third, although it looks like they are doing the same thing?

EDIT
I understand the following 2 statements:

List aList = new ArrayList(); //I can add any objects in there
List<Integer> aList = new ArrayList<Integer>(); //I can only add something that extends Integer in there

But I don't understand why this one is authorised and why it actually works to some extent at runtime although some operations produce a ClassCastException - I would have expected a ClassCastException at the first line of the code posted above:

List<Integer> aList = new ArrayList(); //I can any objects in there

解决方案

If you write

... new ArrayList<Integer>(...

instead it will cause a compiler exception.

On why it works:

System.out.println(list.get(0)); //prints 0.1234

The method Object.toString() is the same in Double and Integer (And because System.out.println() expects an Object this is not cast into an Integer (the compiler optimized the cast away))

Object d = list.get(0);
System.out.println(d.getClass()); // prints class java.lang.Double

Same goes for .getClass(). Here the optimizer again dropped the cast.

System.out.println(list.get(0).getClass()); // ClassCastException

This actually creates an Integer from the list and that fails. It does the cast because the optimizer thought it need to do it, because its not obvious that it doesn't need to.

If you would change that last line to:

    System.out.println(((Object)list.get(0)).getClass());

it works :)

这篇关于Java泛型 - 允许混合类型?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆