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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 小罴孩 中级黑马   /  2013-8-1 22:37  /  1510 人查看  /  0 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

在看张老师的视屏之前,每每遇到反射,我只想说“它妈的:Q”,但是现在我会说“亲爱的:D”
反射的基石—>Class类
把一些具有相同属性和行为的对象抽象出来成为一个类,类与对象的关系是抽象与具体,共性与个性的关系,类是描述抽象的概念,对象是类的一个具体实例。

查看JDK-API文档
Class 类的实例表示正在运行的 Java 应用程序中的类和接口。枚举是一种类,注释是一种接口。每个数组属于被映射为 Class 对象的一个类,所有具有相同元素类型和维数的数组都共享该 Class 对象。基本的 Java 类型(boolean、byte、char、short、int、long、float 和 double)和关键字 void 也表示为 Class 对象。
Class 没有公共构造方法。Class 对象是在加载类时由 Java 虚拟机以及通过调用类加载器中的 defineClass 方法自动构造的。

每一个类在内存中都是一段字节码,每一段字节码是一个具体的对象,是某一个类型
Constructor代表类的构造方法
反射到底是什么东西?
        反射就是把java类中的各成分映射成相应的java类……………………………………………...冯伟立
Constructor类代表某个类中的一个构造方法
可以得到某个类的所有构造方法:
        Constructor[] constructors = Class.forName(“java.lang.String”).getConstructors();
可以得到某一个构造方法:
        Constructor constructor = Class.forName(“java.lang.String”).getConstructor(StringBuffer.class);
        //获得方法时要用到类型
可以创建一个实例对象:
        通常方式:String str = new String(new StringBuffer(“abc”));
        反射方式:String str = (String)constructor.newInstance(new StringBuffer(“abc”));
        //调用获得时的方法时要用到上面相同类型的实例
Class.newInstance()方法:
        例子:String obj = (String)Class.forName(“java.lang.String”).newInstance();
        该方法内部先得到默认的构造方法,让后用该构造方法创建实例对象。
        该方法内部的具体代码到底是什么样的呢?用到了缓存机制来保存默认构造方法的实例对象。




Field类代表某一个类中的一个成员变量(一个字段)
用eclipse自动生成Java类的构造方法
字段的反射:
public class ReflectPoint {
        private int x;
        public int y;
        public ReflectPoint(int x, int y) {
                super();
                this.x = x;
                this.y = y;
        }
}

import java.lang.*;
import java.lang.reflect.Field;
public class ReflectTest {
        public static void main(String[] args) throws Exception {
                ReflectPoint pt1 = new ReflectPoint(2, 3);
                Field fieldY = pt1.getClass().getField("y");
                System.out.println(fieldY.get(pt1));
               
                Field fieldX = pt1.getClass().getDeclaredField("x");
                //暴力方式设置私有变量x为可读取的!
                fieldX.setAccessible(true);
                System.out.println(fieldX.get(pt1));
        }
}
问题来了:得到的Field对象fieldX与fieldY是对应到类上面的成员变量,还是对应到对象上的成员变量?类只有一个,对象可以有多个,假设与对象关联(即得到的Field对象是fieldX与fieldY是类的某一个具体实例),那么关联的是哪个对象呢?所以字段fieldX代表的是ReflectPoint类中的x的定义,而不是某一对象具体的值。
练习:将任意一个对象中的所有String类型的成员变量所对应的字符串内容中的”b”改成”a”。
public static void changeStringValue(Object obj) throws Exception{
                Field[] fields = obj.getClass().getFields();
                for(Field field:fields){
                        if(field.getType() == String.class){
                                String oldValue = (String)field.get(obj);
                                String newValue = oldValue.replace('b', 'a');
                                field.set(obj, newValue);
                        }
                }
}
Method类代表类里面的一个成员方法(字节码里面的方法,而不是一个对象身上的方法)
得到类中的某一个方法:
        Method charAt = Class.forName(“java.lang.String”).getMethod(“charAt”,int.class);
用反射来得到一个方法,从String这个字节码身上拿来的
已知String str = “abc”,下面用反射来实现str.charAt(1);
        Method methodCharAt = String.class.getMethod(String name,Class<?>…parameterTypes)
//invoke(Object obj,Object…args)对带有指定参数(1)的指定对象(str)调用由此 Method 对//象表示的底层方法
        System.out.println(methodCharAt.invoke(str,1));
        如果传递给Method对象的invoke方法的第一个参数为null,这又有什么意义呢?这说明了该Method对象对应的是一个静态方法(这句怎么理解? 静态方法调用时不需要对象!)
        得到输出结果是:b
专家模式:谁拥有这个数据,谁就能干这件事(比如:人关门这件事,关门这个动作只属于门的,人只是负责发出关的命令;再比如:火车司机刹车,司机不可能把火车停下来对吧!司机只是发出信号,刹车动作本身是属于火车的)

评分

参与人数 1技术分 +1 收起 理由
神之梦 + 1 淡定

查看全部评分

0 个回复

您需要登录后才可以回帖 登录 | 加入黑马