beauty_beast

上善若水 厚德载物

反射之私有构造函数、属性、方法

Posted on 2006-05-15 18:35 柳随风 阅读(2038) 评论(2)  编辑  收藏 所属分类: java基础

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




Feedback

# re: 反射之私有构造函数、属性、方法  回复  更多评论   

2007-04-20 13:42 by hackest
谢谢
写得不错!
强!

# re: 反射之私有构造函数、属性、方法[未登录]  回复  更多评论   

2007-07-30 16:24 by king
niu up

只有注册用户登录后才能发表评论。


网站导航:
博客园   IT新闻   Chat2DB   C++博客   博问