Java类如何防止被实例化

2020-08-14 16:24:44 浏览数 (1)

有一些类不想被实例化, 比如静态方法的工具类, 这时要对类进行特殊处理
其中有两点需要注意:
  • 防止通过new实例化 - 解决办法:使用 private 修饰符进行限制
  • 防止通过反射实例化 - 解决办法:抛出 Error 进行限制(如果不抛出异常, 只通过private进行限制, 则通过反射依然能被实例化)
代码如下:
代码语言:javascript复制
// 不可实例化工具类
public final class MyUtils {
    private MyUtils() {
        throw new AssertionError("No "   MyUtils.class.getName()   " instances for you !");
    }
}
实例化测试:
  • new实例化
代码语言:javascript复制
// 编译报错 - MyUtils() 在 com.jiafupeng.controller.rest.MyUtils 中是 private 访问控制
MyUtils myUtils = new MyUtils();
  • 反射实例化
代码语言:javascript复制
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
代码语言:javascript复制
/**
 * 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!");
    }
    ...
}

0 人点赞