`
从此醉
  • 浏览: 1072835 次
  • 性别: Icon_minigender_1
  • 来自: US
社区版块
存档分类
最新评论

Java常量池详解之一道比较蛋疼的面试题

 
阅读更多

代码如下:

 

此文章来自DreamSea(张小哲),转载请注明出处!
/**
 * 
 * @author DreamSea 2011-11-19
 */
public class IntegerTest {
    public static void main(String[] args) {    
        objPoolTest();
    }

    public static void objPoolTest() {
        Integer i1 = 40;
        Integer i2 = 40;
        Integer i3 = 0;
        Integer i4 = new Integer(40);
        Integer i5 = new Integer(40);
        Integer i6 = new Integer(0);
        
        System.out.println("i1=i2\t" + (i1 == i2));
        System.out.println("i1=i2+i3\t" + (i1 == i2 + i3));
        System.out.println("i4=i5\t" + (i4 == i5));
        System.out.println("i4=i5+i6\t" + (i4 == i5 + i6));    
        
        System.out.println();        
    }
}

 看起来比较Easy的问题,但是Console输出的Result和我们所想的确恰恰相反,我们就疑惑了,这是为什么咧?

 

最后通过网上搜索得知Java为了提高性能提供了和String类一样的对象池机制,当然Java的八种基本类型的包装类(Packaging Type)也有对象池机制。    

Integer i1=40;Java在编译的时候会执行将代码封装成Integer i1=Integer.valueOf(40);通过查看Source Code发现

 

/**
     * Returns a <tt>Integer</tt> instance representing the specified
     * <tt>int</tt> value.
     * If a new <tt>Integer</tt> instance is not required, this method
     * should generally be used in preference to the constructor
     * {@link #Integer(int)}, as this method is likely to yield
     * significantly better space and time performance by caching
     * frequently requested values.
     *
     * @param  i an <code>int</code> value.
     * @return a <tt>Integer</tt> instance representing <tt>i</tt>.
     * @since  1.5
     */
    public static Integer valueOf(int i) {
    final int offset = 128;
    if (i >= -128 && i <= 127) { // must cache 
        return IntegerCache.cache[i + offset];
    }
        return new Integer(i);
    }

   Integer.valueOf()中有个内部类IntegerCache(类似于一个常量数组,也叫对象池),它维护了一个Integer数组cache,长度为(128+127+1)=256;Integer类中还有一个Static Block(静态块)

 

 

static {
        for(int i = 0; i < cache.length; i++)
        cache[i] = new Integer(i - 128);
    }

 从这个静态块可以看出,Integer已经默认创建了数值【-128-127】的Integer缓存数据。所以使用Integer i1=40时,JVM会直接在该在对象池找到该值的引用。

 

 

 

  也就是说这种方式声明一个Integer对象时,JVM首先会在Integer对象的缓存池中查找有木有值为40的对象,如果有直接返回该对象的引用;如果没有,则使用New keyword创建一个对象,并返回该对象的引用地址。因为Java中【==】比较的是两个对象是否是同一个引用(即比较内存地址),i2和i2都是引用的同一个对象,So i1==i2结果为”true“;而使用new方式创建的i4=new Integer(40)、i5=new Integer(40),虽然他们的值相等,但是每次都会重新Create新的Integer对象,不会被放入到对象池中,所以他们不是同一个引用,输出false。

 

  对于i1==i2+i3、i4==i5+i6结果为True,是因为,Java的数学计算是在内存栈里操作的,Java会对i5、i6进行拆箱操作,其实比较的是基本类型(40=40+0),他们的值相同,因此结果为True。

 

  

  好了,我想说道这里大家应该都会对Integer对象池有了更进一步的了解了吧,我在诺诺的问一句如果把40改为400猜猜会输出什么?

 

i1=i2    false
i1=i2+i3  true
i4=i5    false
i4=i5+i6  true

   这是因为Integer i1=400,Integer i2=400他们的值已经超出了常量池的范围,JVM会对i1和i2各自创建新的对象(即Integer i1=new Integer(400)),所以他们不是同一个引用。

此文章来自DreamSea(张小哲)http://www.cnblogs.com/DreamSea/archive/2011/11/20/2256396.html

 

3
4
分享到:
评论
2 楼 文仁126520 2014-03-14  
楼主给力啊
1 楼 string2020 2014-03-14  
楼主的钻研精神值得大家学习

相关推荐

    JAVA笔试面试题详解.pdf

    JAVA笔试面试题详解.pdfJAVA笔试面试题详解.pdfJAVA笔试面试题详解.pdfJAVA笔试面试题详解.pdfJAVA笔试面试题详解.pdfJAVA笔试面试题详解.pdfJAVA笔试面试题详解.pdfJAVA笔试面试题详解.pdfJAVA笔试面试题详解.pdf...

    详解JAVA 常量池

    详解JAVA 常量池 JAVA 常量池是JAVA语言中的一种机制,用于存储常量和符号信息。它主要分为Class文件常量池、运行时常量池,全局字符串常量池,以及基本类型包装类对象常量池。 在JAVA语言中,字面量是指在源代码...

    Java堆,栈和常量池详解

    ### Java堆、栈和常量池详解 #### Java内存模型概览 在深入探讨Java中的堆、栈以及常量池之前,我们先来简要回顾一下Java内存模型的基本概念。Java程序运行时会使用到不同的内存区域来存储各种类型的数据,这些...

    《JAVA面试题》--新版Java面试专题视频教程,java八股文面试全套真题+深度详解(含大厂高频面试真题).zip

    十余年JAVA从业经验,精通JAVA技术体系,有志于做JAVA技能提升的朋友可与我联系,交个朋友 十余年JAVA从业经验,精通JAVA技术体系,有志于做JAVA技能提升的朋友可与我联系,交个朋友 十余年JAVA从业经验,精通JAVA...

    详解Java常量池.docx

    详解Java常量池.docx

    Java面试题以及答案整理.pdf

    为了在Java面试中脱颖而出,了解和掌握常见的面试题及答案至关重要。以下是一些关键知识点的详细解析: 1. **super()与 this()的区别** `super()`用于调用父类的构造器,确保子类实例化时父类的初始化;`this()`则...

    汇丰软件java面试题

    "汇丰软件Java面试题详解" 汇丰软件Java面试题是许多IT行业新人的梦寐以求的岗位,需要考生具备扎实的Java基础知识和良好的编程能力。以下是对汇丰软件Java面试题的详细解析。 笔试部分 笔试部分主要包含三部分:...

    java软件工程师面试题

    这是我找java软件工程师时候,收集的java面试题,汇集了主要的试题,实际我在笔试中有80%的内容和这里面的是重复的.希望能帮助找java工作的您. EJB方面.doc java.doc Java中文问题详解(高手必读).txt Java中文问题...

    JAVA面试题JAVA面试题JAVA面试题

    Java面试题是每个Java开发者在求职过程中必须面对的挑战,涵盖范围广泛,涉及语言基础、数据结构、算法、多线程、JVM优化、框架应用等多个方面。以下是一些可能出现的Java面试知识点详解: 1. **Java语言基础** - ...

    java基础知识详解 Java入门必看 Java面试题集锦

    这份资料集主要涵盖Java基础知识、初学者入门指南以及常见的Java面试题,旨在帮助学习者系统地理解和掌握Java的核心概念。 首先,Java基础知识是理解任何Java程序的基础。这包括: 1. **Java环境搭建**:学习如何...

    计算机和JAVA 面试题大全

    【计算机和JAVA 面试题大全】 在计算机科学与技术领域,尤其是软件开发行业,Java是一种广泛应用的编程语言,以其跨平台、面向对象和高效性而受到赞誉。本资料集涵盖了丰富的Java面试题,旨在帮助求职者准备Java...

    最全java面试题及答案(208道).pdf

    "Java面试题及答案详解" Java是目前最流行的编程语言之一,在软件开发行业中广泛应用。以下是Java面试题及答案的详解: Java基础 1. JDK 和 JRE 的区别是什么? JDK(Java Development Kit)是Java开发工具包,...

    java程序员面试题——863面试集

    ### Java程序员面试题详解 #### 一、Java基础知识 1. **作用域public, private, protected, 以及不写时的区别** - **public**: 可以被任何类访问。 - **protected**: 可以被同一包内及不同包内的子类访问。 - ...

    [ 数据通信面试篇 ] 数通面试题大集合(详解)

    [ 数据通信面试篇 ] 数通面试题大集合(详解),看完直怼面试官(合集).rar 包含五个文档,文档质量可以去看我的文章: [ 数据通信面试篇 ] 数通面试题大集合(详解),看完直怼面试官(一)到(五)

    06-VIP-JVM调优实战及常量池详解(1)1

    字符串常量池是Java内存管理的一部分,它存储预编译的字符串。在JDK 1.6及以前,字符串常量池位于方法区(也称为永久代),而在JDK 1.7中,随着永久代逐渐被移除,字符串常量池被移到堆中。到了JDK 1.8及以后,永久...

    JAVA面试题 人事面试 Java技术面试

    1. **Java基础**:Java面试题-COREJAVA部分.txt可能会涵盖Java的基础语法,如数据类型、变量、运算符、流程控制语句,以及类、对象和封装等面向对象编程的概念。 2. **集合框架**:Java面试中,集合框架是必考知识...

    Java 面试题Java 面试题Java 面试题Java 面试题Java 面试题

    "Java 面试题详解" Java 是一门广泛应用于企业级开发、Android 应用开发、Web 应用开发等领域的编程语言。以下是对 Java 面试题的详细解释: 1. Java 中的对象和类 在 Java 中,类是一个蓝图或模板,用于创建对象...

    「Java学习+面试指南」一份涵盖大部分 Java 程序员所需要掌握的核心知识 准备 Java 面试,首选.zip

    Java 基础常见知识点&面试题总结(上) Java 基础常见知识点&面试题总结(中) Java 基础常见知识点&面试题总结(下) 重要知识点详解 : 为什么 Java 中只有值传递? Java 序列化详解 泛型&通配符详解 Java 反射机制详解...

    java面试题--反射机制

    ### Java反射机制详解 #### 一、引言 在Java面试中,经常会出现与反射机制相关的题目。这是因为Java反射机制不仅是Java语言的一项重要特性,也是理解Java动态特性的关键所在。通过本文,我们将深入探讨Java反射...

    互联网公司Java面试题及核心知识点

    相关技术领域的大厂面试题及详解,由于纸质书籍篇幅有限,部分面试题的解答会以电子版 的形式呈现。 适用人群:本资源适合具备一定Java编程基础的程序员和软件开发者,尤其是那些需要处理并发问题或开发高并发应用...

Global site tag (gtag.js) - Google Analytics