`
garyli
  • 浏览: 175815 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

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

    博客分类:
  • 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;
	}
	
	@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+",\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;
	}
	
	@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反射机制是JAVA编程语言中的一个核心特性,它允许运行中的程序动态地获取类的信息并操作类的对象。在JAVA中,反射机制提供了强大的能力,包括在运行时创建对象、访问私有成员、调用未知方法以及实现元编程等功能...

    JAVA反射机制与动态代理综合资料

    描述中的例子包含23个类,这些示例可能涵盖反射的不同应用场景,如访问私有成员、动态调用方法、动态创建对象等。 接下来,我们来看看Java动态代理。Java提供了两种实现动态代理的方式:`java.lang.reflect.Proxy`...

    JAVA反射机制与单例模式

    通过这些类,开发者可以实现动态加载类、创建对象、调用方法以及访问和修改私有成员变量。 反射机制的主要应用包括: 1. 动态加载类:在运行时根据需要加载未知类,例如在插件系统中。 2. 运行时发现并调用方法:...

    java中的反射reflect

    Java中的反射(Reflect)是Java语言的一个重要特性,它允许运行时访问类、接口、字段和方法的信息,甚至能够在运行时动态地创建对象和调用方法。反射在很多场景下都发挥着关键作用,比如在框架开发、插件系统、序列化...

    设计模式之单例模式(结合工厂模式)

    静态内部类单例利用Java类加载机制保证了线程安全,而枚举单例则是Java中实现单例的最佳方式,因为它天然支持序列化且防止反射攻击。 在代码实现上,我们可以创建一个名为SingletonFactory的工厂类,其中包含一个...

    Java单例模式

    Java单例模式是一种设计模式,它的核心思想是确保一个类只有一个实例,并提供一个全局访问点。这种模式在软件设计中非常常见,特别是在需要全局共享资源或者控制类的实例化次数时。以下是对Java单例模式的详细解释:...

    Java SE编程入门教程 java类和对象方法以及包的使用(共56页).pptx

    10. **反射机制**:Java的反射机制允许程序在运行时动态地获取类的信息(如类名、属性和方法),并能调用私有方法或修改私有属性。 11. **Java IO流**:IO流用于读写数据,包括从文件、网络、内存等源读取和写入。...

    单例模式_命令模式

    总结来说,单例模式保证了游戏规则管理器的唯一性,命令模式使得游戏逻辑可以通过命令对象进行灵活控制,而反射机制则实现了根据配置动态加载和执行命令。这种设计组合在`MyFirstGame v3.0`中展现了强大的灵活性和可...

    JAVA面向对象编程(孙卫琴)1.pdf

    8. **反射和动态代理**:反射允许运行时检查和修改程序结构,如获取类的信息、创建对象、调用方法等。动态代理则可以在运行时生成代理对象,用于实现AOP(面向切面编程)等高级功能。 9. **设计模式**:设计模式是...

    单例设计模式的优缺点和设计思想

    2. **对象复制问题**:需要防止通过序列化或反射机制创建额外的实例,这可能破坏单例模式的一致性。 ### 设计思想 单例模式的设计思想主要体现在对“单个实例”和“全局访问点”的追求上。通过将构造函数私有化并...

    私有java

    6. **Java反射API**:虽然私有成员在正常情况下无法被外部访问,但通过Java反射API,可以在运行时动态地获取类的信息并访问私有成员。然而,这通常是不推荐的,因为破坏了封装性,可能导致安全问题和难以维护的代码...

    JAVA设计模式--程序设计--反射--注解--泛型

    通过反射,我们可以动态地创建对象、调用方法、访问和修改私有属性,实现动态加载类,以及进行元数据分析等。反射的应用场景广泛,如插件系统、框架设计、单元测试等。 注解(Annotation)是Java中的元数据,它为...

    Java基础精品课22-xml与反射.zip

    反射在Java中是一个强大的工具,它允许程序在运行时检查类、接口、字段和方法的信息,并能动态地创建对象和调用方法。通过java.lang.Class类,我们可以获取任何类的信息,包括类名、方法、构造器等。java.lang....

    面试经常面试到的反射技术

    1. **什么是反射**:反射是Java提供的一种机制,它允许程序在运行时获取类的信息(如类名、属性、方法等)并动态调用对象的方法或访问其属性。这使得Java具有高度的灵活性和动态性。 2. **Class类**:在Java中,...

    Java面向对象精髓编程

    1. **类(Class)**:类是创建对象的模板或蓝图,它定义了一组属性(数据成员)和行为(方法)。属性描述了对象的状态,而方法描述了对象的行为。 2. **对象(Object)**:对象是类的实例,它是程序运行时的基本...

    设计模式学习使用的简单Demo

    6. **Java反射机制**:Java反射是Java语言的一个重要特性,它允许程序在运行时检查类的信息,如类名、属性、方法等,并能动态地调用方法和创建对象。反射在框架开发、元数据处理和动态代理等方面有着广泛的应用。...

    42丨单例模式(中):我为什么不推荐使用单例模式?又有何替代方案?1

    - **静态嵌套类**:在Java中,使用私有静态嵌套类来实现单例,可以防止反射攻击,同时保持代码的封装性。 - **枚举单例**:Java枚举可以自然地实现线程安全的单例,避免了双重检查锁定等问题,且提供了编译时的保证...

Global site tag (gtag.js) - Google Analytics