在java中,我可以写这样的代码
Boolean b = true ;
它会起作用。我现在有一个拥有“真”值的对象。
这是如何运作的?为什么我不必通过构造函数传递值?像这样:
Boolean b = new Boolean( true ) ;
另外,我可以制作可以以类似方式实例化的自定义类吗?如果有,那叫什么?
这样我就可以做这样的事情:
Foobar foobar = "Test" ;
因此有我自己的包装类。
谢谢
在java中,我可以写这样的代码
Boolean b = true ;
它会起作用。我现在有一个拥有“真”值的对象。
这是如何运作的?为什么我不必通过构造函数传递值?像这样:
Boolean b = new Boolean( true ) ;
另外,我可以制作可以以类似方式实例化的自定义类吗?如果有,那叫什么?
这样我就可以做这样的事情:
Foobar foobar = "Test" ;
因此有我自己的包装类。
谢谢
不,你不能做后者。
前者称为自动装箱,并在 Java v1.5 中引入以自动包装,原语在其包装器对应物中。
使用泛型和/或集合时,可以清楚地看到自动装箱的好处:
在“原始类型的自动装箱和自动拆箱”示例中,我们有:
之前(添加了自动装箱)
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;自动装箱和拆箱模糊了原始类型和引用类型之间的区别,但它们并没有消除它。
这是如何运作的?
这是一个编译器功能。编译器会自动生成装箱操作。它实际上要做的是生成
Boolean.valueOf(true);
因为这样现有的(不可变的)实例 Boolean.TRUE 和 Boolean.FALSE 将被使用而不是创建一个新的。
这与您可以制作 String 对象的方式相同:
String s = "foobar"
真的,这只是 Java 的一项优势。考虑到任何原始数据类型已经具有预定义的包装器,我也不确定为什么要创建自己的包装器类...
这个特性被添加到 Java 1.5,它被称为Autoboxing。这种魔法只适用于原始值和对应的包装器。
而且你不能用Java自己做。如果你仍然想要它,那就选择Scala——它很棒!也就是说,您可以使用称为隐式转换的功能。这是您的案例的小示例:
case class Foobar(value: String)
implicit def convertStringToFoobar(s: String) = Foobar(s)
val foobar: Foobar = "Test";
不,这只是编译器的魔法;它将这些视为特殊情况(称为自动装箱)。参见例如http://download.oracle.com/javase/1.5.0/docs/guide/language/autoboxing.html。
它被称为自动装箱,基本上只是编译器为你做的事情。它仅在 Java 5 中添加,在此之前您必须使用new Boolean( true )
, 或 (更好) Boolean.TRUE
。
不,您不能将它用于您自己的类,它仅适用于原始包装类。