为什么Java自动装箱不能扩展到自动绑定类型方法的方法调用?

我想将一个原语转换为一个字符串,并且我尝试了:

myInt.toString();

这会失败并显示错误:

int cannot be dereferenced

现在,我知道原语不是引用类型(即不是对象),因此不能有方法。然而,Java 5引入了自动装箱和拆箱(一个C#......我从来不喜欢C#,但那不是重点)。所以对于自动装箱,我期望上述将myInt转换为Integer,然后在其上调用toString()。

此外,我相信C#允许这样的通话,除非我记错了。这只是Java的自动装箱/拆箱规格的一个不幸的缺点,还是有一个很好的理由呢?

0

8 答案

Java自动装箱/取消装箱并没有达到让你取消引用原语的程度,所以你的编译器会阻止它。你的编译器仍然知道 myInt 为一个原语。在 jcp.org 上有关于此问题的论文。

Autoboxing在赋值或参数传递过程中非常有用 - 允许将原语作为对象传递(反之亦然),或者将对象分配给对象(反之亦然)。

所以不幸的是,你必须这样做:(荣誉帕特里克,我转向你的方式)

Integer.toString(myInt);
0
额外

同上贾斯汀说,但你应该这样做,而不是:

Integer.toString(myInt);

它节省了一个或两个分配,并且更具可读性。

0
额外

如果Java定义了某些静态方法来操作原始类型并在编译器中构建了一些语法糖,那将会很有帮助

5.asInteger

将相当于

some.magic.stuff.Integer.asInteger(5);

我不认为这样的特性会导致与当前规则下编译的任何代码不兼容,并且在很多情况下这将有助于减少语法混乱。如果Java是自动复制被解引用的原语,人们可能会认为它将解引用语法映射为静态方法调用(这实际上是.NET中发生的),因此用这种形式编写的操作不会比等价的静态方法调用。添加一个鼓励人们编写错误代码的新语言功能(例如自动装箱解除引用的基元)似乎不是一个好主意,尽管允许使用解引用样式的方法。

0
额外

最接近你的例子的有效语法是

((Integer) myInt).toString();

当编译器结束时,这相当于

Integer.valueOf(myInt).toString();

但是,这并不像传统用法 String.valueOf(myInt)那样好,因为除了特殊情况外,它会创建一个新的Integer实例,然后立即抛出,导致更不必要的垃圾。 (缓存一小部分整数,并通过数组访问)。也许语言设计者想要因性能原因阻止这种使用。

编辑:我会很感激,如果downvoter(s)会评论为什么这是没有用的。

0
额外
我希望所有下来的选民都会评论为什么有人投票。我总是这样做,除非它是显而易见的(就像答案是完全错误的或无稽之谈)。
额外 作者 Jason Coco,
可能被刚刚阅读代码的人拒绝,并认为你提倡这样的代码。
额外 作者 Kris,

似乎是一个缺点   规范给我

还有更多的缺点,这是一个微妙的话题。查看

public class methodOverloading{
   public static void hello(Integer x){
      System.out.println("Integer");
   }

   public static void hello(long x){
      System.out.println("long");
   }

   public static void main(String[] args){
      int i = 5;
      hello(i);
   }
}

这里“long”会被打印(我自己没有检查过),因为编译器选择了自动装箱。使用自动装箱时请小心或根本不要使用它!

0
额外

正如大家已经指出的那样,自动装箱可以让你简化一些代码,但是你不能假装原语是复杂的类型。

另外有趣的是:“autoboxing是编译器级别的黑客”在Java中。自动装箱基本上是添加到Java上的一种奇怪的混合物。查看这篇文章了解更多关于它有多奇怪的细节。

0
额外

在C#中,整数既不是引用类型,也不必为了调用 ToString()而加框。但是, 在框架中被视为对象(作为ValueType,因此它们具有值语义)。在CLR中,基元上的方法通过“间接”加载到堆栈(ldind)来调用。

0
额外

另一种方法是使用:

String.valueOf(myInt);

该方法对于每个基本类型和 Object 都是重载的。这样你甚至不必考虑你使用的类型。该方法的实现将为你调用给定类型的适当方法,例如<�代码> Integer.toString(敏)</代码>。

请参阅 http://java.sun.com/javase/ 6 /文档/ API /爪哇/郎/ String.html

0
额外