当前位置: 首页 > 面试题库 >

为什么Integer常量池的行为在127发生变化?

松和泰
2023-03-14
问题内容

我无法理解Java常量池常量的工作方式。

我了解字符串的行为,因此可以证明自己与整数常量也是如此。

所以,对于整数

Integer i1 = 127;
Integer i2 = 127;
System.out.println(i1==i2); // True

Integer i1 = new Integer(127);
Integer i2 = new Integer(127);
System.out.println(i1==i2); // False

直到这里一切都进入我的脑海。

我无法理解的是,当我从127增加整数时,它的行为有所不同。此行为在127之后发生变化,下面是代码段

Integer i1 = 128;
Integer i2 = 128;
System.out.println(i1==i2); // False. WHY?????

有人可以帮我理解吗?


问题答案:

不,用于数字的常量池与用于字符串的方法不同。对于字符串,只保留编译时常量-而对于整数类型的包装器类型,如果适用于该值,则任何装箱操作将始终使用该池。因此,例如:

int x = 10;
int y = x + 1;
Integer z = y; // Not a compile-time constant!
Integer constant = 11;
System.out.println(z == constant); // true; reference comparison

JLS保证池值的范围很小,但是实现可以根据需要使用更大的范围。

请注意,尽管不能保证,但是我看过的每个实现都可以Integer.valueOf用来执行装箱操作-因此,在没有语言帮助的情况下,你可以获得相同的效果:

Integer x = Integer.valueOf(100);
Integer y = Integer.valueOf(100);
System.out.println(x == y); // true

从JLS的5.1.7节开始:

如果装箱的值p为true,false,字节或\ u0000到\ u007f范围内的char或-128到127(含)之间的整数或短数,则令r1和r2为p的任何两次拳击转换。r1 == r2总是这样。

理想情况下,将给定的原始值p装箱将始终产生相同的参考。实际上,使用现有的实现技术可能不可行。以上规则是一种务实的妥协。上面的最后一个子句要求始终将某些通用值装在无法区分的对象中。该实现可以懒惰地或急切地缓存它们。对于其他值,此公式不允许对程序员方面的带框值的身份进行任何假设。这将允许(但不要求)共享部分或全部这些引用。

这样可以确保在最常见的情况下,这种行为将是理想的行为,而不会造成不必要的性能损失,尤其是在小型设备上。例如,较少内存限制的实现可能会缓存所有char和short值以及-32K到+ 32K范围内的int和long值。



 类似资料:
  • 我无法理解整数的Java常量池是如何工作的。 我理解字符串的行为,因此能够证明整数常量也是同样的情况。 因此,对于整数 (&A) 直到现在一切都在我脑海中浮现。 我不能理解的是,当我从127增加整数时,它的行为不同。此行为在127之后发生变化,下面是代码片段 有人能帮我理解一下吗?

  • 问题内容: 输出: 输出: 注意:-128至127之间的数字为真。 问题答案: 当你使用Java编译数字文字并将其分配给Integer(大写)时,编译器将发出: 当你使用自动装箱时,也会生成此行代码。 valueOf 实现了“合并”某些数字,对于小于128的值,它将返回相同的实例。 从Java 1.6源代码的第621行: high可以使用system属性将的值配置为另一个值。 如果使用该系统属性运

  • 只是想知道,为什么在-128到127之间? Integer.valueOf()文档说明它“缓存频繁请求的值”。但是和之间的值是否经常被请求为真实值?我认为经常要求的价值是非常主观的。 这背后有没有可能的原因? 从文档中还说明:“..并可能缓存此范围之外的其他值。” 如何实现?

  • 问题内容: 我已经创建了一个MS Access数据库并为其分配了DSN。我想通过我的Java应用程序访问它。 这就是我在做什么: 我在try块的第一行遇到了异常。那是;。为什么会有此异常? 问题答案: 对于Java 7,您可以仅省略该语句,因为它并不是真正需要的。 对于Java 8,您不能使用JDBC-ODBC Bridge,因为它已被删除。您将需要使用类似UCanAccess的名称。有关更多信息

  • 当我用)运算符使用双引号,并与其他字符串文字值相同的结果为true...为什么会这样? 据我所知,当我们使用()操作符处理字符串时,JVM返回新的,它在堆内存中创建一个新的字符串实例,并在字符串池中创建一个引用。如果这是真的,那么它如何在一个场景中返回true,在另一个场景中返回false? 第一种情况: 第二个场景: 有人能帮我吗?

  • 如果运行,将产生以下输出: 为什么当thread-0完成时,throwable-catching-activity似乎发生在这个完成的线程中?