读书人

java 反照机制更改私有属性 重复创建单

发布时间: 2012-12-26 14:39:29 作者: rapoo

java 反射机制更改私有属性 重复创建单例类对象

单例类:

?

?

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;}@Overridepublic 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+",\n\t 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+",\n\ts2:"+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+",\n\t s2:"+s2+"\n\t 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;}@Overridepublic 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


?

?

读书人网 >编程

热点推荐