我们知道Java中的运行时常量池存储以下文字: 1)整数2)长3)浮点数4)双5)字符串。因此,存储的布尔文字和字符文字在哪里?
示例:
Character c1 = 'a';
Character c2 = 'a';
System.out.println(c1==c2); //prints true
由于==
比较引用,c1和c2是否共享相同的引用? (=请注意,创建这些文字使得它们是相应的原始包装类的对象。
答案 0 :(得分:2)
正如你所说,c1和c2在堆中共享相同的对象,因此比较将为真。这是Java缓存机制。将缓存在-127 .. 127范围内值的所有字符,整数。因此Java将获得缓存值而不是创建新值。这就是两个对象共享相同引用的原因。
Character c1 = 'a';
Character c2 = 'a';
Character c3 = new Character('a'); // force Java creates new object in heap
System.out.println(c1 == c2); -> true
System.out.println(c1 == c3); -> false
出于同样的原因,这是另一个例子:
Integer i1 = 127;
Integer i2 = 127;
System.out.println(i1 == i2); // true
Integer i3 = 1000;
Integer i4 = 1000;
System.out.println(i3 == i4); // false, out of cache range
您将遇到另一个字符串示例,但是在不同的机制上:
String s1 = "stack";
String s2 = "stack";
String s3 = new String("stack");
System.out.println(s1 == s2); // true
System.out.println(s1 == s3); // false
创建时的所有java字符串都将分配并存储在String Pool
中。当您创建新字符串时(如果是s2),Java将在String pool
中搜索此字符串是否已在某处分配。在第三种情况下,我们对Java说:"嗨,Java,请随时为我创建新的"。
总结,在使用compareTo
方法比较两个对象时,比较两个基元时,可以使用==
运算符。 (只是提醒你旧的Java类)。
希望这有帮助:)
答案 1 :(得分:2)
我们知道Java中的运行时常量池存储以下文字:1)整数2)长3)浮点数4)双5)字符串。
实际上,这并不完全正确。一个正确的陈述是在实践中为每个类型Boolean
,Byte
,Short
,{{1}提供了一个单独的自动装箱值的运行时池},Character
和Integer
。
这些池不适用于文字 ...因为包装类型的文字不存在 1 。这些类型的Java文字是基本类型的值。 (事实上,根据JLS,类型Long
或byte
根本没有明显的文字。)
short
和Float
没有自动装箱池,尽管各个Double
方法的javadoc似乎意味着什么。 JLS不需要valueOf
和Float
的autobox缓存,并且库不实现它(至少在Java 6,7,8中)。
另一点需要注意的是,并非所有由自动装箱生成的值都在相应的池中。例如,(默认情况下)只有Double
缓存-128到+127的值。
因此,布尔文字和字符文字在哪里存储?
答案如下:
Integer
和Boolean
类型的文字。Character
和Boolean
的实例可能来自相应的自动装箱池。以你的例子为例:
由于==比较引用,c1和c2是否共享相同的引用?
这是正确的。它说明了前一点。 Character
的自动装箱池(通过JLS)需要通过Character
缓存'\u0000'
。
请注意,我遗漏了'\u007f'
。 String
池是不同的,因为它(主要)用于字符串文字。另一方面,没有为字符串值定义自动装箱......因为字符串值不必与原语与包装二分法相抗衡。
1 - 抱歉迂腐,但是如果你想真正了解这些事情并与其他人一致地谈论这些事情,那么使用正确的Java特定术语是至关重要的。为了严格地说,Literal是出现在>>源代码中的内容<<一个程序。在运行时,相应的东西是值。
答案 2 :(得分:0)
Character c1 = 'a';
Character c2 = 'a';
和
一样Character c1 = 'a';
Character c2 = c1;
两个引用指向同一个对象。在我创建的第二个案例中,c2引用c1,其中c1也是一个指向对象'a'
的引用变量。
可以找到有关参考变量的更多说明here。
另外更准确地说,你是在堆栈内存中创建两个引用变量,名义上是c1和c2,但它们都指向堆内存中的同一个对象!