锁定老帖子 主题:利用反射获取与修改private的属性的值
精华帖 (0) :: 良好帖 (0) :: 新手帖 (1) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2012-11-16
可以看到PrivateObject 里有一个private 的属性String型的 privateString 没有为其实义getter,setter方法。 package org.iteye.bbjava.runtimeinformation; import java.lang.reflect.Field; public class PrivateObject { private String privateString = null; public PrivateObject(String privateString) { this.privateString = privateString; } } 2.Test.java 这里将对PrivateObject类进行反射取值,是一种“暴力操作”,相信经常逛论坛的同学们,应该听过这个词。 还可以“暴力修改”。 package org.iteye.bbjava.runtimeinformation; import java.lang.reflect.Field; public class Test { public static void main(String []args) throws IllegalArgumentException, IllegalAccessException, SecurityException, NoSuchFieldException{ PrivateObject privateObject = new PrivateObject("The Private Value"); Field privateStringField = PrivateObject.class. getDeclaredField("privateString"); privateStringField.setAccessible(true); String fieldValue = (String) privateStringField.get(privateObject); System.out.println("fieldValue = " + fieldValue); } } 3.console infomaction: 引用 fieldValue = The Private Value
4.接下来将对Test.java进行修改,以对“暴力修改”是如何做到的进行说明。 对比上面的Test.java这里多了8行代码,这就是“暴力修改”的关键。 其中 privateStringField.setAccessible(true); 就是对private 属性修改的“权限开关”,当设置为true时,可以修改,为false时会抛出异常,动行时信息将会给出该异常. package org.iteye.bbjava.runtimeinformation; import java.lang.reflect.Field; public class Test { public static void main(String []args) throws IllegalArgumentException, IllegalAccessException, SecurityException, NoSuchFieldException{ PrivateObject privateObject = new PrivateObject("The Private Value"); Field privateStringField = PrivateObject.class. getDeclaredField("privateString"); privateStringField.setAccessible(true); String fieldValue = (String) privateStringField.get(privateObject); System.out.println("fieldValue = " + fieldValue); privateStringField.setAccessible(true); privateStringField.set(privateObject, "As you see,privateString's value is changed!"); String fieldValue1 = (String) privateStringField.get(privateObject); System.out.println("fieldValue = " + fieldValue1); privateStringField.setAccessible(false); privateStringField.set(privateObject, "As you see,privateString's value is changed!"); String fieldValue2 = (String) privateStringField.get(privateObject); System.out.println("fieldValue = " + fieldValue2); } } 5.console infomaction: 引用 fieldValue = The Private Value
fieldValue = As you see,privateString 'value is changed! Exception in thread "main" java.lang.IllegalAccessException: Class org.iteye.bbjava.runtimeinformation.Test can not access a member of class org.iteye.bbjava.runtimeinformation.PrivateObject with modifiers "private" at sun.reflect.Reflection.ensureMemberAccess(Reflection.java:65) at java.lang.reflect.Field.doSecurityCheck(Field.java:960) at java.lang.reflect.Field.getFieldAccessor(Field.java:896) at java.lang.reflect.Field.set(Field.java:657) at org.iteye.bbjava.runtimeinformation.Test.main(Test.java:25) 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2012-11-16
修改final类型的值才有意思
|
|
返回顶楼 | |
发表时间:2012-11-17
freish 写道 修改final类型的值才有意思
那就失去final存在的意义了。 撸主例子不错阿。我在Java编程思想上看来,不过那例子木有撸主的好。支持。。。 |
|
返回顶楼 | |
发表时间:2012-11-17
ifox 写道 freish 写道 修改final类型的值才有意思
那就失去final存在的意义了。 撸主例子不错阿。我在Java编程思想上看来,不过那例子木有撸主的好。支持。。。 private本来就是不给外部直接访问的,这样搞不也失去private的意义了 |
|
返回顶楼 | |
发表时间:2012-11-18
写过一个类,可以递归打印AppClassLoader加载的类的所有属性。有空贴上来
|
|
返回顶楼 | |
发表时间:2012-11-19
freish 写道 ifox 写道 freish 写道 修改final类型的值才有意思
那就失去final存在的意义了。 撸主例子不错阿。我在Java编程思想上看来,不过那例子木有撸主的好。支持。。。 private本来就是不给外部直接访问的,这样搞不也失去private的意义了 既然有这个api,说明sun有考虑让你打破规则不是么? |
|
返回顶楼 | |
发表时间:2012-11-19
freish 写道 ifox 写道 freish 写道 修改final类型的值才有意思
那就失去final存在的意义了。 撸主例子不错阿。我在Java编程思想上看来,不过那例子木有撸主的好。支持。。。 private本来就是不给外部直接访问的,这样搞不也失去private的意义了 这一般用于debug吧,不过总归是破坏封装的。 但是final修饰的变量就不通了,final变量放在栈中,跟普通变量根本无法互相转换。 |
|
返回顶楼 | |
发表时间:2012-11-19
if(i!=我){} 写道 写过一个类,可以递归打印AppClassLoader加载的类的所有属性。有空贴上来
package com.cccode.object; import java.lang.reflect.Field; import java.util.Date; /** * * @author YDSoft-15 * @author if(i!=我){} 保留署名权 * */ public class ObjectFields { /** * @param args */ public static void main(String[] args) { ObjectFields of = new ObjectFields(); System.out.println(of.ObjectFields2String(new A())); } /** * * @param obj * @return 对象存在的属性值 */ public String ObjectFields2String(Object obj) { return ObjectFields2String(new StringBuffer(), obj, 0); } /** * * @param sb * @param obj * @param index * @return 对象存在的属性值 */ private String ObjectFields2String(StringBuffer sb, Object obj, int index) { if (obj == null) { return null; } Class<?> clas = obj.getClass();// 加载类 sb.append(clas.getName()); Field[] fields = clas.getDeclaredFields();// 获得对象属性集合 sb.append(" {"); printBlankSpace(sb, index + 1); for (int i = 0; i < fields.length; i++) { Field field = fields[i]; String fieldName = field.getName();// 得到字段名 sb.append(fieldName); sb.append("("); Class<?> fieldType = field.getType();// 得到字段类别 sb.append(fieldType.getSimpleName()); sb.append(") = "); try { field.setAccessible(true); // 设置强制访问 Object fieldValue = field.get(obj);// 得到属性值 if (fieldType.getClassLoader() != null// 不为BootstrapLoader(ExtClassLoader或AppClassLoader) && !fieldType.isInterface() // fieldType不为接口 && fieldValue != null// 排除未实例化的声明 ) { ObjectFields2String(sb, fieldValue, index + 1);// 递归 } else { sb.append(fieldValue); } } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } finally { field.setAccessible(false); } if (i != fields.length - 1) { printBlankSpace(sb, index + 1); } } printBlankSpace(sb, index); sb.append("}"); return sb.toString(); } private void printBlankSpace(StringBuffer sb, int index) { sb.append("\n"); for (int i = 0; i < index; i++) { sb.append(" "); } } } class A { String a = "String of class A"; B b = new B(); long l = 123456l; Date d = new Date(); StringBuffer sb = new StringBuffer(); java.awt.Image img = null; public A() { sb.append("StringBuffer"); } } class B { String b = "String of class B"; C c = new C(); } class C { String b = "String of class C"; } |
|
返回顶楼 | |
发表时间:2012-11-19
最后修改:2012-11-19
if(i!=我){} 写道 freish 写道 ifox 写道 freish 写道 修改final类型的值才有意思
那就失去final存在的意义了。 撸主例子不错阿。我在Java编程思想上看来,不过那例子木有撸主的好。支持。。。 private本来就是不给外部直接访问的,这样搞不也失去private的意义了 这一般用于debug吧,不过总归是破坏封装的。 但是final修饰的变量就不通了,final变量放在栈中,跟普通变量根本无法互相转换。 恕我直言,这句话反映出你还没搞清楚堆、栈、java堆、java栈的区别以及用途 |
|
返回顶楼 | |
发表时间:2012-11-19
freish 写道 if(i!=我){} 写道 freish 写道 ifox 写道 freish 写道 修改final类型的值才有意思
那就失去final存在的意义了。 撸主例子不错阿。我在Java编程思想上看来,不过那例子木有撸主的好。支持。。。 private本来就是不给外部直接访问的,这样搞不也失去private的意义了 这一般用于debug吧,不过总归是破坏封装的。 但是final修饰的变量就不通了,final变量放在栈中,跟普通变量根本无法互相转换。 恕我直言,这句话反映出你还没搞清楚堆、栈、java堆、java栈的区别以及用途 那烦请您老人家指点一二? |
|
返回顶楼 | |