Java: 线程安全、防反射注入的单例模式

java标志
image-3326

TextUtils.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
package com.genapicode;


public class TextUtils {

  private static final TextUtils TEXT_UTILS = new TextUtils();

  private TextUtils() {
    if (TEXT_UTILS != null) {
      throw new UnsupportedOperationException("ERROR: Forbid reflection calls");
    }
  }

  public static TextUtils getInstance() {
    return TEXT_UTILS;
  }

  public void show() {
    System.out.println("show");
  }
}

MainTest.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
package com.genapicode;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.*;


public class MainTest {

  public static void main(String[] args)
      throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException,
          InstantiationException, IllegalAccessException {
    // 反射注入测试.
    Class clazz = Class.forName("com.genapicode.TextUtils");
    Constructor constructor = clazz.getDeclaredConstructor();
    constructor.setAccessible(true);
    TextUtils newInstance1 = (TextUtils) constructor.newInstance();
    System.out.println("TextUtils1  "+newInstance1);
    for (int i = 0; i < 10000; i++) {
      new Thread(() -> System.out.println(TextUtils.getInstance().toString())).start();
    }
    System.out.println(TextUtils.getInstance().toString());
    // 反射注入测试.
    Class clazz1 = Class.forName("com.genapicode.TextUtils");
    Constructor constructor1 = clazz1.getDeclaredConstructor();
    constructor1.setAccessible(true);
    TextUtils newInstance2 = (TextUtils) constructor1.newInstance();
    System.out.println("TextUtils2  "+newInstance2);
  }
}