概述
单例类:
package com.shenli.test;
public class Singleton {
private static final Singleton singleton = new Singleton();
private Singleton(){}
public static Singleton getInstance(){
return singleton;
}
private int intValue = -1;
public int getIntValue(){
return this.intValue;
}
@Override
public String toString() {
return String.valueOf(hashCode()).concat(",").concat(String.valueOf(intValue));
}
}
它是一个单例类,并且拥有一个私有属性intValue,现在我们使用反射机制来改变私有属性,并且创建新的实例对象:
package com.shenli.test;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class TestReflect {
public static void main(String[] args) {
Singleton s = Singleton.getInstance();
Singleton s2 = Singleton.getInstance();
System.out.println("before change private value.");
System.out.println("t s:"+s+",nt s2:"+s2);
Class clazz = Singleton.class;
Field field;
try {
field = clazz.getDeclaredField("intValue");
field.setAccessible(true);
field.setInt(s2, 100);
} catch (NoSuchFieldException | SecurityException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
System.out.println("n After use reflect change private:");
System.out.println("t s:"+s+",nts2:"+s2);
try {
Constructor<Singleton>[] constructors = clazz.getDeclaredConstructors();
for(Constructor<Singleton> constructor : constructors){
constructor.setAccessible(true);
Singleton s3 = constructor.newInstance();
System.out.println("n After use reflect change constructor.");
System.out.println("t s:"+s+",nt s2:"+s2+"nt s3:"+s3);
}
} catch (SecurityException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
System.out.println("nSo the private value can be change, nand Singleton object can be Re-created.");
}
}
输出:
before change private value.
s:1143701442,-1,
s2:1143701442,-1
After use reflect change private:
s:1143701442,100,
s2:1143701442,100
After use reflect change constructor.
s:1143701442,100,
s2:1143701442,100
s3:1956785676,-1
So the private value can be change,
and Singleton object can be created many times.
如果不希望私有属性被更改,可以声明为final
如果单例类不会重复创建,就要在私有构造函数里面抛出异常。
更改后的Singleton如下:
package com.shenli.test;
public final class Singleton {
private static final Singleton singleton = new Singleton();
private Singleton(){
if(singleton != null){
throw new RuntimeException("The class Singleton can not be re-created!");
}
}
public static Singleton getInstance(){
return singleton;
}
private final int intValue = -1;
public int getIntValue(){
return this.intValue;
}
@Override
public String toString() {
return String.valueOf(hashCode()).concat(",").concat(String.valueOf(intValue));
}
}
运行测试程序后的输出:
before change private value.
s:64011397,-1,
s2:64011397,-1
After use reflect change private:
s:64011397,-1,
s2:64011397,-1
java.lang.reflect.InvocationTargetException
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source)
at java.lang.reflect.Constructor.newInstance(Unknown Source)
at com.shenli.test.TestReflect.main(TestReflect.java:46)
Caused by: java.lang.RuntimeException: The class Singleton can not be re-created!
at com.shenli.test.Singleton.<init>(Singleton.java:9)
... 5 more
最后
以上就是谦让飞鸟为你收集整理的java 反射机制更改私有属性 重复创建单例类对象的全部内容,希望文章能够帮你解决java 反射机制更改私有属性 重复创建单例类对象所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复