`
从此醉
  • 浏览: 1089777 次
  • 性别: 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面试题》--新版Java面试专题视频教程,java八股文面试全套真题+深度详解(含大厂高频面试真题).zip

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

    常量池详解归类.pdf

    对于`String`类,它是Java中最常用的类之一,其字符串字面量(如"hello")在编译时就会放入常量池。在创建`String`对象时,如果使用字面量的方式(如`String s1="hello";`),那么相同的字面量将会引用常量池中的...

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

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

    java面试题详解如何更好面试

    java面试题 java面试题 java面试题 java面试题

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

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

    计算机和JAVA 面试题大全

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

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

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

    2024java面试题.pdf

    ### Java 面试知识点详解 #### 一、Java 基础知识 1. **面向对象的特征:** - **抽象**:抽象是指在程序设计中隐藏对象的复杂性,只展示对象的关键特性。这有助于降低系统复杂度,提高代码的可维护性和可读性。 ...

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

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

    120个Java经典面试题和答案

    以下是一些基于标题和描述中提到的Java经典面试题及对应的知识点详解: 1. **Java基础** - **数据类型**:Java有8种基本数据类型,了解它们的存储大小和范围,以及如何进行类型转换。 - **变量与常量**:理解变量...

    Java中级面试题

    ### Java中级面试题详解 #### Java基础 **1. StringBuffer的实现方式,容量如何扩充** - **实现方式**: `StringBuffer`内部通过一个字符数组`char[] value`来存储字符串内容。 - **容量扩充**: 当执行`append`...

    Java堆、栈和常量池详解

    易混点完美解析

    java面试题大全

    从给定的文件标题“java面试题大全”和描述“java基础,java面试技巧详解,及面试题及详解”中,我们可以提炼出一系列与Java面试相关的知识点,包括简历准备、面试技巧以及Java基础知识的重要性。 ### 简历准备 ...

    Java 中的字符串常量池详解

    Java中的字符串常量池是Java虚拟机(JVM)为了优化字符串对象的使用而设立的一个特殊区域,它存储了程序中所有的字符串字面量。在Java中,字符串是不可变的,这意味着一旦创建,就不能修改。这个特性使得字符串常量...

    java 五大流行框架 spring,springmvc,mybatis等面试题详解

    java 五大流行框架 spring,springmvc,mybatis等面试题详解

    (完整版)运维面试题(含答案).pdf

    (完整版)运维面试题(含答案).pdf(完整版)运维面试题(含答案).pdf(完整版)运维面试题(含答案).pdf(完整版)运维面试题(含答案).pdf(完整版)运维面试题(含答案).pdf(完整版)运维面试题(含答案).pdf(完整版)运维面试题...

    Java 常量池的实例详解

    主要介绍了Java 常量池的实例详解的相关资料,Java的常量池中包含了类、接口、方法、字符串等一系列常量值,需要的朋友可以参考下

    Java面试题详解,和一些基础知识的深入剖析,个人认为非常棒

    “JAVA面试题解惑系列(六)——字符串(String)杂谈”可能涉及到String池的概念,即JVM会缓存重复的字符串,以提高性能。此外,String的equals()和==的区别也常常是面试的焦点,前者比较内容,后者比较对象引用。 ...

    2023最新java面试题附带答案详解,代码,word文档

    以下是一些基于提供的面试题的知识点详解: 1. **栈(Stack)**:栈是一种特殊的线性表,遵循“后进先出”(LIFO)原则。它可以使用顺序存储或链式存储,但通常使用链式存储以方便插入和删除操作。栈的记忆作用体现...

Global site tag (gtag.js) - Google Analytics