1. 程式人生 > 其它 >防止利用暴力反射破壞單例模式

防止利用暴力反射破壞單例模式

技術標籤:設計模式反射設計模式java

單例模式的實現是將構造私有化,然後內部維護一個物件,但是還是可以通過暴力反射建立多個例項,程式碼如下:
我以上篇文章講的靜態內部類方式實現單例模式為例:
程式碼:

package com.hy.practice;

import sun.security.jca.GetInstance;

/**
 * @author HY
 * @ClassName UserService
 * @Description 靜態內部類
 * @DateTime 2020/12/27 10:45
 * Version 1.0
 */
public class UserService
{ //構造私有化 private UserService() { } private static class InnerClass { //內部類內例項化 static UserService userService=new UserService(); } public static UserService getInstance(){ return InnerClass.userService; } }

暴力反射建立多個物件:

            Class<?> aClass =
Class.forName("com.hy.practice.UserService"); Constructor<?> constructor = aClass.getDeclaredConstructor(); constructor.setAccessible(true); Object o1 = constructor.newInstance(); Object o2 = constructor.newInstance(); System.
out.println(o1); System.out.println(o2);

輸出:
單例模式被破壞
可以看到,通過暴力反射可以呼叫私有的構造方法進行多次例項化,解決辦法就是在私有構造方法裡面判斷一下物件是否有例項。
程式碼:

package com.hy.practice;

import sun.security.jca.GetInstance;

/**
 * @author HY
 * @ClassName UserService
 * @Description 靜態內部類
 * @DateTime 2020/12/27 10:45
 * Version 1.0
 */
public class UserService {
    private static UserService instance;
    //構造私有化
    private UserService() {
        if (instance!=null){
           //說明有例項,直接報錯
            throw new RuntimeException("對暴力反射說NO");
        }
        //沒有就讓他用一次
        getInstance();
    }

    private static class InnerClass {
        //內部類內例項化
      private static  UserService userService=new UserService();
    }

    public static UserService getInstance(){
        return instance=InnerClass.userService;
    }
}

測試程式碼:

			Class<?> aClass = Class.forName("com.hy.practice.UserService");
            Constructor<?> constructor = aClass.getDeclaredConstructor();
            constructor.setAccessible(true);
            Object o1 = constructor.newInstance();
            System.out.println(o1);
            Object o2 = constructor.newInstance();
            System.out.println(o2);

輸出結果:
在這裡插入圖片描述
可以看到第一次呼叫沒有問題,第二次呼叫就報錯了,所以就解決了此問題