黑马程序员技术交流社区
标题:
(以解决)关于暴力反射的和私有成员问题
[打印本页]
作者:
周海诚
时间:
2012-4-24 16:20
标题:
(以解决)关于暴力反射的和私有成员问题
本帖最后由 周海诚 于 2012-4-24 19:47 编辑
回答了这么多,自己的问题也很多,一个个解决。阿门
反射中getDeclaredField(变量名)方法和setAccessible(ture)方法可以强行取出对象中的私有变量,
那把属性设为private还有什么用呢?
作者:
王杰
时间:
2012-4-24 16:32
反射中getDeclaredField(变量名)方法和setAccessible(ture)方法可以强行取出对象中的私有变量,
那把属性设为private还有什么用呢?
getDedaredField Method 获得被阻止的文件访问权。
setAccessible(true) method是设置字段是友好的,这样就可以将私有字段打印在控制台了。
将属性设置为私有的是为了防止一般用户去访问这些字段,但是作为开发者我们可以通过反射去访问。
将内部的属性和方法进行封装的一个方法就是私有,然后向用户提供接口,用户通过提供的接口进行操作。
作者:
毕博
时间:
2012-4-24 16:35
在运行时使用反射分析对象,如果访问的是私有域或是私有方法,私有构造函数,会抛出IllegalAccessException.因为反射机制的默认行为受限于java的访问控制,然而,如果一个java程序没有受到安全管理器的控制,就可以覆盖访问控制。为了达到这个目的,需要调用Field,Method,Constructor对象的setAccessible方法,setAccessible方法是AccessibleObject类的一个方法,是Field,Method,Constructor类的公共超类。
setAccessible(true);
不要过多地使用反射:破坏类封装;效率偏低;编译器不容易帮助发现错误,在运行时才会被发现。
我使用反射,是为了写单元测试代码,对运行对象的分析,改变对象的私有域等,达到测试需要的覆盖率。
希望对你有帮助
作者:
应佳锋
时间:
2012-4-24 16:37
属性设置为private 是符合OOP的思想 利用暴力反射去获取毕竟是特别情况 我们有时候可以忽略这种情况 按照人们的正常思维去思考
举例子: 你的钱 在你的口袋的 如果不设置private 就是希望别人直接伸手去你的口袋里获取钱
暴力反射就是 类似有一个小偷在你不知道的情况下获取到了你的钱 (属于例外)
就好像 静态 static 他其实就是全局对象 不属于OOP思想里的 但是它存在 我们也用他
其实一个真正有经验的人不会去在乎什么什么标准什么什么模式 怎么做有效率 人家就会怎样做
比如数据库设计 一定要符合三大范式 但是人家有经验的人 发现如果不符合三大范式 那会使数据库更优化 效率更好 那么人家不一定会去遵守三大范式
作者:
金超
时间:
2012-4-24 16:44
通过反射,只能查到这个某个类有哪些属性,哪些方法,是查看的这个类的类型,并不是查看的一个实例,所以是查不到私有变量的值得。为了较好的封装,默认为private,也要优先考虑用private。如果需要隐藏内部逻辑,一定是private
如果是比较简单的,可以用public,譬如某一个bean得id之类的;或者是一些可以共享的譬如static得等等。。。
作者:
孙天
时间:
2012-4-24 17:30
比如以下代码,暴力访问是取消对权限的检查,但是尽量不要这样用,因为明明私有了还要访问会产生安全隐患。
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
反应过来了 就是开放的对象不一样。。。
作者:
光sail
时间:
2012-4-24 18:39
学的不太好,也过来补补呵呵
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/)
黑马程序员IT技术论坛 X3.2