2014-07-09 24 views
2

從我對java的瞭解我不認爲這是可能的,但我想提出這個問題的人比我有更多的知識。訪問時修改一個靜態變量

如果我有一個靜態變量說,

public static String NAME = "james"; 

有什麼辦法,通過反射或其它方式說創造了聽衆的變量,例如,如果有人呼叫:

ClassName.NAME 

它可以在獲得結果之前進行修改,因此我可以更改NAME的值,使其等於「simon」而不是?

要清楚,這個代碼庫不是我自己的,我不能改變變量來代替使用getters和setter。我知道這會讓這個更簡單,但不幸的是這不是一個選項。

+2

不,不適用於字段訪問,不適用於純Java。看看AspectJ。 –

+1

使變量保持私密並提供公共的getter和setter函數。 –

+0

@KevinWorkman我正在使用不是我自己的代碼庫,我不能將該變量更改爲方法,但不幸的是不會破壞其他人的代碼。 –

回答

6

不,你不能。這就是爲什麼你不應該使用public變量的原因之一。始終使用privateprotected變量,並通過像static public String getName()這樣的獲取方法訪問它們。這樣你可以把任何邏輯放入你想要的getter中。

2

有計算機科學的說,你可以實現由「間接的另一個水平」任何事情,這樣在使用的訪問方法:

public class Foo { 

    private static String name; 

    public static String getName() { 
     String result = name; 
     //do a lot of other things. 
     return result; 
    } 


} 

否則,我認爲這是不可能的。你可以重寫字節碼:這樣每個對這個項目的調用都會被替換爲首先做一些其他的事情。但這是非常複雜的。

如果它不是你自己的,你不能這樣做,除非用很大的努力(重寫字節碼)。

1

你可以做一些技巧來實現這一點,你不能直接修改它,但你可以使用公共靜態方法來訪問該變量。

另一方面,我同意Sotirios Delimanolis你可以使用方面來實現這一點。

您可以爲該變量創建一個切入點,以在其之前,之後或周圍修改該切入點。

對我來說,最好的方法是創建一個private static variable並通過public static method訪問它,然後use aspects訪問此方法並根據您的需要應用前/後邏輯。

+0

我對切入點或aspectj沒有太多瞭解,但是沒有將靜態變量更改爲private,並通過方法訪問它,當有人試圖讀取它時,是否可以使用切入點對其進行修改? –

+0

@AndrewT。我從來沒有使用方面來修改靜態變量,我一直使用的方法。但是,你可以同時擁有一個「公共靜態變量」和一個「公共靜態方法」來將它用作代理來使用一個方面修改變量。所以你結合兩種需求 –

0

您可以使用反射編輯靜態變量的值。

public class LoadClass { 
    public static String name="James"; 
    public void disp(){ 

    } 
    public static void main(String[] args) throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException { 
     Field field = LoadClass.class.getDeclaredField("name"); 
     System.out.println(field.get(new LoadClass())); 
     field.set(new LoadClass(), "simon"); 
     System.out.println("get field value " +field.get(new LoadClass())); 
     System.out.println("After change : " + name); 
    } 

} 

不知道這是否回答你的問題。

+0

不是。這是一個公共的靜態變量,我可以很容易地改變它,它在一個非常特殊的地方很難改變它。如果你可以給我一個方法,這樣我就可以改變這個變量在使用反射訪問時具體返回的內容,這對我有很大的幫助。 –

+0

你爲什麼要用反射?你也可以使用'LoadClass.name =「Simon」;'... –

+0

是的。你是對的。我們不需要反射API,我們可以直接訪問和更改值。但是,因爲安德魯想要反思的解決方案,我發佈了這個。 – user153