------- <a href="http://www.itheima.com" target="blank">android培训</a>、<a href="http://www.itheima.com" target="blank">java培训</a>、期待与您交流! ----------
反射:就是加载类,并解剖出类的各个组成成分
作用:做框架使用的
要加载类先要得到要加载的类
Class类代表某个类的字节码
1、获取class类的方法有三种:
1:先获取对象 通过对象的getclass方法 person p=new person() p.getclass
2:class cls =String.class
3:使用class的forName()方法 Class.forName("")// 一定是类的完整名称
两种方式 如果有直接使用没有先创建
String s = "abcd";
Class c1 = s.getClass();
Class c2 = String.class;
Class c3 = Class.forName("java.lang.String");
System.out.println(c1 == c2); true
System.out.println(c1 == c3); true
isPrimitive() 判定一个class类型是否是基本类型
methord 方法中的invoke(null,变量),如果第一个参数是null那么这个方法是静态方法
2、Class对象的常用方法
Constructor
(1、)获得公有的无参构造方法
// 首先获得无参的构造函数
Constructor constructor = clazz.getConstructor(null);
// 使用无参的构造函数创建一个实例对象
constructor.newInstance(null);
(2、)获得公有的带参构造方法
// 首先获得无参的构造函数
Constructor constructor = clazz.getConstructor(String.class);
// 使用无参的构造函数创建一个实例对象
constructor.newInstance("wangxiaoer");
(3、)获得私有的构造方法
// 首先获得有参的私有构造函数
Constructor constructor = clazz.getDeclaredConstructor(int.class);
// 将访问权限打开,暴力访问
constructor.setAccessible(true);
// 使用无参的构造函数创建一个实例对象
Object cn = constructor.newInstance(123);
(4、)
/* 无参的构造函数创建对象也可以直接使用newinstance方法 */
// 获得类的字节码
Class clazz = Person.class;
// 创建类的实例
clazz.newInstance();
Method
(1、)调用无参的公用的方法
// 获得字节码文件
Class clazz = Class.forName("cn.dream.data.Person");
// 获得person类的无参的run方法
Method method=clazz.getMethod("run", null);
//调用获得的method方法 第一个参数为 调用这个方法的对象 第二个参数为 给这个方法传递的参数
method.invoke(p, null);
(2、)调用带参的公用的方法
Person p = new Person();
// 获得字节码文件
Class clazz = Class.forName("cn.dream.data.Person");
// 获得person类的含参的eat方法 第一个参数为调用的的方法 第二个参数为方法的参类型
Method method=clazz.getMethod("eat", String.class);
//调用获得的method方法 第一个参数为 调用这个方法的对象 第二个参数为 给这个方法传递的参数
method.invoke(p, "猪肉");
(3、)调用含参的私用的方法
Person p = new Person();
// 获得字节码文件
Class clazz = Class.forName("cn.dream.data.Person");
// 获得person类的含参的私有的show方法 第一个参数为调用的的方法 第二个参数为方法的参类型
Method method=clazz.getDeclaredMethod("show", String.class);
//打开访文权限
method.setAccessible(true);
//调用获得的method方法 第一个参数为 调用这个方法的对象 第二个参数为 给这个方法传递的参数
method.invoke(p, "xiaosan");
(4、)调用含参的静态方法
// 获得字节码文件
Class clazz = Class.forName("cn.dream.data.Person");
// 获得person类的含参的静态方法song 第一个参数为调用的的方法 第二个参数为方法的参类型
Method method = clazz.getMethod("song", String.class);
// 调用获得的method方法 第一个参数为 调用这个方法的对象 第二个参数为 给这个方法传递的参数
method.invoke(null, "xiaosan");
(5、)调用main方法
// 获得字节码文件
Class clazz = Class.forName("cn.dream.data.Person");
// 获得person类的含参的静态方法song 第一个参数为调用的的方法 第二个参数为方法的参类型
Method method = clazz.getMethod("main", String[].class);
// 调用获得的method方法 第一个参数为 调用这个方法的对象 第二个参数为 给这个方法传递的参数
// 静态方法不需要对象,所以第一个参数为空
// 此时第二参数为可变参数,为了兼容1.5之前的版本,会将数组拆开为几个参数,但是main方法传递到就是一个数组,
// 所以在将数组放到一个object的数组中区
method.invoke(null, new Object[] { new String[] { "aa", "bb" } });
Field 字段
(1、)公用的字段
创建一个对象
Person p = new Person();
// 获得字节码文件
Class clazz = Class.forName("cn.dream.data.Person");
// 获得person类的name字段
Field f = clazz.getField("name");
// 调用获得的那个对象的字段 p是某个对象
String name = (String) f.get(p);
// 获得得到字段的类型
Class type = f.getType();
// 更改字段的值 第一个参数为那个对象 第二个参数为更改的值
f.set(p, "fhgjk");
(2、)私有字段
Person p = new Person();
// 获得字节码文件
Class clazz = Class.forName("cn.dream.data.Person");
// 获得person类的name字段
Field f = clazz.getDeclaredField("age");
f.setAccessible(true);
// 调用获得的那个对象的字段 p是某个对象
int age= (int) f.get(p);
System.out.println(age);
(3、)获得静态字段的值
Person p = new Person();
// 获得字节码文件
Class clazz = Class.forName("cn.dream.data.Person");
// 获得person类的password字段
Field f = clazz.getField("password");
// 修改公用字段的值
f.set(null, 32);
// 调用获得的那个对象的字段 p是某个对象
//静态方法不需要对象。可以传一个空NULL
int passsword = (int) f.get(null);
f.set(null, 32);
System.out.println(passsword);