自动装箱和拆箱在Java和C#中的表现不同

时间:2009-10-20 20:38:02

标签: c# java autoboxing

我手动将代码从Java(1.6)转换为C#,并发现原语(int和double)的行为有些困难。在C#中,似乎几乎所有转换都会自动发生

        List<double> list1 = new List<double>();  // legal, C#
        double d0 = 3.0;
        list1.Add(d0);                            // legal, C#
        Double dd = 2.3f;                         // legal, C#
        list1.Add(dd);                            // legal, C#
        List<Double> list2 = new List<Double>();  // legal, C#
        double d1 = 3.0;
        list2.Add(d1);                            // legal, C#
        list2.Add(2.0);                           // legal, C#
        double d2 = list2.get(0);                 // legal, C#

但在Java中只允许一些

        List<double> list1 = new ArrayList<double>();  // illegal, Java
        List<Double> list2 = new ArrayList<Double>();  // legal, Java
        double d1 = 3.0;
        list2.add(d1);                                 // legal, Java
        list2.add(2.0);                                // legal, Java
        double d2 = list2.get(0);                      // legal, Java

我很感激系统地分析差异和任何基本原理。

2 个答案:

答案 0 :(得分:18)

在C#中,doubleDouble 完全相同(只要您没有创建自己的类型Double,这将是是愚蠢的。)

double 已定义作为global::System.Double的别名。因此,这里没有拳击。

在java中,Double是一个盒装double,其中类型擦除是泛型实现的关键部分。

答案 1 :(得分:8)

在您的C#示例中,没有发生装箱或拆箱(和自动装箱)。 double只是struct Double的别名。

在Java中,拳击是必要的。由于type erasure,您无法创建List<double>,只能创建List<Double>。在编译时,List<?>变为List<Object>并且需要进行装箱/取消装箱,以便您可以将本机类型变量添加到List<Object>或将本机变量分配给列表的元素