11

在java中,我可以写这样的代码

Boolean b = true ;

它会起作用。我现在有一个拥有“真”值的对象。

这是如何运作的?为什么我不必通过构造函数传递值?像这样:

Boolean b = new Boolean( true ) ;

另外,我可以制作可以以类似方式实例化的自定义类吗?如果有,那叫什么?

这样我就可以做这样的事情:

Foobar foobar = "Test" ; 

因此有我自己的包装类。

谢谢

4

6 回答 6

14

不,你不能做后者。

前者称为自动装箱,并在 Java v1.5 中引入以自动包装,原语在其包装器对应物中。

使用泛型和/或集合时,可以清楚地看到自动装箱的好处:

来自文章:J2SE 5.0 in a Nutshell

“原始类型的自动装箱和自动拆箱”示例中,我们有:

之前(添加了自动装箱)

ArrayList<Integer> list = new ArrayList<Integer>();
list.add(0, new Integer(42)); 
int total = (list.get(0)).intValue();

 ArrayList<Integer> list = new ArrayList<Integer>();
 list.add(0, 42);
 int total = list.get(0);

如您所见,代码更清晰。

请记住文档中的最后一条注释:

那么什么时候应该使用自动装箱和拆箱呢?仅当引用类型和原语之间存在“阻抗不匹配”时才使用它们,例如,当您必须将数值放入集合中时。对于科学计算或其他对性能敏感的数字代码,不适合使用自动装箱和拆箱。Integer 不能替代 int;自动装箱和拆箱模糊了原始类型和引用类型之间的区别,但它们并没有消除它。

于 2011-02-03T19:39:54.080 回答
3

这是如何运作的?

这是一个编译器功能。编译器会自动生成装箱操作。它实际上要做的是生成

Boolean.valueOf(true);

因为这样现有的(不可变的)实例 Boolean.TRUE 和 Boolean.FALSE 将被使用而不是创建一个新的。

于 2011-02-03T19:44:38.717 回答
1

这与您可以制作 String 对象的方式相同:

String s = "foobar"

真的,这只是 Java 的一项优势。考虑到任何原始数据类型已经具有预定义的包装器,我也不确定为什么要创建自己的包装器类...

于 2011-02-03T19:40:24.360 回答
1

这个特性被添加到 Java 1.5,它被称为Autoboxing。这种魔法只适用于原始值和对应的包装器。

而且你不能用Java自己做。如果你仍然想要它,那就选择Scala——它很棒!也就是说,您可以使用称为隐式转换的功能。这是您的案例的小示例:

case class Foobar(value: String)
implicit def convertStringToFoobar(s: String) = Foobar(s)
val foobar: Foobar = "Test";
于 2011-02-03T19:45:48.913 回答
0

不,这只是编译器的魔法;它将这些视为特殊情况(称为自动装箱)。参见例如http://download.oracle.com/javase/1.5.0/docs/guide/language/autoboxing.html

于 2011-02-03T19:40:40.727 回答
0

它被称为自动装箱,基本上只是编译器为你做的事情。它仅在 Java 5 中添加,在此之前您必须使用new Boolean( true ), 或 (更好) Boolean.TRUE

不,您不能将它用于您自己的类,它仅适用于原始包装类。

于 2011-02-03T19:41:53.903 回答