歡迎您光臨本站 註冊首頁

Java反射獲取私有構造函數、屬性、方法

←手機掃碼閱讀     火星人 @ 2014-03-09 , reply:0

  我一直以為類的私有構造函數、屬性、方法除了類自身其他類是無法訪問的,前幾天正好學習Spring框架,在學習Spring框架基礎 Bean包時,寫了一個簡單的例子,類似如下:

  package study.spring.bean;

  public class SimpleBean

  {

  private String beanName;

  private SimpleBean() {

  System.out.println( " SimpleBean " );

  }

  /** */ /**

  * @return Returns the beanName.

  */

  public String getBeanName()

  {

  return beanName;

  }

  /** */ /**

  * @param beanName The beanName to set.

  */

  public void setBeanName(String beanName)

  {

  this .beanName = beanName;

  }

  }

  發現居然也能調用成功,當時很驚訝,反射機制平時在以前的項目中也常使用,但不能構造只有私有構造函數的類.

  自己做了一個簡單例子:

  package study.spring.bean;

  import java.lang.reflect.Constructor;

  import java.lang.reflect.InvocationTargetException;

  public class SimpleTest

  {

  /** *//**

  * @param args

  */

  public static void main(String[] args)

  {

  // TODO Auto-generated method stub

  try

  {

  Constructor[] cts=Class.forName("study.spring.bean.SimpleBean").getDeclaredConstructors();

  for(int i=0;i<cts.length;i ){

  cts[i].newInstance(null);

  }

  }

  catch (SecurityException e)

  {

  // TODO Auto-generated catch block

  e.printStackTrace();

  }

  catch (ClassNotFoundException e)

  {

  // TODO Auto-generated catch block

  e.printStackTrace();

  }

  catch (IllegalArgumentException e)

  {

  // TODO Auto-generated catch block

  e.printStackTrace();

  }

  catch (InstantiationException e)

  {

  // TODO Auto-generated catch block

  e.printStackTrace();

  }

  catch (IllegalAccessException e)

  {

  // TODO Auto-generated catch block

  e.printStackTrace();

  }

  catch (InvocationTargetException e)

  {

  // TODO Auto-generated catch block

  e.printStackTrace();

  }

  }

  }

  也是如我所想 拋出java.lang.IllegalAccessException異常,當時就懷疑Spring框架是否使用反射的一些特性,後來查了相關文檔才知道原因何在:

  實際上java在反射創建一個類的實例時,默認會檢測是否符合相關安全,該檢測開關可以關閉.

  Constructor、Field、Method都是繼承於AccessibleObject,對應實例調用setAccessible(true)就關閉該開關

  如上面的例子,在代碼 cts[i].newInstance(null);行前調用上述方法: cts[i].setAccessible(true);

  這樣就可以創建只有構造函數的實例、調用私有構造方法,訪問類的私有屬性.

  呵呵,這樣好像java安全性就大大降低.如果你非常注重應用的安全性,java當然考慮到這方面,你可以在JVM啟動參數增加 -Djava.security.manager 啟用安全管理器,如果有該參數,它將檢測正在關閉接入檢測的代碼是否許可了這樣做,上述代碼執行時會拋出java.security.AccessControlException異常.


[火星人 ] Java反射獲取私有構造函數、屬性、方法已經有303次圍觀

http://coctec.com/docs/java/show-post-60293.html