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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© j420984 中级黑马   /  2015-6-22 19:38  /  285 人查看  /  1 人回复  /   1 人收藏 转载请遵从CC协议 禁止商业使用本文

看了一半吧,累了,只写了这么多.纯手码.
一.        反射的基础.
a)        反射的基石:Class类
i.        java程序中的各个Java类属于同一类事物,描述这类事物的Java类名就是Class.
ii.        对此提问:众多的人用一个什么类表示:Person
iii.        对此提问:Person类代表人,它的实例对象就是张三,李四这样一个个具体的对象,Class类代表Java类,它的各个实例对象又分别对应什么了
1.        对应各个类在内存中的字节码,例如Person类的字节码,ArrayList类的字节码.
2.        一个类被类加载器加载到内存中,占用一片存储空间,这个空间里面的内容就是类的字节码,不同的类的字节码是不同的,所以它们在内存中的内容是不同的,这一个个的空间可分别用一个个的对象来表示,这些对象显然具有相同的类型,这个类型是什么了
iv.        如何得到各个字节码对应的实例对象(Class类型)
1.        类名.class;如:System.class
2.        对象.getClass();如:new Date().getName();
3.        Class.forName(“类名”)如Class.forName(“java.util.Date”);
v.        九个预定义Class实例对象:
1.        参看Class.isPrimitive方法的帮助
2.        Int.class==Integer.TYPE
3.        8个基本的类型对应了八个Class对象,void也对应了一个Class对象
4.        数组也是一种类型:数组类型的Class实例对象
a)        Class isArray()
b)        总之,只要是源程序中出现的类型,都有各自的Class实例对象,例如:int][];void;
b)        反射就是把Java类中的各种成分映射成相应的Java类,例如,一个java类中用一个Class类的对象来表示,一个类中的组成部分:成员变量,方法,构造方法,包等等信息也用一个个的JAVA类来表示,就像汽车是一个类,汽车中的发动机,变速箱等等也是一个个的类;表示java类的Class类显然要提供一系列的方法,来获得其中的变量,方法,构造方法,修饰符,包等信息,这些信息就是用相应类的实例对象来表示,它们是Field,Method,Contructor,Package等等.
c)        一个类中的每个成员都可以用相应的反射API类的一个实例对象来表示,通过调用Class类的方法可以得到这些实例对象后,得到这些实例对象后有什么用呢,怎么用了,这正是学习和应用反射的要点.
二.        Constructor类
a)        Constructor类代表某个类中的一个构造方法
b)        得到某个类所有的构造方法:
i.        例子:Constructor[] constructor  = Class.forName (“java.lang.String).getConstructor(StringBuffer.class);
ii.        程序开发分为编译时和开发时.编译器只看变量的定义,不看代码的执行.
iii.        得到某一个构造方法:
1.        Constructor constructor = Class.forName(“java.lang.String”).getConstruntor(StringBuffer(“abc”));//调用获得的方法时要用到上面相同类型的实例对象.
iv.        创建实例对象:
1.        通常方式:String str = new String(new         StringBuffer(“abc”));
2.        反射方法:String str = (String)constructor.newinstance(new StringBuffer(“abc”));//调用获得的方法时要用到上面相同类型的实例对象.
v.        Class.newInstance()方法:
1.        例子:String obj = (String)Class.forName(“java.lang.String”).newInstance();
2.        该方法内部先得到默认的构造方法,然后用该构造方法创建实例对象.
3.        该方法内部的具体代码是怎么样写的了,用到了缓存机制来保存默认构造方法的实例对象.
三.        Field类
a)        Field类代表某介盆地辊的一个成员变量,
b)        演示用eclipse自动生成java类的构造方法.
c)        问题:得到的Field对象是对应到类上面的成员变量,还是对应到对象上的成员变量;类只有一个,而该类的实例对象有多个,如果是与对象关联,那关联的是哪个对象了,所以字段fieldX代表的是X的定义,而不是具体的x(具体的对象)变量
d)        示例代码
ReflectPoint pt1 = new ReflectPoint(3,5);
Field fieldy = pt1.getClass().getField(“y”);
e)        功能需求:将任间一个对象中的所有String类型的成员变量所对应的字符串内容中的b改成a

package com.jwd.black.ReflectPoint;

import java.lang.reflect.Field;

public class ReflectTest {
        public static void main(String[] args) throws Exception{
                ReflectPoint pt1 = new ReflectPoint(3,5);
                Field fieldy = pt1.getClass().getField("y");

                changeString(pt1);
                System.out.print(pt1);
        }
        private static void changeString(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);
                        }
                }
        }
}

package com.jwd.black.ReflectPoint;

public class ReflectPoint {
        private int x;
        public int y;
        public String str1 = "ball";
        public String str2 = "basketball";
        public String str3 = "itcast";

        ReflectPoint(int x, int y) {
                this.x = x;
                this.y = y;
        }

        public String toString() {
                return str1 + ";" + str2 + ";" + str3 + ";";
        }
}

f)        总结:获得一个对象,换掉里面字段的内容.
四.        Method类:成员方法的反射
a)        Method类代表某个类中的一个成员方法
b)        得到类中的某一个方法
i.        例子:Method charAt = Class.forName(“java.lang.String”).getMethod(“charAt”,int.class);
ii.        调用方法
1.        通常方式:System.out.printIn(str.charAt(1));
2.        反射方式:System.out.printIn(charAt.invoke(str,1);
3.        如果传递给Method对象的invoke()方法的一个参数为null,这有着什么样的意义了,说明该Method对象对应的是一个静态方法
c)        对接收数组参数的成员方法进行反射,用反射方式执行某个类中的main()方法
i.        目标:写一个程序,这个程序能够根据用户提供的类名,去执行该类中的main方法
ii.        问题:启动Java程序的main方法的参数是一个字符串数组,即public static void main(String[] args),通过反射方式来调用这个main方法时,如何为invoke方法传递参数了在给main方法传递参数时,不能使用代码mainMethod.invoke(null,new String[]{“xxx”};
iii.        解决办法:
mainMethod.invoke(null,new  Object[]{new String[]{“xxx”}});
mainMethod.invoke(null,( Object)new String[]{“xxx”});编译器会作特殊处理,编译时不把参数当作数组看待,也就不会数组打散成若干参数了.

       

1 个回复

倒序浏览
写的不错!收藏了!
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马