java反射 修改靜態方法的值 setAccessible太無節操了

這幾天閒來無事。在網上看了一個題目,相信你們都知道這個題目get

 static void change(String str){
        str="welcome";
    }
     
    public static void main(String[] args) {
        String str = "123";
        change(str);
        System.out.println(str);
    } 
str =多少?
若是你們都知道 。。
而後我想把最後輸出要「welcome」怎麼作?
因而改爲這樣
  static String change(String str){
        str="welcome";
        return str;
    }
而後main裏
str=change(str);這結果改了,可是改的代碼太多。、
我想只能改change方法。也不須要返回值,來解決問題。先看了下
String類發現 private final char value[]; 是私有的。把這個值改了不就OK了嘛
因而想到了反射:
代碼以下:
static void change(String str){
        try {
            Class<?> clazz = str.getClass();
            Field fields = clazz.getDeclaredField("value");
            Object obj = fields.get(str);
            char [] charValue = (char [] )obj;
            System.out.println(charValue); 
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
發現打出結果 welcome 那麼只要改掉
charValue就OK了吧。因而繼續加代碼 發現 modifiers "private final" 會出這個錯,
要加上
    field.setAccessible(true);
  try {
            Class<?> clazz = str.getClass();
            Field field = clazz.getDeclaredField("value");
            field.setAccessible(true);
            Object obj = field.get(str);
            char [] charValue = (char [] )obj;
            charValue = new char [3];
            for(int i=0;i<charValue.length;i++){
            charValue[i]='a';
            }
            field.set(str, charValue);
        } catch (Exception e) {
            e.printStackTrace();
        }
}發現能知足個人要求,。值是被改了,而後我想改變長度,因而又動一下代碼charValue = new char [4];
發現值不能改變 繼續看String源碼,發現有個count屬性,。因而又了改了這個值代碼以下

 try {
            Class<?> clazz = str.getClass();
            Field field = clazz.getDeclaredField("value");
            field.setAccessible(true);
            Object obj = field.get(str);
            char [] charValue = (char [] )obj;
            charValue = new char [4];
            for(int i=0;i<charValue.length;i++){
                charValue[i]='a';
            }
             Field field1 = clazz.getDeclaredField("count");
             field1.setAccessible(true);
             field1.set(str, charValue.length);
             field.set(str, charValue);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
發現能解決問題。
我又試了下
而後我又試下Integer 發現同樣能夠
代碼以下:
static void changeInteger(Integer a){            try {             Class<?> clazz = a.getClass();             Field field = clazz.getDeclaredField("value");             field.setAccessible(true);             field.set(a, 12312);         } catch (Exception e) {             e.printStackTrace();         }     }
我的以爲只要Field.setAccessible(true); 以後,即便是final關鍵字標示過得屬性也能夠有訪問權限!這樣的反射會改變JAVA的結構,甚至你的代碼可維護性,你徹底能夠 改別的代碼裏面的值 ,因此這只是一個簡單的例子。只是驗證經過反射能作一些讓你沒法想象的東西。。
相關文章
相關標籤/搜索