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

Mik*_*one 51 java autoboxing

我想将原语转换为字符串,我试过:

myInt.toString();
Run Code Online (Sandbox Code Playgroud)

这失败并出现错误:

int cannot be dereferenced
Run Code Online (Sandbox Code Playgroud)

现在,我得到的原语不是引用类型(即不是Object),所以不能有方法.然而,Java 5引入了自动装箱和拆箱(一个C#......我在C#中从未喜欢过,但这不是重点).因此,使用自动装箱,我希望上面的内容将myInt转换为Integer,然后调用toString().

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

Jus*_*ard 45

Java自动装箱/取消装箱不会允许您取消引用原语,因此编译器会阻止它.您的编译器仍然知道它myInt是一个原语.在jcp.org上有一篇关于这个问题的论文.

在分配或参数传递期间,自动装箱主要是有用的 - 允许您将基元作为对象传递(反之亦然),或者将基元分配给对象(反之亦然).

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

Integer.toString(myInt);
Run Code Online (Sandbox Code Playgroud)


Pat*_*ick 27

贾斯汀所说的同样如此,但你应该这样做:

Integer.toString(myInt);
Run Code Online (Sandbox Code Playgroud)

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


SaM*_*SaM 15

另一种方法是使用:

String.valueOf(myInt);
Run Code Online (Sandbox Code Playgroud)

对于每种基本类型都会重载此方法Object.这样你甚至不必考虑你正在使用的类型.该方法的实现将为您调用给定类型的适当方法,例如Integer.toString(myInt).

请参阅http://java.sun.com/javase/6/docs/api/java/lang/String.html.


dli*_*sin 9

对我来说似乎是规范的缺点

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

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);
   }
}
Run Code Online (Sandbox Code Playgroud)

这里将打印"long"(我自己没有检查过),因为编译器选择扩大自动装箱.使用自动装箱时要小心,或者根本不使用它!


eri*_*son 5

最接近您的示例的有效语法是

((Integer) myInt).toString();
Run Code Online (Sandbox Code Playgroud)

当编译器完成时,这相当于

Integer.valueOf(myInt).toString();
Run Code Online (Sandbox Code Playgroud)

但是,这并不像传统用法那样好String.valueOf(myInt),因为除了特殊情况之外,它会创建一个新的Integer实例,然后立即抛弃它,导致更多不必要的垃圾.(缓存了一小部分整数,并通过数组访问进行访问.)语言设计人员可能出于性能原因而不鼓励这种用法.

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