Java: Why does "Character newChar = 'c' " work if Character is a wrapper class? How come it doesn't need a constructor?

huangapple go评论62阅读模式
英文:

Java: Why does "Character newChar = 'c' " work if Character is a wrapper class? How come it doesn't need a constructor?

问题

Example 1:

Character newCharacter = 'c';

Example 2:

Character newCharacterOther = new Character('c');

But what are the differences?

In the first example, how does the Character class know to set its value to "c" without needing a constructor for that?

Does it use a factory method behind the scenes? Can someone please explain to me how the compiler knows what to do?

I have provided an image of the constructor of the Character.class in java.lang.

It even says that it's deprecated and that it shouldn't be accessed like that, but I am still confused a bit.

Java: Why does "Character newChar = 'c' " work if Character is a wrapper class? How come it doesn't need a constructor?

英文:

These are both fine for me:

Example 1:

Character newCharacter = 'c';

Example 2:

Character newCharacterOther = new Character('c');

But what are the differences?

In the first example, how does the Character class know to set its value to "c" without needing a constructor for that?

Does it use a factory method behind the scenes? Can someone please explain to me how the compiler knows what to do?

I have a provided an image of the constructor of the Character.class in java.lang.

It even says that it's deprecated and that it shouldn't be accessed like that, but I am still confused a bit.

Java: Why does "Character newChar = 'c' " work if Character is a wrapper class? How come it doesn't need a constructor?

答案1

得分: 6

I'll provide the translated portions:

语言规范中所述

> 赋值上下文允许使用以下之一:
>
> * ...
> * 自动装箱转换(§5.1.7)
> * ...

参考第5.1.7节

> 具体来说,以下九种转换被称为装箱转换:
>
> * ...
> * 从 char 类型到 Character 类型
> * ...
>
> 在运行时,装箱转换如下进行:
>
> * ...
> * 如果 p 是 char 类型的值,则装箱转换将 p 转换为类和类型为 Character 的引用 r,使得 r.charValue() == p
> * ...

所以,你的代码等效于:

Character newCharacter = Character.valueOf('c');

> 但它们有什么区别?

new Anything 保证创建一个新的 Anything 实例(或者会引发异常)。因此,new Character('c') == new Character('c') 总是为 false。

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

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

英文:

As described in the language spec:

> Assignment contexts allow the use of one of the following:
>
> * ...
> * a boxing conversion (§5.1.7)
> * ...

Referring to section 5.1.7:

> Specifically, the following nine conversions are called the boxing conversions:
>
> * ...
> * From type char to type Character
> * ...
>
> At run time, boxing conversion proceeds as follows:
>
> * ...
> * If p is a value of type char, then boxing conversion converts p into a reference r of class and type Character, such that r.charValue() == p
> * ...

So, your line is equivalent to:

Character newCharacter = Character.valueOf('c');

Indeed, if you decompile your class, you will see that's exactly what gets invoked.


> But what are the differences?

new Anything is guaranteed to create a new instance of Anything (or fail with an exception). So, new Character('c') == new Character('c') is always false.

On the other hand, Character.valueOf('c') == Character.valueOf('c') may be true, because there is no requirement for a method invocation to return a new instance. Indeed, it is guaranteed by specification that you won't get a new instance on these two invocations.

This allows you to reuse existing instances, avoiding unnecessary allocations, thus saving memory.

huangapple
  • 本文由 发表于 2020年8月14日 16:20:36
  • 转载请务必保留本文链接:https://go.coder-hub.com/63409113.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定