有时可能需要编写只包含静态方法和静态成员的类。例如:工具类。不论是JDK还是平时工作中的项目,总是会有很多的工具类。 这样的工具类不希望被实例化,因为实例化并没有太大的意义。 但是在缺少显式构造器的情况下,编译器会自动提供一个公有的无参构造器。 如何尝试让这些工具类不被实例化呢?
- 企图通过将类做成抽象类来强制该类不可被实例化是行不通的,该类可以被子类化,可以通过匿名内部类的方式进行实例化。这样做甚至会误导用户,以为这种类是专门为了继承而设计的
public class UtilDemo {
public static void main(String[] args) {
new XxUtil() {
@Override
public void test() {
System.out.println("被实例化了");
}
};
}
}
- 由于显式的构造器是私有的,不可以在类的外部访问。
AssertionError
不是必须的,可以是任何错误,这样做可以避免别的地方调用内部的构造器。保证该类在任何情况下都不会被实例化。
public class XxUtil {
private XxUtil(){
throw new AssertionError();
}
}
public class UtilDemo {
public static void main(String[] args) throws InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException {
// 这种方式是创建不了的
//XxUtil xxUtil = new XxUtil();
Class<XxUtil> clazz = XxUtil.class;
Constructor<XxUtil> ctor = clazz.getDeclaredConstructor();
ctor.setAccessible(true);
// 通过这种方式报错: java.lang.AssertionError
XxUtil xxUtil = ctor.newInstance();
System.out.println(xxUtil);
}
}
这种做法的副作用,就是不能被子类化。所有的构造器都必须显式或隐式调用超类构造器,在这种情形下,子类就没有可访问的超类构造器可调用了。 但是,一般情况下,工具类是没有子类的