2014-12-19 62 views
1

這裏我在運行java反射代碼時遇到了一些困難,我無法在運行時使用java中的反射來訪問動態更改的字段值這裏我將我的代碼完整代碼與輸出片段和預期產出Java反射無法訪問動態更改的私有字段值

這裏是我的反思類

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


public class Test1 { 

    public void reflect() throws IllegalAccessException, IllegalArgumentException, InvocationTargetException { 

     TestJava instance = new TestJava(); 

     Class<?> secretClass = instance.getClass(); 





     // Print all the field names & values 

     Field fields[] = secretClass.getDeclaredFields(); 

     System.out.println("Access all the fields"); 

     for (Field field : fields) { 

      System.out.println("Field Name: " + field.getName()); 
      if(field.getName().equals("i")) { 
       field.setAccessible(true); 

       System.out.println("For testing" +" "+field.get(instance) + "\n"); 
      } 

      field.setAccessible(true); 

      System.out.println(field.get(instance) + "\n"); 

     } 

    } 

    public static void main(String[] args) { 

     Test1 newHacker = new Test1(); 
     TestJava secret = new TestJava(); 



     try { 
      secret.increment(); 
      newHacker.reflect(); 
      secret.increment(); 
      newHacker.reflect(); 
      secret.increment(); 
      newHacker.reflect(); 
      secret.increment(); 
      newHacker.reflect(); 


     } catch (Exception e) { 

      e.printStackTrace(); 

     } 

     } 


} 

我在這裏從這個類訪問私有變量

public class TestJava { 

    private int i; 

    public void increment() { 
     i++; 

     System.out.println("Testing i value" +" "+ i); 
    } 

} 

把這個程序的輸出是

Testing i value 1 
Access all the fields 
Field Name: i 
For testing 0 

0 

Testing i value 2 
Access all the fields 
Field Name: i 
For testing 0 

0 

Testing i value 3 
Access all the fields 
Field Name: i 
For testing 0 

0 

Testing i value 4 
Access all the fields 
Field Name: i 
For testing 0 

0 

但該預期的結果

Testing i value 1 
Access all the fields 
Field Name: i 
For testing 1 

1 

Testing i value 2 
Access all the fields 
Field Name: i 
For testing 2 

2 

Testing i value 3 
Access all the fields 
Field Name: i 
For testing 3 

3 

Testing i value 4 
Access all the fields 
Field Name: i 
For testing 4 

4 

回答

3

Test1.reflect使用的TestJava不同的實例從mainsecret。 (請注意,有兩個地方new TestJava()被稱爲。)所以調用secret.increment()將不會影響Test1.reflect使用的TestJava的實例。

但是,如果你這樣做:

public class Test1 { 
    public void reflect(TestJava instance) throws IllegalAccessException, InvocationTargetException { 
     // Everything in your original method minus the first line 
    } 
    // ... 
} 

,然後使用main如下:

secret.increment(); 
newHacker.reflect(secret); 

那麼事情應該表現爲您期望。

+0

你是對的。但內部不明白爲什麼這不影響。請給你一個線索爲什麼? – 2014-12-19 06:01:54

+2

字段是每個實例(除非我們正在處理靜態字段,但這裏不是這種情況)。因此,對象的兩個不同實例將具有相同字段的獨立值。 – 2014-12-19 06:02:52