`
colorfish
  • 浏览: 26813 次
  • 性别: Icon_minigender_1
  • 来自: 长沙
社区版块
存档分类
最新评论

JDK源码学习一--Integer、Long、Float、Double基本数据类的缓存

阅读更多
1.Integer、Long、Float、Double基本数据类

问题来源:今天偶然看到了Integer.valueOf()方法,而查看资料显示【.valueof()是一个静态方法,同时调用几次该方法来创建Integet对象,最终都是调用到同一个Integer实例。】
由于对jdk的api实现不熟悉,所以不明白这些是怎么做到的。因此我编写一个例子进行一下验证:

Integer a = Integer.valueof(10);
Integer b = Integer.valueof(10);
Integer c = null;
c=10;
a=11;

最后我在 c = 10;处打下断点,查看各个对象的id号,发现实例a、b、c三个都是同一个实例id号,因此就表示a、b、c 是同一个对象。
这种结果正好符合资料上面的描述。当我把a=11;重新设置值时,对象a的实例id变成新的id号了,这样就相当于重新实例了一个Integer对象。
这种现象我没有弄明白,按照正常的思维来分析,a=11;这句代码应该只是把Integer实例中的value属性重设一下值,为什么会重新实例一个新的
Integer对象呢?是在没弄明白,所以只好去查看jdk 1.5 API源代码。
打开Integer类,里面的方法让我大开眼界,发现自己和大师级别人物的差距太大了,所以以后要继续好好学习,追随他们,直至超越(低调...)
根据上面的【问题来源】我有一下几个问题需要通过jdk的源码来解答疑惑。
1.为什么调用a、b、c这三个变量调用Integer.valueof()会得到同一个实例?
2.为什么c=10;也会自动变成一个等同于a、b的实例?
3.为什么执行a=11;之后会产生一个新的Ingeter对象?
抱着疑问去看东西,永远是最有效果的。
打开Integer类,就让我看到了一句代码,不得其解。
public static final Class<Integer> TYPE = (Class<Integer>) Class.getPrimitiveClass("int");

4.这句代码的意思不是很清楚,也不知道TYPE到底有啥作用,问题是Class.getPrimitiveClass()这个方法我在jdk1.5 api文档里面都没有找到。
这个问题先放下,不影响我对上面三个问题的解答。

问题一解答:
为什么调用Integer.valueof()会得到同一个实例,只好去查找valueof()方法。方法代码如下:

public static Integer valueOf(int i) {
final int offset = 128;
if (i >= -128 && i <= 127) { // must cache 该处只能缓存-128~127的数据,超出这个范围的就都是新实例化Ingeter对象。
    return IntegerCache.cache[i + offset];
}
        return new Integer(i);
    }



IntegerCache是Integer类的一个成员内部类,代码如下:
public final class Integer extends Number implements Comparable<Integer> {
… …
private static class IntegerCache {
private IntegerCache(){}

static final Integer cache[] = new Integer[-(-128) + 127 + 1];//静态设置一个存储Integer的数组,就是一个cache
//初始化这个cache,你会发现这个cache里面只缓存了-128~127这个范围的Integer实例。
static {
    for(int i = 0; i < cache.length; i++)
cache[i] = new Integer(i - 128);
}
    }

… …
}

按照源代码的逻辑来推断,只有在数值属于(-128~127)这个范围类的数据,调用Integer.valueof(输入的数值)才会使用缓存中已实例化好的对象。
超出这个范围的数据都是新实例化的对象。接下来就验证这个结论:

Integer e = Integer.valueof(128);
Integer f = Integer.valueof(128);


验证发现:果然e、f的实例号不一样。说明不在(-128~127)范围内的数据调用Integer.valueof()是产生新的实例。




自动装箱与拆箱的功能事实上是编译器来帮您的忙,编译器在编译时期依您所编写的语法,决定是否进行装箱或拆箱动作。在自动装箱时对于值从-128到127之间的值,它们被装箱为Integer对象后,会存在内存中被重用,所以范例4.6中使用==进行比较时,i1 与 i2实际上参考至同一个对象。如果超过了从-128到127之间的值,被装箱后的Integer对象并不会被重用,即相当于每次装箱时都新建一个Integer对象,所以范例4.7使用==进行比较时,i1与i2参考的是不同的对象。所以不要过分依赖自动装箱与拆箱,您还是必须知道基本数据类型与对象的差异。
分享到:
评论
2 楼 skill1986 2011-09-13  
cn-done 写道
是否尝试过
String a="123";
String b="123";
System.out.println(a==b)的结果是?


结果是True
1 楼 cn-done 2010-10-01  
是否尝试过
String a="123";
String b="123";
System.out.println(a==b)的结果是?

相关推荐

    基本数据类型和包装类型1

    基本数据类型包括字节(byte)、短整型(short)、整型(int)、长整型(long)、浮点型(float)、双精度浮点型(double)、字符型(char)以及布尔型(boolean)。这些类型直接存储值,没有对象的概念,它们在内存...

    必会的面试基本问题总结(1)

    - **答案**:Java提供了8种基本数据类型的包装类,分别是:`Byte`, `Short`, `Integer`, `Long`, `Float`, `Double`, `Character`, `Boolean`。这些包装类主要用于处理基本数据类型与对象之间的转换,以及提供各种与...

    GitHub 上标星 115k+ 的 Java 教程.pdf

    - **基本类型**:Java提供了多种基本数据类型,包括但不限于`byte`, `short`, `int`, `long`, `float`, `double`, `char`, `boolean`。每种类型都有其特定的大小和用途。 - `byte`: 占用8位内存空间,主要用于需要...

    Java 基础(2-8) - 知识点.pdf

    Java 有八种基本数据类型:boolean(布尔型)、byte(字节型)、char(字符型)、short(短整型)、int(整型)、float(单精度浮点型)、long(长整型)和double(双精度浮点型)。此外,每种基本类型都有对应的...

    百度、腾讯、头条、美团的面试题目总结!

    1. **八种基本数据类型的大小,以及他们的封装类** - `double`: 占用8位,对应的封装类为`Double`。 - `float`: 占用4位,对应的封装类为`Float`。 - `long`: 占用8位,对应的封装类为`Long`。 - `int`: 占用4位...

    java面试题整理

    基本数据类型包括`byte`、`short`、`int`、`long`、`float`、`double`、`char`和`boolean`。 4. **类型转换**: - 浮点型与双精度型转换:将`double`赋值给`float`需要强制类型转换,否则会导致精度损失。 - 短...

    Java八股文高频面试题

    - **Java数据类型分为基本类型和引用类型**:基本类型包括整数型(byte, short, int, long)、字符型(char)、浮点型(float, double)和布尔型(boolean)。引用类型包括类、接口和数组,如String。 4. **数据...

    【05-面向对象(下)】

    •八大数据类型的包装类分别为:Byte、Short、Integer、Long、Character、 Float、Double、Boolean。 把基本数据类型变量包装类实例是通过对应包装类的构造器来实现的,不仅如此,8个包装类中除了 Character之外,...

    Java常见面试题及答案.pdf

    1. Java中的基本数据类型包括byte、short、int、long、float、double、char和boolean,它们不是对象,而是直接存储值的类型。 2. 引用类型包括类、接口和数组,其中Integer是int的包装类,提供了面向对象的处理方式...

    java面试总结

    - **浮点型**: `float`, `double` - **字符型**: `char` - **布尔型**: `boolean` #### 十六、冒泡排序 - **原理**: 通过不断地比较相邻两个元素的大小,并交换位置,使得较大的元素逐渐“浮”到数组的后面。 - **...

    2021 - JAVA秋招基础知识点面试题

    String不属于Java的基本数据类型,基本类型包括byte、boolean、char、short、int、float、long、double。String是Java中的一个对象。 7. Java字符串操作类的区别: Java中操作字符串的类主要有String、StringBuffer...

    Java基础笔记

    Java提供了九种基本数据类型,并且每种基本数据类型都有相应的封装类。理解这些类型及其大小对于编写高效和资源利用合理的代码至关重要。 - **`byte`**: 占用1字节,即8比特。对应的封装类为`Byte`。 - **`short`**...

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

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

    j2ee面试题大汇总

    基本数据类型包括`byte`、`int`、`char`、`long`、`float`、`double`、`boolean`和`short`。 - **字符串常量池**:为了提高效率,Java会缓存字符串常量,以减少内存消耗。 2. **StringBuffer** 当需要频繁修改...

    Java 面试题208道.docx

    Java的八个基础数据类型是:byte、boolean、char、short、int、float、long和double。String是一个对象,它是类`String`的实例,不属于基础类型。 7. **String、StringBuffer和StringBuilder**: 这三个类都用于...

    java面试笔记整理,包含java,redis,kafka等

    - **Java提供了8种基本类型的包装类,如Integer、Double等。** - **必要性:** 为了使基本类型能够作为参数传递给需要Object类型的方法,同时也便于实现序列化和其他功能。 #### 十四、自动装箱与拆箱 - **自动装箱...

    java知识点

    Java的基本数据类型包括整型(byte、short、int、long)、浮点型(float、double)、字符型(char)和布尔型(boolean)。每种类型都有其特定的取值范围和内存占用。 理解并熟练运用这些Java知识点,不仅可以提升...

Global site tag (gtag.js) - Google Analytics