Java迷题:等于还是不等于?

 我来答
大沈他次苹0B
2022-10-14 · TA获得超过7320个赞
知道大有可为答主
回答量:3059
采纳率:100%
帮助的人:177万
展开全部
表面上看来这只是一些基础的问题 当真正的了解了以后你就会发现 啊 原来是这么一回事!下文是几道Java谜题 不仔细分析就会犯错哦

  等于还是不等于?

  看来看下面的一段代码

  代码片段

  public static void main(final String[] args) { Integer a = new Integer( ); Integer b = ; System out println(a == b); }

  这段代码的输出是什么?相信很多人都会很容易的猜到 false 因为a b两个对象的地址不同 用 == 比较时是false 恭喜你 答对了

  再看下面的一段代码

  代码片段

  public static void main(final String[] args) { Integer a = ; Integer b = ; System out println(a == b); }

  你可能会回答 这没什么不一样啊 所以还是false 很遗憾 如果你执行上面的一段代码 结果是true

  上面的代码可能让你有些意外 那好吧 再看看下面的这段代码

  代码片段

  public static void main(final String[] args) { Integer a = ; Integer b = ; System out println(a == b); }

  结果是true吗?很遗憾 如果你执行上面的一段代码 结果是false

  感到吃惊吗?那最后再看下面的一段代码

  代码片段

  public static void main(final String[] args) { Integer a = Integer valueOf( ); Integer b = ; System out println(a == b); }

  最后的结果 可能你已经猜到了 是true

  为什么会这样?

  现在我们分析一下上面的代码 可以很容易的看出 这一系列代码的最终目的都是用 == 对两个对象进行比较 Java中 如果用 == 比较两个对象结果为true 说明这两个对象实际上是同一个对象 false说明是两个对象

  现在 我们来看看为什么会出现上面的现象

  我们先看代码片段 最后的运行结果是true 说明a b两个对象实际上是同一个对象 但是a对象是通过调用Integer的valueOf方法创建的 而b对象是通过自动装箱创建出来的 怎么会是同一个对象呢?难道问题在字节码那里 毕竟Java程序是依靠虚拟器运行字节码来实现的

  通过jdk中自带的工具javap 解析字节码 核心的部分摘取如下

   : bipush : invokestatic # ; //Method java/lang/Integer valueOf:(I)Ljava/lang/Integer; : astore_ : bipush : invokestatic # ; //Method java/lang/Integer valueOf:(I)Ljava/lang/Integer;

  代码中我们只调用了一次Integer valueOf方法 但是字节码中出现了两次对Integer valueOf方法的调用 那么另一次是哪里呢?只可能在自动装箱时调用的 因此这段代码实际上等价于

  public static void main(final String[] args) { Integer a = Integer valueOf( ); Integer b = Integer valueOf( ); System out println(a == b); }

  现在问题就简单了 看jdk源代码 查看valueOf方法的具体实现

  public static Integer valueOf(int i) { final int offset = ; if (i >= && i <= ) { // must cache return IntegerCache cache[i + offset]; } return new Integer(i); }

  看到这儿 上面的代码就很明确了 对于 到 的数字 valueOf返回的是缓存中的对象 所以两次调用Integer valueOf( )返回的都是同一个对象

  我们再先看代码片段 根据上面的分析 代码片段 实际上等价于以下代码

  public static void main(final String[] args) { Integer a = Integer valueOf( ); Integer b = Integer valueOf( ); System out println(a == b); }

  由于 不在 到 范围内 所以两个对象都是通过new Integer()的方式创建的 所以最后结果为false

  片段 和片段 就不做具体分析了 相信读者可以自行分析

lishixinzhi/Article/program/Java/gj/201311/27590

已赞过 已踩过<
你对这个回答的评价是?
评论 收起
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式