1. 反射的基石-àClass类
a) Java程序中的各个java类属于同一类事物,描述这类java类的就是Class。众多的java类用Class类来表示。
b) Class.forName 的作用:加载字节码,如果虚拟机有字节码则直接加载,如果没有则新加载到虚拟机、方便以后调用字节码。
c) 获得字节码对应的对象方法:
l 类名.Class 例如:System.Class
l 对象.Class --à newData().getClass();
l Class.forName(“类名”); ---àClass.forName(“java.util.date”);
l 例如:
Stringstr1 = "abc";
Class cls1 = str1.getClass();
Class cls2 = String.class;
l Class cls3 =Class.forName("java.lang.String");
2. 反射的定义:反射就是把java类中的各种成分映射到java 类中。例如一个类中的方法,变量,构造方法等等也是一个个的java类来表示的。
3. Constructor类:代表某个类中的一个构造方法。
a) 得到某个类中所有的构造方法:
l Construction[]Constructions = Class.forName(“java.lang.String”).getConstructions();
b) 得到某一个构造方法:
l Construction[]Construction = Class.forName(“java.lang.String”).getConstructions(StingBuffer.class);
c) 创建实例化对象:
l 常用方式:
1. String str = newString(new StringBuffer(“abc”));
l 反射方式:String str =(String) Construction.newInstance(new StrigBuffer(“abc”)); //StringBuffer调用获得方法时要用到上面相同类型的实例化对象。
l Class.newInstace();方法
1. 例子:String obj =(String)Class.forName().newInstance();//该方法内部先得到默认的构造方法,不带参数的构造方法,然后用构造方法创建实例对象。.
d) Field类:代表某个类中的一个成员变量。
ReflectPoints pt1=new ReflectPoints(5,3);
l FieldfiledY=pt1.getClass().getField("y");//需要抛出异常、取
l System.out.println(filedY.get(pt1)); //输出为3.不是5,因为每个对象身上都有fieldY,它不代表一个具体的值,只代表变量,不是对象身上的值,而是类上,要用它去取某个对应的值
l Field filedY=pt1.getClass().getField("x");//当变量X为私有时,为不可见,改成getDeclaredField就可以了。
l fieldX setAccessible(true);//此处标记为可访问私有变量
l System.out.println(filedX.get(pt1));//X可见却不能使用,办法:如上解决办法
4. Method类:代表某个类中的一个成员方法
a) 获得了中的某一个方法:
l Method methodChatAt=String.class.getMethod("CharAt", int.class);
b) 调用方法:反射方式:
l System.out.println(methodChatAt.invoke(str1,1));
1. //如果传递给Method对象的Invoke()方法的第一个参数为null,即str为null,说明该Method调用的对象对应的是一个静态方法
5. 练习:用反射方式去执行某个类中的方法:
a) 目标:写一个程序,该程序能够根据用户的类名去执行该类中的main方法,用反射方式调用。
b) 问题:启动java程序的main方法的参数是一个字符串数组,用反射方式调用这个main方法时,jdk1.5是把整个数组打包当做是一个参数传递,而jdk1.4会把数组打散为若干个单独的参数,1.5是包含1.4的。所以在传递时不能使用mainMethod.invoke(null,newString[]{“xxx”},会被java当成1.4语法进行理解。所以会出现参数类型不对。
c) 解决:mainMethod.invoke(null,newObject[]{new String[]{“xxx”}});
l 也可以:mainMethod.invoke(null,(Object)newString[]{“xxx”});
6. 数组的反射:具有相同数组和元素类型的数组属于同一个类型,即具有相同的Class实例对象。
a) 代表数组的Clas实例对象的getSuperClass()的方法返回的父类为Object类对应的Class。
b) 基本数据类型的一维数组可以被当作Object类型使用,不能当作Object[]类型使用:非基本类型的一维数组面积可以当做Object类型使用,还可以当做Object[]类型使用。
c) Arrays.asList();可以转换String[]类型成List,不能转换int[]
d) Java中有内存泄露吗?
l 有,当某个对象的不使用的时候,没有被释放,一直暂用空间,这就叫内存泄露。
7. 反射的作用:实现框架功能
a) getRealPath();得到文件在硬盘上的绝对路径