第一节Class一、概述:1、Class是Java程序中各个Java类的总称;它是反射的基石,通过Class类来使用反射。
2、Class和class的区别1)class:Java中的类用于描述一类事物的共性,该类事物有什么属性,没有什么属性,至于这个属性的值是什么,则由此类的实例对象确定,,不同的实例对象有不同的属性值。
2)Class:指的是Java程序中的各个Java类是属于同一类事物,都是Java程序的类,这些类称为Class。
例如人对应的是Person类,Java类对应的就是Class。
3、属性:类名,类的访问属性,类所属包名,字段名称列表,方法名称列表等。
二、对象的创建和使用:1、创建实例对象:不可用new Class()的方式,因为Class没有这样的构造方法。
而是将字节码对象赋值给Class变量。
如Class c1 = Person.class。
如Person类,它的字节码:首先要将Person的java文件编译为class文件放于硬盘上,即为二进制代码,再将这些代码加载到内存中,接着用它创建一个个对象。
就是把类的字节码加载进内存中,再用此字节码创建一个个对象。
当有如Person、Math、Date等等的类,那么这些字节码就是分别的一个Class对象。
即Class c2 = Date.class;。
2、获得类的字节码对象:如Class.forName(”ng.String”)即获得String.class。
得到这个字节码对象有两种情况:1)此类已经加载进内存:若要得到此类字节码,不需要再加载。
2)此类还未加载进内存:类加载器加载此类后,将字节码缓存起来,forName()方法返回加载进来的字节码。
3、得到各字节码对应的实例对象(Class类型)的方式:1)类名.class:如System.class,String.class等等2)对象.class:如new Date().getClass()或者d.getClass()。
(Date d = new Date())3)Class.forName(“类名”):如Class.forName(”ng.String”)当获取类名的时候,是不知道此类的名称的,forName(字符串参数)方法中传入字符串型的变量作为对外访问的入口,即传入什么类名就获得什么类名,从而得知相应的类名。
注:forName()是静态方法,是反射中使用的一种方式获取字节码的实例对象。
每个类的字节码对象只有唯一的一个,如任何字符串对象,对应唯一的String.clas字节码。
4、九个预定义的Class:1)包括八种基本类型(byte、short、int、long、float、double、char、boolean)的字节码对象和一种返回值为void类型的void.class。
2)Integer.TYPE是Integer类的一个常量,它代表此包装类型包装的基本类型的字节码,所以和int.class是相等的。
基本数据类型的字节码都可以用与之对应的包装类中的TYPE常量表示数组类型的Class实例对象,可以用Class.isArray()方法判断是否为数组类型的。
5、总结:只要是在源程序中出现的类型都有各自的Class实例对象,如int[].class、void.class 等。
三、方法:1、static Class forName(String className)---> 返回与给定字符串名的类或接口的相关联的Class对象。
2、Class getClass()---> 返回的是Object运行时的类,即返回Class对象即字节码对象3、Constructor getConstructor()---> 返回Constructor对象,它反映此Class对象所表示的类的指定公共构造方法。
4、Field getField(String name)---> 返回一个Field对象,它表示此Class对象所代表的类或接口的指定公共成员字段。
5、Field[] getFields()---> 返回包含某些Field对象的数组,表示所代表类中的成员字段。
6、Method getMethod(String name,Class… parameterTypes)---> 返回一个Method对象,它表示的是此Class对象所代表的类的指定公共成员方法。
7、Method[] getMehtods()返回一个包含某些Method对象的数组,是所代表的的类中的公共成员方法。
8、String getName()---> 以String形式返回此Class对象所表示的实体名称。
9、String getSuperclass()---> 返回此Class所表示的类的超类的名称10、boolean isArray()---> 判定此Class对象是否表示一个数组11、boolean isPrimitive()---> 判断指定的Class对象是否是一个基本类型。
12、T newInstance()---> 创建此Class对象所表示的类的一个新实例。
示例:public static void fuction()throws Exception{String str1 = "abc";Class cls1 = str1.getClass();Class cls2 = String.class;Class cls3 = Class.forName("ng.String");System.out.println(cls1 == cls2);//trueSystem.out.println(cls1 == cls3);//true//判断是否为基本类型:isPrimitive()System.out.println(cls1.isPrimitive());//falseSystem.out.println(int.class == Integer.class);//false//Integer.TYPE代表包装类对应的基本数据类型的字节码System.out.println(int.class == Integer.TYPE);//trueSystem.out.println(int[].class.isPrimitive());//false//判断是否为数组类型的System.out.println(int[].class.isArray());//true}第二节反射1、概述:把Java类中的各种成分映射成相应的Java类。
如Class中的每一个方法返回的都是一种类(型),即Method对所有方法抽取成了这个类Method,它的每一个对象(如变量methodObj1)代表了一个方法。
2、一个类中的组成成分:成员变量、方法、构造函数、包等信息,也用一个个java类来表示(如汽车是一个类,其中的发动机,变速箱等也是对应的一个个类),表示Java类的Class类显然要提供一系列的方法来获取其中的变量、方法、构造函数、修饰符、包等信息,这些信息就是用相应的类的实例对象来表示,他们是Field、Method、Contructor、Package等。
3、一个类中的每个成员都可用相应的反射API类的一个实例对象来表示,通过调用Class 类的方法可得到这些实例对象。
第三节反射中的各种类一、Constructor类1、概述:Constructor代表某个类的构造方法2、获取构造方法:1)如何得到摸个类的所有构造方法:如得到String类的所有构造方法Constructor[] cons = Class.forName(“ng.String”).getConstructors();2)获取某一个构造方法:Constructor con = String.class.getConstructor(StringBuffer.class);①3、创建实例对象:1)通常方式:String str = new String(new StringBuffer (”abc”));2)反射方式:String str = (String)con.newInstance(new StringBuffer(“abc”));②调用获得的方法时要用到上面相同类型的实例对象,即两个StringBuffer()要对应相等。
NewInstance():构造出一个实例对象,每调用一次就构造一个对象。
注意:上面的两个地方①②都要用到StringBuffer,这必须是一致的。
第①个是指定要带StringBuffer参数类型的构造方法,即所需使用的是含StringBuffer类型的构造方法。
第②个是用这个构造方法创建对象,要传入的参数类型是StringBuffer。
4、Class.newInstance():创建一个对象,不带参数的构造方法。
演示://new String(new StringBuffer("abc"));Constructor constructor1 =String.class.getConstructor(StringBuffer.class);String str2 =(String)constructor1.newInstance(new StringBuffer("abc"));System.out.println(str2);//Class.newInstrance创建不带参数的构造方法String str3 =(String)Class.forName("ng.String").newInstance();System.out.println("str3:"+str3);二、Field类1、概述:Field类代表成员变量(字段)的反射。
示例:public class ReflectPoint {private int x;public int y;public String toString(){return str1+";" + str2 + ";" + str3;}}public class FieldTest(){ReflectPoint pt1 = new ReflectPoint(3,5);//fieldX和fieldY并不是对象身上的变量,而是类上的//要用它去取某个对象上的对应的值,传入什么对象,就取相应对象的值。
Field fieldY = pt1.getClass().getField("y");System.out.println(fieldY.get(pt1));//获取私有的成员变量Field fieldX = pt1.getClass().getDeclaredField("x");fieldX.setAccessible(true);System.out.println(fieldX.get(pt1));}2、获取成员变量:如上例子所示:1)获取公有的成员变量:getField(String name)和get(变量)2)获取私有的成员变量:暴力反射getDeclared(String name)setAccessible(boolean b),将b设为true即可get(变量)//替换字符private 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类1、概述:Method类代表某个类中的一个成员方法。