A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 周海诚 黑马帝   /  2012-4-24 16:20  /  2901 人查看  /  7 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 周海诚 于 2012-4-24 19:47 编辑

回答了这么多,自己的问题也很多,一个个解决。阿门
反射中getDeclaredField(变量名)方法和setAccessible(ture)方法可以强行取出对象中的私有变量,
那把属性设为private还有什么用呢?

评分

参与人数 1技术分 +1 收起 理由
贠(yun)靖 + 1

查看全部评分

7 个回复

倒序浏览
反射中getDeclaredField(变量名)方法和setAccessible(ture)方法可以强行取出对象中的私有变量,
那把属性设为private还有什么用呢?
getDedaredField Method 获得被阻止的文件访问权。
setAccessible(true) method是设置字段是友好的,这样就可以将私有字段打印在控制台了。
将属性设置为私有的是为了防止一般用户去访问这些字段,但是作为开发者我们可以通过反射去访问。
将内部的属性和方法进行封装的一个方法就是私有,然后向用户提供接口,用户通过提供的接口进行操作。

评分

参与人数 1技术分 +1 收起 理由
贠(yun)靖 + 1

查看全部评分

回复 使用道具 举报
在运行时使用反射分析对象,如果访问的是私有域或是私有方法,私有构造函数,会抛出IllegalAccessException.因为反射机制的默认行为受限于java的访问控制,然而,如果一个java程序没有受到安全管理器的控制,就可以覆盖访问控制。为了达到这个目的,需要调用Field,Method,Constructor对象的setAccessible方法,setAccessible方法是AccessibleObject类的一个方法,是Field,Method,Constructor类的公共超类。

setAccessible(true);



不要过多地使用反射:破坏类封装;效率偏低;编译器不容易帮助发现错误,在运行时才会被发现。

我使用反射,是为了写单元测试代码,对运行对象的分析,改变对象的私有域等,达到测试需要的覆盖率。

希望对你有帮助

评分

参与人数 1技术分 +1 收起 理由
贠(yun)靖 + 1

查看全部评分

回复 使用道具 举报
属性设置为private  是符合OOP的思想  利用暴力反射去获取毕竟是特别情况 我们有时候可以忽略这种情况 按照人们的正常思维去思考
举例子: 你的钱 在你的口袋的 如果不设置private 就是希望别人直接伸手去你的口袋里获取钱
暴力反射就是 类似有一个小偷在你不知道的情况下获取到了你的钱  (属于例外)
就好像 静态 static 他其实就是全局对象 不属于OOP思想里的 但是它存在 我们也用他
其实一个真正有经验的人不会去在乎什么什么标准什么什么模式 怎么做有效率 人家就会怎样做
  比如数据库设计  一定要符合三大范式 但是人家有经验的人 发现如果不符合三大范式 那会使数据库更优化 效率更好 那么人家不一定会去遵守三大范式

评分

参与人数 1技术分 +1 收起 理由
贠(yun)靖 + 1

查看全部评分

回复 使用道具 举报
通过反射,只能查到这个某个类有哪些属性,哪些方法,是查看的这个类的类型,并不是查看的一个实例,所以是查不到私有变量的值得。为了较好的封装,默认为private,也要优先考虑用private。如果需要隐藏内部逻辑,一定是private
如果是比较简单的,可以用public,譬如某一个bean得id之类的;或者是一些可以共享的譬如static得等等。。。
回复 使用道具 举报
比如以下代码,暴力访问是取消对权限的检查,但是尽量不要这样用,因为明明私有了还要访问会产生安全隐患。

public class ReflectDemo2 {

       
        private static  String person_string = "cn.itcast.c.bean.Person";
        /**
         * @param args
         * @throws Exception
         */
        public static void main(String[] args) throws Exception {

                getPrivateFieldDemo();
        }
       
        /*
         * 获取私有字段。
         */
        private static void getPrivateFieldDemo() throws Exception {
               
                Class clazz = Class.forName(person_string);
               
                Field field = clazz.getDeclaredField("age");
               
//                System.out.println(field);
               
                Object obj = clazz.newInstance();
//                取消对权限的检查。暴力访问
                field.setAccessible(true);
               
                field.set(obj,68);
               
                Object value = field.get(obj);
                System.out.println("value="+value);
        }

        public static void getPublicFieldDemo() throws Exception {
               
                Class clazz = Class.forName(person_string);
               
                Field field = clazz.getField("name");
               
                //获取字段值。但是对于非静态的字段必须要有所属的对象。
//                既然需要该类对象,就可以通过Class类中的newInstance方法来完成。该类实例的创建。
                Object obj = clazz.newInstance();
               
               
                //给指定字段赋值。
                field.set(obj,"旺财");
               
                Object value = field.get(obj);
               
                System.out.println("value="+value);
               
        }

        /*
         * 获取指定名称的字段。
         */
       

       
        /*
         * 获取指定的字节码文件中的属性。字段.
         */
        public static void getFieldsDemo() throws ClassNotFoundException {
               
//                1,获取指定名称字节码文件对象。
                Class clazz = Class.forName(person_string);
//                2,通过该字节码文件对象的方法获取字节码文件中的字段
                Field[] fields = clazz.getFields();
                fields = clazz.getDeclaredFields();
               
                for(Field field : fields){
                        System.out.println(field);
                }
        }
       

}
回复 使用道具 举报
周海诚 黑马帝 2012-4-24 18:26:46
7#
反应过来了 就是开放的对象不一样。。。
回复 使用道具 举报
学的不太好,也过来补补呵呵
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马