`

Java包装类的常量池

    博客分类:
  • Java
 
阅读更多
Integer a=Integer.valueOf(100);
Integer b=Integer.valueOf(100);
System.out.println(a==b);
Double d1=Double.valueOf(100);
Double d2=Double.valueOf(100);
System.out.println(d1==d2); 
 
为什么包装类 Ingeter两个值就相等 Double的就不相等了呢

 

在给Integer赋值时,实际上是自动装箱的过程,也就是调用了Integer.valueOf(int)方法,当这个值大于等于-128并且小于等于127时使用了常量池,所以前两个地址是相等的,但是后两个超过了127,故不使用常量池。

也就是说
Integer -128~127实际上你可以看成是整形int,所以第一个类的输出结果应该是==
Interger 128以上的数值就不能看成int了,他是对象,两个值相同的不同的对象如果用==判断肯定是不等的,可以用equals判断。

 Java的8种基本类型 (Byte, Short, Integer, Long, Character, Boolean, Float, Double), 除Float和 Double以外, 其它六种都实现了常量池, 但是它们只在大于等于-128并且小于等于127时才使用常量池。 

Java包装类常量池详解  

 

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); 
             Integer i7 = 140; 
             Integer i8 = 140;
            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("i7=i8\t" + (i7 == i8);
            System.out.println();         
        } 
    }

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

i7=i8 false

Java为了提高性能提供了和String类一样的对象池机制,当然Java的八种基本类型的包装类(Packaging Type)也有对象池机制。

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

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

从这个静态块可以看出,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=i2false i1=i2+i3true i4=i5false i4=i5+i6true

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

分享到:
评论

相关推荐

    java 内存中 堆、栈、常量池、方法区的总结

    在Java中,String是一个特殊的包装类。字符串可以通过两种方式创建:直接赋值和使用new关键字。当使用直接赋值时,如`String str = "abc";`,JVM会在常量池中查找是否存在"abc",如果存在则直接引用该字符串;如果不...

    java包装类练习.doc

    java 包装类练习 Java 包装类是 Java 语言中的基本类型的对象表示形式,用于提供包装基本类型的对象。Java 包装类包括 Boolean、Byte、Character、Short、Integer、Long、Float 和 Double 八种。 1. Long 包装类型...

    详解JAVA 常量池

    它主要分为Class文件常量池、运行时常量池,全局字符串常量池,以及基本类型包装类对象常量池。 在JAVA语言中,字面量是指在源代码中用来表示固定值的表示法。例如,整数、浮点数、字符串、布尔类型、字符类型等都...

    深入探索Java常量池

    Java中的基本数据类型的包装类大部分都实现了常量池技术,即Byte、Short、Integer、Long、Character、Boolean。这些包装类默认创建了[-128,127]的对应类型的缓存数据存放到常量池中,超过此范围仍然会创建新的对象。...

    Java 包装类

    Java包装类是Java编程语言中的一个关键特性,主要用于将基本数据类型(如int、char、boolean等)与对象之间进行转换。这是因为Java的API库中许多类和方法都设计为接收或返回对象,而基本类型不是对象。为了解决这个...

    常量池详解归类.pdf

    相反,浮点数的包装类`Double`和`Float`并没有实现常量池,因此`Double d1=1.0; Double d2=1.0;`的比较结果为false,即使数值相同,它们也是堆中不同的对象。 对于`String`类,它是Java中最常用的类之一,其字符串...

    JVM常量池教程吐血整理干货.md

    Java中的一些基本数据类型的包装类(如`Integer`、`Byte`、`Character`、`Long`和`Short`)提供了缓存池来存储数值范围内的对象。这些缓存池的主要作用是为了提高性能,因为可以直接复用已存在的对象,而不是每次都...

    浅谈java常量池

    Java中的八种基本类型包装类(Byte、Boolean、Short、Character、Integer、Long、Float、Double)中,除了Boolean,其他七种为-128到127之间的整数值提供了常量池。这意味着,当你创建这些值的包装对象时,如果值在...

    Day20 Java常用类

    Java作为一种面向对象的语言,为了保持其面向对象的一致性,对于每种基本数据类型都提供了一个对应的包装类。这些包装类允许基本数据类型以对象的形式存在,从而使得它们可以作为参数传递给方法或者存储在集合中。 ...

    28.java基本类型封装.docx

    本文详细介绍了Java中基本数据类型封装的相关知识,包括基本概念、包装类的概述、自动装箱与拆箱以及包装类常量池的具体实现。通过了解这些内容,开发者可以更好地理解和运用Java语言中的基本数据类型及其封装类,...

    Java常用类

    除了基础类型的包装类外,Java还提供了一些专门用于处理数字的类,比如BigInteger、BigDecimal等,它们支持更大范围的数值运算,并且提供了更高的精度。 ### 六、Random类 Random类用于生成伪随机数。通过调用其...

    Java常用类讲义大全.docx

    * 常量池:采用双引号赋值字符串,那么在编译期将会放到方法区中的字符串常量池里。 * 堆中创建对象:如果是运行时对字符串相加或相减会放到堆中,并先验证方法区中是否含有相同的字符串常量,如果存在,把地址返回...

    java自动拆装箱及享元设计模式

    Java虚拟机(JVM)维护了一个字符串常量池,用于存储所有的字符串字面量和常量池中的字符串。当我们创建一个新的字符串对象时,如果该字符串的内容已经存在于常量池中,那么JVM会返回常量池中的引用,而不是创建新的...

    java面试题大全.pdf

    8. 基本数据类型与包装类:在Java中,除了八种基本数据类型,还存在与之对应的包装类,如Integer、Double等。它们是不可变的,并且提供了各种有用的方法来处理对应的基本数据类型。 9. 集合框架:Java集合框架包括...

    包装类和字符串1

    在Java编程语言中,包装类是用来封装基本数据类型的对象,它们提供了一种对象化的操作方式。以下是关于包装类和字符串的详细知识: 1. **基本数据类型及其包装类**: - Java有八种基本数据类型,包括`byte`、`...

    2023年Java常用API知识测试带答案.doc

    Java常用API知识点 String类相关知识点 ...这些知识点涵盖了Java中String类、StringBuffer类、包装类、null和“”的区别、正则表达式、自动装箱和常量池等方面的内容,对于Java开发者来说非常重要。

    java实验报告心得.doc

    本实验报告旨在掌握 Java 基础知识,包括 String 类、StringBuffer 类、Math 类、包装类和 StringTokenizer 类等。通过实验,学生可以熟悉 Java 基础编程概念和技术。 一、String 类 *equals() 方法和 "==" 运算符...

    动力节点老杜Java基础入门学习教程分享——常用类

    综上所述,本文介绍了 Java 编程语言中一些常用的类,包括 `String`、`StringBuffer`、`StringBuilder`、基本类型的包装类、日期类、数字类、`Random` 类以及枚举类型。这些类和接口是 Java 程序员经常使用的工具,...

    Java基础学习09.pdf

    它涵盖了String、StringBuffer和StringBuilder类的使用及其区别,8种基本数据类型的包装类,以及字符串常量池的概念。 首先,文档强调了学习目标,包括掌握StringBuffer和StringBuilder的使用方法,理解String与...

    Java谜题,java中的有趣的解谜

    2. **字符串常量池**:Java中的字符串是不可变的,每次创建新的字符串对象,如果内容已经存在于字符串常量池中,那么实际上只是返回了池中的引用,而不是创建新对象。这个特性在处理大量字符串拼接时需要特别注意。 ...

Global site tag (gtag.js) - Google Analytics