1. 程式人生 > >反射破壞單例類及呼叫JavaBean生成 的方法

反射破壞單例類及呼叫JavaBean生成 的方法

首先要上被破壞的單例類

package com.mywenwen;

public class Simpleton {
	private String username;
	private static Simpleton simple;
	private Simpleton(){
		
	}
	public static Simpleton getSimpleton(){
		return simple;
	}
	static{
		simple = new Simpleton();
	}
	public String getUsername() {
		return username;
	}
	public void setUsername(String username) {
		this.username = username;
	}
	public String toString(){
		return this.getClass().getName() + username + " , " + this.hashCode();
	}
}

這是一個正常的單例類 私有的構造方法和靜態 的返回方法 , 還有一個JavaBean的物件username和自動生成的get/Set方法

然後就是測試段

package com.mywenwen;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

public class SimpleTest {
	public static void main(String[] args) throws Exception{
		/*
		 * 呼叫 私有方法 強制例項化單例模式
		 * 
		 */
		Class<?> classSimple = Simpleton.class;
		Constructor<?> constructor = classSimple.getDeclaredConstructor();
		constructor.setAccessible(true);//取消Java語言訪問檢查
		Object obj = constructor.newInstance();//呼叫無參構造方法(Private)
		Field[] fields = classSimple.getDeclaredFields();//獲取欄位 , 包括private 
		
		for(Field fiel : fields){
		//開始執行遍歷欄位 並且生成設定方法(set + 首字母大寫 + 其他字母 )
			String s = "set" + fiel.getName().substring(0,1).toUpperCase() + fiel.getName().substring(1);
			System.out.println("Execute Method is " + s) ;
			if(!isUpdate(fiel))
				//判斷值是否為 String , int , float 不是就下一個
				continue;
			Method method = classSimple.getDeclaredMethod(s , String.class);
				//執行生成的方法
			method.invoke(obj, "wenwen");
			
		}
		//輸出修改的結果
		System.out.println(obj.toString());
	}
	public static boolean isUpdate(Field field){
		Class<?> c = field.getType();
		if(c == String.class)
			return true;
		if(c == Integer.TYPE)
			return true;
		if(c == float.class)
			return true;
		return false;
	}
}

然後要上執行結果