先把类的构造方法私有化,如下:
/**
* 保证类不能被实例化
*/
public class CannotBeInstance {
private CannotBeInstance() {
System.out.println("实例化了");
}
}
此时想要实例化的话,就会报如下错误,记得在不同包下测试:
这样就安全了么,试试通过反射来实例化对象,如下:
运行结果如下:
发现被实例化了,此时解决方法可以在私有化的构造方法中直接抛出异常,修改如下:
再次使用反射来实例化CannotBeInstance对象,结果如下:
这样一看,通过反射好像也无法生成CannotBeInstance对象了。
子类实例化时会先调用父类的构造函数,那么此时如果CannotBeInstance类有子类,子类能实例化么,修改代码如下:
/**
* 保证类不能被实例化
*/
public class CannotBeInstance {
private CannotBeInstance() throws Exception {
throw new Exception("CannotBeInstance类无法被实例化");
}
/**
* 子类
*/
static class CannotBeInstance2 extends CannotBeInstance {
public CannotBeInstance2() throws Exception {
}
}
public static void main(String[] args) throws Exception {
CannotBeInstance2 cannotBeInstance2 = new CannotBeInstance2();
}
}
运行结果如下:
可以发现如果父类没有提供可以被正常访问的构造函数,那么就会影响到子类的实例化。所以如果某个类不允许被实例化,那么建议再加上final修饰符修饰类,避免被继承,从源头上处理问题。