天天看點

java 反射 私有構造函數_Java反射擷取私有構造函數、屬性、方法

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

package study.spring.bean;

public   class SimpleBean

{

private String beanName;

private SimpleBean() {

System.out.println( " SimpleBean " );

}

public   String getBeanName()

{

return beanName;

}

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

{

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[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異常。