Tal*_*han 35 java reflection singleton
我知道在Java中,我们可以通过创建一个类的实例new,clone(),Reflection和serializing and de-serializing.
我创建了一个实现Singleton的简单类.
我需要一直停止创建我的类的实例.
public class Singleton implements Serializable{
private static final long serialVersionUID = 3119105548371608200L;
private static final Singleton singleton = new Singleton();
private Singleton() { }
public static Singleton getInstance(){
return singleton;
}
@Override
protected Object clone() throws CloneNotSupportedException {
throw new CloneNotSupportedException("Cloning of this class is not allowed");
}
protected Object readResolve() {
return singleton;
}
//-----> This is my implementation to stop it but Its not working. :(
public Object newInstance() throws InstantiationException {
throw new InstantiationError( "Creating of this object is not allowed." );
}
}
Run Code Online (Sandbox Code Playgroud)
在这个类我已经设法停止了类实例new,clone()并且serialization,但是我无法通过Reflection来阻止它.
我创建对象的代码是
try {
Class<Singleton> singletonClass = (Class<Singleton>) Class.forName("test.singleton.Singleton");
Singleton singletonReflection = singletonClass.newInstance();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
Run Code Online (Sandbox Code Playgroud)
Dav*_*e G 57
尝试创建公共构造函数
private Singleton() {
if( Singleton.singleton != null ) {
throw new InstantiationError( "Creating of this object is not allowed." );
}
}
Run Code Online (Sandbox Code Playgroud)
Jon*_*eet 15
检查构造函数怎么样:
private Singleton() {
if (singleton != null) {
throw new IllegalStateException("Singleton already constructed");
}
}
Run Code Online (Sandbox Code Playgroud)
当然,这可能并没有真正阻止它 - 如果有人正在使用反射来访问私有成员,他们可能能够将字段设置为null.你必须问自己,你想要阻止什么,以及它是多么有价值.
(编辑:正如Bozho提到的那样,即使通过反思也可能无法设置最终字段.如果有一些方法可以通过JNI等进行,我不会感到惊讶,但是......如果你给人们足够的访问权限,他们就能够做几乎任何事......)
Boz*_*zho 10
private Singleton() {
if (Singleton.singleton != null) {
throw new RuntimeException("Can't instantiate singleton twice");
}
}
Run Code Online (Sandbox Code Playgroud)
你应该注意的另一件事是readResolve(..)方法,因为你的类实现了Serialiable.你应该返回现有的实例.
但使用单身人士的最简单方法是通过枚举 - 你不必担心这些事情.
| 归档时间: |
|
| 查看次数: |
41969 次 |
| 最近记录: |