我一直以为类的私有构造函数、属性、方法除了类自身其他类是无法访问的,前几天正好学习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 安全性方面了解不多,实际开发中也很少与之相关,如哪位同行有相关经验,请多多指教,谢谢!