2015-04-29 66 views
3

Java初級;使用反射可以訪問私人領域(不問如何, Question 1Question 2)好的。Java:通過反射訪問私人領域(行爲)

我的問題與這種行爲的性質有關。

  1. 有什麼限制嗎?我可以訪問我遇到的任何.class的字段嗎?
  2. 在我的代碼中,一旦你設置了一個字段的可見性,可以說「公開」,它是永久改變還是直到上下文結束(方法,如果...)? 以下代碼
  3. 是不是ok給大家?我的意思是,StackOverflow的Seniors程序員,是否存在安全漏洞?

代碼將帖子:

Field f = obj.getClass().getDeclaredField("field"); 
    if (...) { 
    f.setAccessible(true); 
    // f IS accesible 
    } 
    // is f accesible? 
+1

在某些情況下,反射是違反規定的。想到的一種情況是通過反射訪問它的'private'構造函數來創建一個'Singleton'類的多個實例。 – CKing

+3

你是什麼意思「*在我的代碼中,一旦你設置了一個字段的可見性讓我們說」公開「,*」?如果你指的是'f.setAccessible(true)',那麼你准許訪問它所表示的Field的這個特定實例。如果您創建另一個Filed指向同一個字段的實例(不管在前一個字段實例上調用了setAccessible(true)),這個新實例將無法訪問專用字段。 – Pshemo

+0

@Chetan Kinger正是!如果某件事被設計成私人的......讓它成爲私人的。在私有屬性的情況下......嘗試調用已實現的getter。 Pshemo,在你調用setAccessible的上下文結束時仍然可以訪問(編輯我的問題) – Manu

回答

3

有什麼限制嗎?

是的 - 您需要幾個JVM permissions(最值得注意的是accessDeclaredMemberssuppressAccessChecks,在文檔中標有大膽的警告)才能使用;如果您的JVM的安全配置文件有些嚴格(比如說,這些惹人注意的applet),那麼您的代碼將無法工作,因爲這些權限將不可用。

它會永遠改變嗎?

是的,只要程序繼續運行,字段將保持可訪問狀態(只要您繼續使用與更改訪問權限相同的Field實例)即可訪問。

不好嗎?

不一定。它允許Java代碼使用私有字段對對象進行序列化和反序列化,它允許複雜的嘲諷,可以簡化測試,它允許您查看那些你無法窺探的地方。但是,由於它打破了期望,所以應該謹慎使用它,並確保用戶知道您需要額外的權限並且「正在尋找隱藏的空間」。文檔(見上文)很清楚地表明,這被認爲是有風險的,只有當你知道你在做什麼時才應該允許它。

+0

「*它會永遠改變嗎?是的,只要你的程序繼續運行,字段將保持可訪問。*」這僅適用於通過調用'setAccessible(true)'的'Field'實例訪問此字段(並且沒有拋出SecurityException)。我們仍然無法直接訪問私人領域(沒有反思)。 – Pshemo

+0

謝謝你指出 - 更新的答案。 – tucuxi