反射破壞單例類及呼叫JavaBean生成 的方法
阿新 • • 發佈:2018-12-18
首先要上被破壞的單例類
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; } }
然後要上執行結果