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

Java中奇怪的整数装箱

岳阳文
2023-03-14
问题内容

我刚刚看到类似于以下代码:

public class Scratch
{
    public static void main(String[] args)
    {
        Integer a = 1000, b = 1000;
        System.out.println(a == b);

        Integer c = 100, d = 100;
        System.out.println(c == d);
    }
}

运行后,此代码块将打印出来:

false
true

我理解为什么第一个是false:因为两个对象是单独的对象,所以==比较引用。但是我不知道为什么第二条语句返回了true?当Integer的值在一定范围内时,会出现一些奇怪的自动装箱规则吗?这里发生了什么?


问题答案:

true行实际上是由语言规范保证的。从5.1.7节开始:

如果要装箱的值p为true,false,一个字节,\ u0000到\ u007f范围内的char或-128和127之间的int或short数字,则令r1和r2为任何两次装箱转换的结果的p。r1 == r2总是这样。

讨论继续进行,这表明尽管保证了第二行的输出,但第一行却没有保证(请参见下面引用的最后一段):

理想情况下,将给定的原始值p装箱将始终产生相同的参考。实际上,使用现有的实现技术可能不可行。以上规则是一种务实的妥协。上面的最后一个子句要求始终将某些通用值装在无法区分的对象中。该实现可以懒惰地或急切地缓存它们。

对于其他值,此公式不允许对程序员方面的带框值的身份进行任何假设。这将允许(但不要求)共享部分或全部这些引用。

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



 类似资料:
  • 我在做Maven项目。我用log4j做了一个日志。但它在给定的文件中显示了一些starnge日志。我试图理解,为什么会出现这种奇怪的日志,但我不明白。请帮助我,为什么这些不需要的行会进入日志文件。 请帮我把这个拿开。 log.properties 我通过阅读这个链接创建了这个文件。 代码是 日志txt-(log.txt的一些起始行)

  • 所以我更新了代码,添加了行所做的是将主线程置于Hibernate状态一段时间,因此jvm可以获得一些时间来创建一个新线程。我正在得到我的预期输出

  • 我发现了Java并发的奇怪行为。请参阅下面的下一段代码: 在我看来,这段代码应该挂起并永远等待,但是在控制台中的next out没有任何问题地完成了代码: 我试图找到一些关于如果线程死了通知锁的信息,但缺乏。我也没有在Java规范中找到任何信息。 但是如果我试图锁定其他对象(而不是thread对象),就会像我预期的那样工作得很好。

  • 如果有人理解java编译器为什么这么做,请解释一下。

  • 下面的代码是一个小示例,可以轻松重现问题。所以我有 String 类型的变量,它设置了默认值。我有3种方法: getter 塞特 将字符串转换为布尔值的方便方法 自省不会将getter作为readMethod返回,将setter作为WriteMethod返回。相反,它将isTest()方法作为readMethod返回。setter为空。 从文档中我了解到,如果类型是boolean,那么" is "

  • 问题内容: 我通常对JOINS十分熟悉,但这是新的。 假设三个表(两个表的典型情况和第三个链接器表): (出于简化目的,我无法复制实际的结构,这不是我的代码。) 通常,要获得“谁在什么时候买了什么”的表格,我可以这样做: 但是我已经看到了这个: 这是什么?只是另一种语法,还是一种性能技巧? (它在SQLServer,FYI上,但是大概可以应用于其他…) 问题答案: 括号不会改变语义。子句的位置控制