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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© ゞSunペ果果つ 中级黑马   /  2013-5-3 10:14  /  1449 人查看  /  4 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

  1. package demo;
  2. import java.lang.reflect.*;
  3. public class Demo1 {
  4.         public static void main(String[] args) throws Exception{
  5.                 Point p=new Point();
  6.                 System.out.println(p);
  7.                 changeb(p);
  8.                 System.out.println(p);
  9.                 System.out.println(p.s1);
  10.         }
  11. public static void changeb(Object obj)throws Exception{
  12.         Field []fields=obj.getClass().getFields();
  13.         for(Field field:fields){
  14.                 if(field.getType()==String.class){
  15.                         String s=(String)field.get(obj);
  16.                         s=s.replace('b', 'x');
  17.                         field.set(obj, s);
  18.                 }
  19.         }
  20. }
  21. }
  22. class Point{
  23.         public String s1="aaabbbccc";
  24.         public String s2="box";
  25.         public String s3="testbox";
  26.        
  27.         public String toString(){
  28.                 return "1"+s1+"2"+s2+"3"+s3;
  29.         }
  30. }
复制代码
这段代码的功能是将Point类中的字符串中的‘b’字符替换成x。
我也实现了这个功能了,我是再想,通过反射我们改变了类文件中的数据,
它的java文件是没有改变的,这个没有质疑,是不是编译后的.class文件也没有改变那?
如果.clss文件没有改变,也就是说,这里的代码实际操作的是加载的虚拟机的.class文件
那么当我们退出的时候,如果可以查看它编译时的,class文件。里面的内容是不是应该没有发生改变那?

评分

参与人数 1技术分 +1 收起 理由
田磊阳 + 1

查看全部评分

4 个回复

倒序浏览
应该是没有变的
1,类加载器将类的class文件读入内存,并为之创建一个java.lang.Class对象,而系统中所有的类,它们实际上也是对象,称为类对象,它们都是java.lang.Class的实例,虚拟机为每种类型管理一个独一无二的Class对象,也就是说,每个类(型)都有一个Class对象。
2,类的初始化
使用反射方式来强制创建某个类或接口对应的java.lang.Class对象。
3,缓存机制
通过反射查看类信息
a) 使用Class类的forName()静态方法.该方法需要传入字符串参数,该字符串参数的值是某个类的全限定类名(必须添加完整包名)。
b) 调用某个类的class属性来获取该类对应的Class对象。
c) 调用某个对象的getClass()方法,该方法是java.lang.Object类中的一个方法,所以所有java对象都可以调用该方法,该方法将会返回该对象所属类对应的Class对象。
使用反射生成并操作对象,访问属性值。
其实你一直操作的是一个类(型)对像其实和我们操作new的对象本质上是没有区别的!



评分

参与人数 1技术分 +1 收起 理由
田磊阳 + 1

查看全部评分

回复 使用道具 举报
我觉得应该是由于Java在编译源文件的时候,只是检查语法错误,创建对象和加载.class文件并没有执行,它们只在jvm开启后才会在内存中创建,因此你所操作的内容都是内存里面东西,当jvm退出后释放内存,你所更改的值也随之消失了。而原来的.class文件在你硬盘上面并没有受到影响。除非你可以加一步将更改后的值重新存到硬盘上,应该就可以了。这和IO流中用BufferedWriter 往硬盘里写数据,只有flush了或close了才可以将缓冲区的内容写进去应该类似。
回复 使用道具 举报
harborbest 发表于 2013-5-3 11:22
应该是没有变的
1,类加载器将类的class文件读入内存,并为之创建一个java.lang.Class对象,而系统中所有的类 ...

谢谢了,回答很精辟
回复 使用道具 举报
赵崇友 发表于 2013-5-3 13:13
我觉得应该是由于Java在编译源文件的时候,只是检查语法错误,创建对象和加载.class文件并没有执行,它们只 ...

嗯嗯,我也是这样想的,就是拿出来看看自己的想法是不是正确
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马