反射
获取Class对象的三种方式
1.通过对象获取字节码文件对象
Student stu=new Student();
Class c1=stu.getClass();
2.通过类名获取字节码文件对象
Class c2=Student.class;
3.通过class类中的forname("完整的包名+类名")
Class c3=Class.forName("com.oracle.demo02.Student");
通过反射获取构造方法
获取所有构造方法:getDeclaredConstructors()
获取所有公共构造方法: getConstructors()
获取私有有参构造方法:getDeclaredConstructor(String.class)
需要暴力反射:setAccessible(true)
例:
Class c=Class.forName("com.oracle.demo02.Student"); //获取私有有参构造方法 Constructor con=c.getDeclaredConstructor(String.class); //创建对象 //暴力反射 //不允许,不提倡暴力反射 con.setAccessible(true); Student stu=(Student) con.newInstance("小红"); System.out.println(stu);
获取公共有参构造方法:getConstructor(String.class,int.class)
通过反射获取成员变量
获取公共成员变量对象(一个):getField("age");
一般步骤为:
1 // 获取字节码文件对象 2 Class c=Class.forName("com.oracle.demo02.Student"); 3 //获取公共成员变量对象 4 Field f=c.getField("age"); 5 //快速根据字节码文件对象创建对象 6 Object obj= c.newInstance(); 7 //给age成员变量赋值 8 f.set(obj, 18); 9 System.out.println(f.get(obj));
获取公共成员变量对象(多个):getDeclaredFields()
通过反射获取成员方法
获取公共有参方法对象一般方法:getMethod("sleep", String.class)
1.获取字节码文件对象
2.获取公共有参方法对象、
3.快速创建对象
4.调用方法
例:
1 //获取字节码文件对象 2 Class c=Class.forName("com.oracle.demo02.Student"); 3 //获取公共有参方法对象 4 Method method=c.getMethod("sleep", String.class); 5 //快速创建对象 6 Object obj=c.newInstance(); 7 //调用方法 8 method.invoke(obj, "小红");
运行如图所示:
反射擦除
程序编译后产生的.class文件中是没有泛型约束的,这种现象我们称为泛型的擦除。我们可以通过反射技术,来完成向有泛型约束的集合中,添加任意类型的元素。
例:定义一个整型集合,通过反射可以存入字符串。
1 ArrayList<Integer> list = new ArrayList<Integer>(); 2 //添加元素到集合 3 list.add(new Integer(30)); 4 list.add(new Integer("12345")); 5 list.add(123); 6 //list.add("哈哈");//因为有泛型类型的约束 7 System.out.println(list); 8 //通过反射技术,实现添加任意类型的元素 9 //1, 获取字节码文件对象 10 Class c = Class.forName("java.util.ArrayList"); 11 12 //2, 找到add()方法 13 Method addMethod = c.getMethod("add", Object.class); 14 //3, 执行add()方法 15 addMethod.invoke(list, "哈哈");// list.add("哈哈"); 16 System.out.println(list);