反射
首先新建一个用于测试反射机制的类Student类,包含public,static的属性,构造器和方法:
Student.java
1 package cn.ftf.reflex;
2 /*
3 用于测试类的类
4 */
5 public class Student {
6 private String name;
7 int age;
8 public String address;
9 public Student() {
10 super();
11 }
12 private Student(String name) {
13 super();
14 this.name = name;
15 }
16 Student(String name, int age) {
17 super();
18 this.name = name;
19 this.age = age;
20 }
21 public Student(String name, int age, String address) {
22 super();
23 this.name = name;
24 this.age = age;
25 this.address = address;
26 }
27 private void function() {
28 System.out.println("function");
29 }
30 public void method1() {
31 System.out.println("mathed");
32 }
33 public void method2(String s) {
34 System.out.println("methed "+s);
35 }
36 public String method3(String s,int age) {
37 return s+"-->"+age;
38 }
39 public String toString() {
40 return "name: "+name+" age: "+age+" address:"+address;
41 }
42 }
获取类的Class对象的方式:
1 package cn.ftf.reflex;
2 /*
3 * 获取类的Class对象的方式
4 */
5 public class ReflectDemo {
6 public static void main(String[] args) {
7 String path="cn.ftf.reflex.Student";
8 //使用类的class属性来得到类的class对象
9 Class<Student> c1=Student.class;
10 System.out.println(c1);
11 Class c6=int.class;
12
13 Class<Student> c2=Student.class;
14 System.out.println(c1=c2);
15
16 //调用对象的getclass()方法
17 Student s=new Student();
18 Class<? extends Student> c3=s.getClass();
19 int arrs[]=new int[10];
20 arrs.getClass();
21
22 //使用class类中的静态方法forName(String className)
23 try {
24 Class c5=Class.forName(path);
25 } catch (ClassNotFoundException e) {
26 // TODO Auto-generated catch block
27 e.printStackTrace();
28 }
29
30 }
31
32 }
获取对象的构造方法进而构造对象:
1 package cn.ftf.reflex;
2
3 import java.lang.reflect.Constructor;
4
5 /*
6 * 反射获取构造方法
7 */
8 public class ReflelctDemo01 {
9 public static void main(String[] args) throws ClassNotFoundException, Exception, SecurityException {
10 String path="cn.ftf.reflex.Student";
11 Class<?> c=Class.forName(path); //得到字节码文件对象c
12 //由字节码文件对象得到构造方法
13 Constructor<?>[]cons=c.getConstructors(); //getConstructor()只能拿到公共的构造方法
14 Constructor<?>[]cons1=c.getDeclaredConstructors(); //可以拿到所有的构造方法
15 Constructor<?>c1= c.getDeclaredConstructor(); //括号内参数:是你要获取的构造方法的参数的个数和数据类型哦对应的字节码文件对象,没有参数表示午无参的构造方法
16 Object o=c1.newInstance();//由构造方法创建对象
17 System.out.println(o); //根据重写的toString()方法查看类的信息
18 for(Constructor<?> con:cons) {
19 System.out.println(con);
20 }
21 for(Constructor<?> con:cons1) {
22 System.out.println(con);
23 }
24
25
26 //通过带参数的构造方法创建对象
27 Class cc=Class.forName(path);
28 Constructor<?> conss=cc.getConstructor(String.class,int.class,String.class);
29 Object obj=conss.newInstance("房廷飞",20,"郑州");
30 System.out.println(obj);
31
32 //暴力反射
33 //私有的构造方法虽然可以被获取但是不能直接创建对象,需要暴力创建取消访问检查,即暴力反射
34 Constructor<?> consss=cc.getDeclaredConstructor(String.class);
35 consss.setAccessible(true); //取消构造器的访问检查
36 Object obj2=consss.newInstance("房廷飞");
37 System.out.println(obj2);
38
39 }
40
41 }
获取成员变量,调用空构造器再给成员变量赋值
1 package cn.ftf.reflex;
2
3 import java.lang.reflect.Constructor;
4 import java.lang.reflect.Field;
5
6 /*
7 * 获取成员变量,和获取构造方法大同小异
8 */
9 public class ReflectDemo02 {
10 public static void main(String[] args) throws Exception {
11 String path="cn.ftf.reflex.Student";
12 Class c=Class.forName(path);
13 Field[] fields=c.getFields(); //获取可以公共访问的成员变量
14 Field[] fields1=c.getDeclaredFields(); //获取所有的
15 for(Field field:fields1) {
16 System.out.println(field);
17 }
18
19 //给成员变量赋值
20 Field field=c.getField("address"); //获取单个的
21 Field field2=c.getDeclaredField("name");
22 field2.setAccessible(true); //同样私有方法取消访问检查
23 Field field3=c.getDeclaredField("age");
24
25 Constructor<?> con=c.getConstructor(); //获取无参的构造方法创建对象
26 Object o=con.newInstance();
27
28 field.set(o, "郑州");
29 field2.set(o, "房廷飞");
30 field3.set(o, 20);
31 System.out.println(o);
32
33 }
34
35 }
获取成员方法,调用成员方法:
1 package cn.ftf.reflex;
2
3 import java.lang.reflect.Constructor;
4 import java.lang.reflect.Method;
5
6 /*
7 * 获取成员方法,大同小异
8 */
9 public class ReflectDemo03 {
10 public static void main(String[] args) throws Exception {
11 String path="cn.ftf.reflex.Student";
12 Class c=Class.forName(path);
13 Method[] methods=c.getMethods(); //所用的公共方法,包括继承的类的
14 Method[] methods1=c.getDeclaredMethods(); //本类所有的方法,不包括继承的
15 for(Method method:methods1) {
16 System.out.println(method);
17 }
18 Method method=c.getDeclaredMethod("function"); //获取指定方法,私有的
19 method.setAccessible(true);
20 Method method1=c.getMethod("method1"); //获取指定方法无参数,五返回值
21 Method method2=c.getMethod("method2",String.class); //获取指定方法,带参数
22 Method method3=c.getMethod("method3",String.class,int.class); //获取指定方法,带参数和返回值
23 Constructor<?> con=c.getConstructor();
24 Object obj=con.newInstance();
25 method.invoke(obj);
26 method2.invoke(obj, "hahaha");
27 Object oo=method3.invoke(obj, "房廷飞",20); //带返回值的方法,.invoke()方法返回的是对象,可查api
28 System.out.println(oo);
29
30 }
31
32 }
应用练习---跳过泛型约束,向带Integer泛型的ArrayList中添加字符串:
1 package cn.ftf.reflex;
2 /*
3 * 练习:向带Integer泛型的ArrayList中添加字符串
4 * 泛型可以越过泛型检查,获取原始方法所需要的参数类型,添加原始类型
5 */
6 import java.lang.reflect.Method;
7 import java.util.ArrayList;
8
9 public class ReflectTest01 {
10 public static void main(String[] args) throws Exception {
11 ArrayList<Integer> arrs=new ArrayList<Integer>();
12 arrs.add(10);
13 arrs.add(20);
14 arrs.add(30);
15 Class c=arrs.getClass();
16 Method method=c.getMethod("add",Object.class);
17 method.invoke(arrs, "hello");
18 method.invoke(arrs, "Java");
19 System.out.println(arrs);
20 }
21
22 }

浙公网安备 33010602011771号