设计模式 笔记3 | 单例模式 在源码中的应用 Runtime 、Integer、Spring @Bean

文章目录

  • 一、Runtime 饿汉式
  • 二、Integer 封装类型中的单例
    • 2.1 自动装箱与自动拆箱
    • 2.2 IntegerCache 饿汉式
      • 2.2.1 拓展: Java类加载机制
      • 2.2.2 单例模式的源码浅析
  • 三、Spring 源码中的单例

一、Runtime 饿汉式


java.lang.Runtime 是从 JDK1.0 就开始出现的类,每个Java应用程序都有一个 Runtime 实例,该实例允许应用程序与运行应用程序的环境交互。当前运行时可以从getRuntime方法获得。

【例1】使用 Runtime 对象打开系统的记事本

public class Demo{
   
    public static void main(String[] args) throws IOException {
   
        Runtime runtime = Runtime.getRuntime();
        runtime.exec("notepad");
    }
}

【例2】使用 Runtime 对象打开系统的计算器

Runtime runtime = Runtime.getRuntime();
runtime.exec("calc");

【例3】使用 Runtime 对象实现10秒后自动关机

Runtime runtime = Runtime.getRuntime();
runtime.exec("shutdown -s -t 10");

这个类内部用到了单例模式中的饿汉式

public class Runtime {
   
    private static Runtime currentRuntime = new Runtime();

    public static Runtime getRuntime() {
   
        return currentRuntime;
    }
    
    private Runtime() {
   }
    ...
}

二、Integer 封装类型中的单例


2.1 自动装箱与自动拆箱

JDK8中的 Integer 是 int 类型的封装类型,可以直接互相转换,这个过程称为自动装箱和自动拆箱

public class Demo{
   
    public static void main(String[] args) {
   
        Integer a = 10;
        int b = a;
        System.out.println(a +"=" + b);
    }
}

那么它是如何实现 Integer -> int 自动拆箱类型的转换的呢?其实不用去硬记,我们直接调试一下就知道了,这里我使用的是 IDEA 工具
设计模式 笔记3 | 单例模式 在源码中的应用 Runtime 、Integer、Spring @Bean_第1张图片

通过调试可以看出, int -> Integer 本质上是调用了 Integer类中的 静态方法 valueOf(),而且这里我们返回的是 IntegerCache.cache里缓存的值

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

而 Integer -> int 本质上则调用了 Integer 类中的对象方法 intValue

public int intValue() {
   
    return value;
}

通过上面这个小例子,我们引入了 Integer类中的单例应用,静态内部类 IntegerCache,这个类是用来缓存 [-128 ~ 127] 的整型变量的,假如我们定义的a是大于127的数,比如128,调试看看结果:

设计模式 笔记3 | 单例模式 在源码中的应用 Runtime 、Integer、Spring @Bean_第2张图片

在 valueOf() 方法中判断整型变量的值超出了缓存的范围,于是就直接返回一个新的 Integer对象。

2.2 IntegerCache 饿汉式

2.2.1 拓展: Java类加载机制

Integer.IntegerCache 的源码如下,根据之前的学习我们可以判定这就是一个单例模式的具体实现,因为它具有以下几个特点,类是静态的,且构造方法私有化 private IntegerCache() {},除此之外,其内部变量以及一些初始化均是 static 修饰的,毕竟它的作用就是缓存,得在执行前就初始化完毕。
根据 Java 的类加载机制,对于静态类来说,访问到其内部的静态方法或非final修饰的静态变量或对象变量、对象方法,其内部的静态代码块才会执行,例如:我们只访问静态类中final修饰的静态成员变量 a

public class Demo{
   
    static class Test{
   
        private final static int a = 0;
        static void hello(){
   
            System.out.println("World!");
        }
        static{
   
            System.out.print("Hello,");
        }
    }
    public static void main(String[]

你可能感兴趣的:(学习笔记,单例模式,spring,java)