反射
1. 什么是反射: 所有反射中用到的类都在这个包中:java.lang.reflect
通过加载某个类,在内存中生成类的对象,我们可以对类中的结构进行操作。
这些结构包括:构造方法、属性、方法等
1) 类: Class (在内存中生成的字节码对象)
2) 构造方法: Constructor
3) 属性: Field
4) 方法: Method
2. 反射在实际开发中的应用:
1) 用于开发IDE,如:eclipse、netbean
2) 用于框架的开发:Struts、Hibernate等
3) 用于一些小工具的开发
Class类:
1. 类的加载:
源代码 (编译) --> 字节码(类加载器) --> 类对象
2. 得到Class对象的三种方式: 无论使用上面哪种方式加载类对象,始终得到同一个类对象。第三种方式耦合性最低
1) 类名.class 可以得到一个类对象
如:Class c1 = Employee.class;
2) 通过对象getClass()方法得到类对象
Employee emp = new Employee();
Class c2 = emp.getClass();
3) 通过Class中静态方法
Class.forName("类全名");
3. Class类中的方法:
1) getName() 得到类的全名
2) getSimpleName() 得到类的简单名,没有包名
Constructor构造方法的类
1. 作用: 代表一个类对象中的构造方法
2. 得到Constructor类的方法:
1) Class类中的方法:得到一个构造方法
getConstructor(Class... 变量类型) 只能得到公共的构造方法
getDeclaredConstructor(Class...变量类型) 得到声明的构造方法,无论什么修饰符
得到多个构造方法
Constructor[] getConstructors() 得到所有公共构造方法
Constructor[] getDeclaredConstructors() 得到所有声明的构造方法
2) 实例化对象的方法:
a. 通过构造方法创建对象:
得到构造方法以后,可以对类进行实例化。
Object newInstance(Object...对象),返回一个已经实例化好的对象
b.Class创建对象:只能是无参构造
Class对象.newInstance();
c. 暴力反射:
setAccessible(true)
3. 基本类型与引用类型类对象
在反射中int.class和Integer.class是两种不同的类型
4. Declared的规律:
如果一个方法上有Declared这个单词,则表示可以得到所有声明的对象。如果没有这个单词,则只能得到public类型的对象
Method方法类
得到一个指定的方法
公有的方法: clazz.getMethod(方法名, Class...方法的参数类型); 方法有重载
声明的方法: clazz.getDeclaredMethod(方法名, Class...方法的参数类型);
得到所有方法
所有公有的方法: Method[] clazz.getMethods();
所有声明的方法: Method[] clazz.getDeclaredMethods();
Method类的方法:
方法对象.invoke(实例对象, 方法参数);
调用实例方法1 调用实例方法 2 Employee emp = new Employee(); 3 m1.invoke(emp,"西瓜"); 4 5 调用静态方法 6 m3.invoke(null, 12); 可以使用对象,也可以不使用对象,指定为null
代码1 public static void main(String[] args) throws Exception { 2 //1.得到类对象 3 Class clazz = Class.forName("com.itheima.b.Employee"); 4 //实例化对象 5 Constructor c1 = clazz.getConstructor(); 6 Object obj = c1.newInstance(); 7 //2. 得到方法对象 8 Method m1 = clazz.getMethod("eat", String.class); 9 System.out.println(m1); 10 //3. 调用方法 11 m1.invoke(obj, "西瓜"); 12 13 //得到声明的方法 14 Method m2 = clazz.getDeclaredMethod("work", int.class); 15 System.out.println(m2); 16 //暴力反射 17 m2.setAccessible(true); 18 //调用私有的方法 19 m2.invoke(obj, 8); 20 21 //得到静态方法 22 Method m3 = clazz.getDeclaredMethod("sleep", int.class); 23 System.out.println(m3); 24 //调用静态方法 25 m3.invoke(null, 12); 26 27 System.out.println("==============="); 28 //得到所有的方法 29 //Method[] methods = clazz.getMethods(); 30 Method[] methods = clazz.getDeclaredMethods(); 31 for (Method method : methods) { 32 System.out.println(method); 33 } 34 } 35
Field属性类
得到指定的字段(对象)
clazz.getField(属性名);
获取所有公有字段
clazz.getFields();
获取所有声明的字段
clazz.getDeclaredFields();
给属性赋值
基本属性赋值: setInt(), setDouble() . . . .
引用属性赋值: set(obj, value) (引用属性就是String这些)
代码1 public static void main(String[] args) throws Exception { 2 //1.得到类对象 3 Class clazz = Class.forName("com.itheima.b.Employee"); 4 //实例化对象 5 Object obj = clazz.newInstance(); //使用默认的构造方法实例化对象 6 //2.得到其中的一个属性 7 Field f1 = clazz.getField("name"); 8 System.out.println(f1); 9 //3. 属性:获取它的值,设置它的值 10 //给引用类型赋值 11 f1.set(obj, "孙悟空"); 12 System.out.println(obj); 13 //得到年龄 14 Field f2 = clazz.getDeclaredField("age"); 15 System.out.println(f2); 16 //暴力反射 17 f2.setAccessible(true); 18 //赋值 19 f2.setInt(obj, 500); 20 System.out.println(obj); 21 System.out.println("============="); 22 //得到所有公共的属性 23 //Field[] fields = clazz.getFields(); 24 Field[] fields = clazz.getDeclaredFields(); 25 for (Field field : fields) { 26 System.out.println("变量名:" + field.getName() + "\t变量类型:" + field.getType()); 27 } 28 }


浙公网安备 33010602011771号