Java:如果 Character 是包装类,为什么“Character newChar = 'c'”有效?为什么它不需要构造函数?

Ale*_*tis 3 java constructor factory java.lang.class java.lang

这些对我来说都很好:

示例 1:

Character newCharacter = 'c';
Run Code Online (Sandbox Code Playgroud)

示例 2:

Character newCharacterOther = new Character('c');
Run Code Online (Sandbox Code Playgroud)

但有什么区别呢?

在第一个示例中,Character 类如何知道将其值设置为“c”而不需要构造函数?

它是否在幕后使用工厂方法?有人可以向我解释编译器如何知道要做什么吗?

我在java.lang 中提供了Character.class 的构造函数的图像。

它甚至说它已被弃用,不应该像那样访问它,但我仍然有点困惑。

显示 Java 类的构造函数的图像

And*_*ner 6

语言规范中所述

赋值上下文允许使用以下之一:

  • ...
  • 拳击转换(第 5.1.7 节)
  • ...

参考第 5.1.7 节

具体来说,以下九种转换称为装箱转换:

  • ...
  • 从字符类型到字符类型
  • ...

在运行时,装箱转换按如下方式进行:

  • ...
  • 如果p是 char 类型的值,则装箱转换转换prclass 和 type的引用Character,这样r.charValue() == p
  • ...

所以,你的行相当于:

Character newCharacter = Character.valueOf('c');
Run Code Online (Sandbox Code Playgroud)

事实上,如果你反编译你的类,你会看到这正是被调用的。


但有什么区别呢?

new Anything保证创建一个新的实例Anything(或因异常而失败)。所以,new Character('c') == new Character('c')总是假的。

另一方面,Character.valueOf('c') == Character.valueOf('c') 可能为真,因为方法调用不需要返回新实例。实际上,规范保证您不会在这两次调用中获得新实例。

这允许您重用现有实例,避免不必要的分配,从而节省内存。