欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

int和Integer的区别与联系:包装类、自动拆箱装箱、享元模式

程序员文章站 2024-03-06 09:44:19
...

1、基本数据类型和引用数据类型

1.1、 基本数据类型:

java提供了8种基本数据类型:
boolean、byte、int、char、long、short、double、float;
java提供诸如:类、接口等引用数据类型,其中Integer就是一种引用数据类型,常被称为包装类。

1.2、int和Integer的区别

int是基本数据类型,Integer是int包装类。
Integer变量必须实例化后才能使用,int可以直接使用
Integer的默认值是null,int默认值是0
Integer变量实际上是对象的引用,指向new的Integer对象,int是直接存储数据。

2、包装类的自动拆箱装箱

2.1、什么是包装类

Java中的基本数据类型没有方法和属性,而包装类就是为了让这些拥有方法和属性,实现对象化交互
int和Integer的区别与联系:包装类、自动拆箱装箱、享元模式
数值型包装类都继承至Number,而字符型和布尔型继承至Object。

2.2、什么是拆箱装箱

装箱:基本数据类型转换为包装类;
拆箱:包装类转换为基本数据类型。

3、享元模式

对于两个非new生成的Integer对象,进行比较时,如果两个变量的值在区间-128到127之间,则比较结果为true,如果两个变量的值不在此区间,则比较结果为false。
解析原因:归结于java对于Integer与int的自动装箱与拆箱的设计,是一种模式:叫享元模式(flyweight)。
(1)加大对简单数字的重利用,Java定义在自动装箱时对于在-128~127之内的数值,它们被装箱为Integer对象后,会存在内存中被重用,始终只存在一个对象。
(2)而如果在-128~127之外的数,被装箱后的Integer对象并不会被重用,即相当于每次装箱时都新建一个 Integer对象。

享元模式(Flyweight)又称为 轻量级模式,它是一种对象结构型模式。

面向对象技术可以很好地解决一些灵活性或可扩展性问题,但在很多情况下需要在系统中增加类和对象的个数。当对象数量太多时,将导致运行代价过高,带来性能下降等问题。享元模式 正是为解决这一类问题而诞生的。

享元模式 是对象池的一种实现。类似于线程池,线程池可以避免不停的创建和销毁多个对象,消耗性能。享元模式 也是为了减少内存的使用,避免出现大量重复的创建销毁对象的场景。

享元模式 的宗旨是共享细粒度对象,将多个对同一对象的访问集中起来,不必为每个访问者创建一个单独的对象,以此来降低内存的消耗。

享元模式 把一个对象的状态分成内部状态和外部状态,内部状态即是不变的,外部状态是变化的;然后通过共享不变的部分,达到减少对象数量并节约内存的目的。

享元模式 本质:缓存共享对象,降低内存消耗

主要解决

当系统中多处需要同一组信息时,可以把这些信息封装到一个对象中,然后对该对象进行缓存,这样,一个对象就可以提供给多处需要使用的地方,避免大量同一对象的多次创建,消耗大量内存空间。

享元模式 其实就是 工厂模式 的一个改进机制,享元模式 同样要求创建一个或一组对象,并且就是通过工厂方法生成对象的,只不过 享元模式 中为工厂方法增加了缓存这一功能。

优缺点

优点

享元模式 可以极大减少内存中对象的数量,使得相同对象或相似对象在内存中只保存一份,降低内存占用,增强程序的性能;
享元模式 的外部状态相对独立,而且不会影响其内部状态,从而使得享元对象可以在不同的环境中被共享;

缺点

享元模式 使得系统更加复杂,需要分离出内部状态和外部状态,这使得程序的逻辑复杂化;
为了使对象可以共享,享元模式 需要将享元对象的状态外部化,而且外部状态必须具备固化特性,不应该随内部状态改变而改变,否则会导致系统的逻辑混乱;

使用场景

系统中存在大量的相似对象;
细粒度的对象都具备较接近的外部状态,而且内部状态与环境无关,也就是说对象没有特定身份;
需要缓冲池的场景;

code:

/**
 * @author ypy
 */
public class Demo1 {
    public static void main(String[] args) {
        Integer i = 100;
        Integer j = 100;

        if(i.equals(j)){
            System.out.println("i.equals(j) = "+i.equals(j));
        }else {
            System.out.println("i.equals(j) != "+i.equals(j));
        }

        /**
         * 非new生成的Integer变量和new Integer()生成的变量比较时,结果为false。
         * 因为非new生成的Integer变量指向的是静态常量池中cache数组,而cache数组中存储的指向了堆中的Integer对象,
         * 而new Integer()生成的变量指向堆中新建的对象,两者在内存中的对象引用(地址)不同。
         */
        Integer m = new Integer(5);
        int n = 5;
        System.out.println(m == n);

        /**
         * 对于两个非new生成的Integer对象,
         * 进行比较时,如果两个变量的值在区间-128到127之间,则比较结果为true,
         * 如果两个变量的值不在此区间,则比较结果为false
         *
         * 解析原因:归结于java对于Integer与int的自动装箱与拆箱的设计,是一种模式:叫享元模式(flyweight)。
         * (1)加大对简单数字的重利用,Java定义在自动装箱时对于在-128~127之内的数值,
         * 它们被装箱为Integer对象后,会存在内存中被重用,始终只存在一个对象。
         * (2)而如果在-128~127之外的数,被装箱后的Integer对象并不会被重用,即相当于每次装箱时都新建一个 Integer对象。
         */
        Integer i1 = 127;
        Integer j1 = 127;
        if(i1 == j1){
            System.out.println("i1 == j1");
        }else {
            System.out.println("i1 != j1");
        }

        Integer i2 = 128;
        Integer j2 = 128;
        if(i2 == j2){
            System.out.println("i2 == j2");
        }else {
            System.out.println("i2 != j2");
        }

        // 声明一个Integer对象,用到了自动的装箱:解析为:Integer num = Integer.valueOf(10);
        Integer num = 10;
        System.out.println("num = "+num);

        //声明一个Integer对象
        Integer num1 = 10;

        // 进行计算时隐含的有自动拆箱
        System.out.print(num1--);
    }
}

执行结果:
int和Integer的区别与联系:包装类、自动拆箱装箱、享元模式