Java类如何防止被实例化

时间:2022-07-23
本文章向大家介绍Java类如何防止被实例化,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

有一些类不想被实例化, 比如静态方法的工具类, 这时要对类进行特殊处理

其中有两点需要注意:

  • 防止通过new实例化 - 解决办法:使用 private 修饰符进行限制
  • 防止通过反射实例化 - 解决办法:抛出 Error 进行限制(如果不抛出异常, 只通过private进行限制, 则通过反射依然能被实例化)

代码如下:

// 不可实例化工具类
public final class MyUtils {
    private MyUtils() {
        throw new AssertionError("No " + MyUtils.class.getName() + " instances for you !");
    }
}

实例化测试:

  • new实例化
// 编译报错 - MyUtils() 在 com.jiafupeng.controller.rest.MyUtils 中是 private 访问控制
MyUtils myUtils = new MyUtils();
  • 反射实例化
Class<MyUtils> adminClass = MyUtils.class;
Constructor<?>[] declaredConstructors = adminClass.getDeclaredConstructors();
Constructor<?> c = declaredConstructors[0];
c.setAccessible(true);//  使其能访问到private构造方法
Object o = c.newInstance();
System.out.println(o);

// 运行报错
Exception in thread "main" java.lang.reflect.InvocationTargetException
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
    at com.jiafupeng.controller.rest.UserController.main(UserController.java:59)
Caused by: java.lang.AssertionError: No com.jiafupeng.controller.rest.MyUtils instances for you !
    at com.jiafupeng.controller.rest.MyUtils.<init>(MyUtils.java:11)
    ... 5 more

拓展 可参考 java.util.Objects

/**
 * This class consists of {@code static} utility methods for operating
 * on objects.  These utilities include {@code null}-safe or {@code
 * null}-tolerant methods for computing the hash code of an object,
 * returning a string for an object, and comparing two objects.
 *
 * @since 1.7
 */
public final class Objects {
    private Objects() {
        throw new AssertionError("No java.util.Objects instances for you!");
    }
    ...
}