Integer的内部学习

Integer的内部学习:



学习内容:

  1. Integer自动装箱和拆箱的内部学习
  2. 静态代码块的深层
  3. 缓存区域的原理
  4. 缓存为什么用内部类去写

过程:

Integer自动装箱和拆箱的内部学习

理解自动装箱

当基本数据类型处于需要对象的环境中,就会自动触发装箱机制,也就是说会自动把基本数据类型转换为包装类对象。
底层:触发自动装箱机制的时候,会默认调用valueOf(xxx x)这个静态方法来实现。

(1)提出问题

public static void main(String[] args) {
        Integer a = 80;
        Integer b = 80;
        Integer c = 150;
        Integer d = 150;
        System.out.println(a == b);
        System.out.println(c == d);
    }

运行结果:
在这里插入图片描述
问题的提出:为什么对象指代的值是相同的,为什么打印的两个结果不同呢?

(2)查找源码

public static Integer valueOf(int i) {
        if (i >= IntegerCache.low && i <= IntegerCache.high)
            return IntegerCache.cache[i + (-IntegerCache.low)];
        return new Integer(i);
    }

要对此代码进行理解就需要了解IntegerCache

(3)查找IntegerCache并对其理解
其中重要的几行代码的理解:
static final int low = -128; //缓存下届并不可改变,只能更改上届。
int h = 127;//h值,自动缓存区间设置为[-128,N]。区间的下界是固定 。
i = Math.max(i, 127);// 取较大的作为上界,但又不能大于Integer的边界MAX_VALUE。

(4)回到第(2)步进行理解
在Integer类中其实存在名叫Cache机制,它是一个常量,存在于Java的方法区中,当我们给定的整数在[-128,127]之间的话,那么会直接从cache中返回对应的Integer类的引用(或者说地址),如果整数的大小不在这个范围内的话,那么valueof()方法会新new一个Integer类型的对象,并返回。

(5)总结
当对象指代的值大于127,每一次返回的包装类型的地址都是不一样的。

理解自动拆箱

当包装类型处于需要基本数据类型的环境中,就会自动触发拆箱机制,也就是说会自动把包装对象转换为基本数据类型。
底层:触发自动拆箱机智的时候,会自动调用xxxValue()这个成员方法

Integer num = 100;
int num1 = num;

执行上面的代码时由于num为包装类型,而num1为基本数据类型,所以会进行自动拆箱,将包装类型转变为基本数据类型。其底层使用的方法是intValue()方法,具体内容如下:

public int intValue() {
        return value;
    }

静态代码块的执行学习

在代码中含有静态代码块时,我们经常碰到的就是代码块、静态方法、构造方法的执行顺序的问题。
我们通过例子来进行学习子类与父类静态代码块的执行顺序

package Test2;
public class TestDemo7 extends Test{

    static {
        System.out.println("子类静态代码块!");
    }
    {
        System.out.println("子类代码块!");
    }
    public TestDemo7(){
        super();
        System.out.println("子类构造!");
    }
    public static void main(String[] args) {
        TestDemo7 test = new TestDemo7();
    }
}
// 父类
class Test {
    public Test(){
        System.out.println("父类构造!");
    }

    {
        System.out.println("父类代码块!");
    }

    static {
        System.out.println("父类静态代码块!");
    }
}

执行结果:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
运用jclasslib生成的信息中的方法,可以看出执行的顺序是–>main–>。
通过分析得出结论: 加载顺序:父类静态代码块>子类静态代码块>main方法

缓存区域的理解

1.什么是缓存

1、Cache是高速缓冲存储器 一种特殊的存储器子系统,其中复制了频繁使用的数据以利于快速访问
2、凡是位于速度相差较大的两种硬件/软件之间的,用于协调两者数据传输速度差异的结构,均可称之为 Cache

2.什么是缓存区域

我们在编写代码的过程中有些数据,数据量小,但是访问十分频繁,针对这种场景,需要将数据放到缓存区域中,以提升系统的访问效率,减少无谓的数据库访问(数据库访问占用数据库连接,同时网络消耗比较大)。

3.缓存区域的好处

将程序或系统经常要调用的对象存在内存中,以便其使用时可以快速调用,不必再去创建新的重复的实例。这样做可以减少系统开销,提高系统效率。一般的用法就是把数据从数据库读到内存,然后之后的数据访问都从内存来读,从而减少对数据库的读取次数来提高效率。

Integer类里为什么实现内部缓存

我们知道在java中创建的新实例需要占用堆中的一些内存空间,因此创建新对象始终是一个昂贵的过程。因此为了避免这种昂贵的对象创建过程,许多框架会以不同的方式进行资源池化。
包装类在java中是不可变的,所以,像字符串池一样,他们也可以拥有自己的"字符串池"(抽象)。JDK提供的包装类也以实例池的形式提供它,即每个包装类以缓存的形式存储自己类型的常用实例列表,并且在需要时,可以在代码中使用它们。它有助于在程序运行时节省大量的字节。

在Integer.java类中有一个内部类,即IntegerCache
IntegerCache代码:

private static class IntegerCache
{
    private IntegerCache(){}
    static final Integer cache[] = new Integer[-(-128) + 127 + 1];
    static {
        for(int i = 0; i < cache.length; i++)
            cache[i] = new Integer(i - 128);
    }
}

valueOf()方法里是这样的:

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);
}

IntegerCache是​​静态内部类,只有在第一次使用时才会被初始化。所以在第一次,由于缓存创建,时间可能会更长,之后不会花费更多时间。但是,实际的好处是内存重用。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值