JAVA初涉反射

来源:互联网 发布:直播软件商业计划书 编辑:程序博客网 时间:2024/05/22 23:37

什么是反射呢?反射就是通过字节码文件对象去使用成员。那么什么是字节码文件对象呢?我们写java代码时,写的东西它的后缀是”.java”,但是当机器编译了这个文件之后,生成的文件的后缀就变成了”.class”,这个就是字节码文件,我们可以把这个文件看成一个对象,这个对象就叫字节码文件对象–对应的类Class。

获取字节码文件对象的三种方法:

  1. 通过Object类的getClass()方法;
  2. 数据类型的静态class属性;
  3. 通过Class类的静态forName()方法;

反射的步骤:

  1. 先获取字节码文件对象
  2. 去寻找对象的对应的成员对象
  3. 过该成员的对象调用方法使用

这里是一些常用的成员对象的获取方法:

1.通过反射获取构造方法    public Constructor[] getConstructors() 获取公共的构造方法    public Constructor[] getDeclaredConstructors() 获取所有的构造方法(包括私有)    public Constructor getConstructor(Class... parameterTypes) 根据构造参数获取公共的指定构造    public Constructor getDeclaredConstructor(Class<?>... parameterTypes) 根据构造参数获取指定构造(包括私有,但是私有在使用的时候需要取消访问限制)2.通过反射获取构造方法并创建对象    public T newInstance(Object... initargs)3.通过反射获取成员变量并使用    public Field[] getFields()获取公有的成员变量    public Field[] getDeclaredFields()获取全部的成员变量,包括私有    public Field getDeclaredField(String name) 传入变量名称返回指定的成员变量对象,包括私有    public Field getField(String name)传入变量名称返回指定的成员变量对象,仅可获取共有的    public void set(Object obj,Object value)给一个对象的一个字段设置一个值4.通过反射获取成员方法并使用    public Method[] getMethods()获取所有公共成员方法    public Method[] getDeclaredMethods()获取所有成员方法,包括私有    public Method getMethod(String name, Class<?>... parameterTypes)参数一:方法名 参数二:方法参数类型.class 获取指定的公共方法    public Method getDeclaredMethod(String name,Class<?>... parameterTypes)参数一:方法名 参数二:方法参数类型.class 获取指定的方法,包括私有    Object invoke(Object obj, Object... args) 让某一个对象使用这个方法,并且传入参数

总结的说一下:在这里,你要记住几个关键词:

1、与构造方法相关:Constructor   与成员变量相关:Field   与成员方法相关:Method2、如果要获取公共的:Declared3、如果要获取所有的记得在你的语句后面加上‘s’,并且此时获取到的是一个包   含了你想要的成员对象的数组4、如果是要调用单个的成员变量的话,你需要输入该变量的名称5、如果你要调用单个成员方法的话,你需要输入该方法的名称和该方法所需要的参数类型.class

代码演示:(如果你不想看这些分开的代码,在文章最后面有一个小的综合的例子 )

package com.thz_03;public class Student {    private String name;    String studyNum;    public int grade;    protected int age;    //四种构造    public Student(){        System.out.println("这是Student的public构造");    }    public Student(String name,int age,int grade){        System.out.println("这是Student的public带参构造");    }    protected Student(String name){        System.out.println("这是Student的protected构造"+name);    }    private Student(String studyNum,int grade){        System.out.println("这是Student的private构造方法"+studyNum+grade);    }    Student(int age,int grade){        System.out.println("这是Student的默认构造"+age+grade);    }    //四种方法    public void method(){        System.out.println("这是public的method方法");    }    private void method(int age){        System.out.println("这是private的method方法,参数为age"+age);    }    void method(int age,int grade){        System.out.println("这是默认的method方法,参数为age和grade"+age+","+grade);    }    protected void method(String name){        System.out.println("这是protected的method方法,参数为name"+name);    }}
package com.thz_03;import java.lang.reflect.Field;//获取Class对象的成员变量Fieldspublic class ClassFieldsDemo {    public static void main(String[] args) throws Exception {        //1、获取Class对象        //Class c = new Student().getClass();        //Class c = Student.class;        Class c = Class.forName("com.thz_03.Student");        //获取student中所有的public修饰的成员变量        Field[] f = c.getFields();        for (Field field : f) {            System.out.println(field);        }        System.out.println("------------------------");        //获得单个的public成员变量        Field f1 = c.getField("grade");        System.out.println(f1);        System.out.println("------------------------");        //获取所有的成员变量        Field[] f2 = c.getDeclaredFields();        for (Field field : f2) {            System.out.println(field);        }        System.out.println("------------------------");        //获取单个成员变量        Field f3 = c.getDeclaredField("name");        Field f4 = c.getDeclaredField("age");        Field f5 = c.getDeclaredField("studyNum");        Field f6 = c.getDeclaredField("grade");        System.out.println(f3);        System.out.println(f4);        System.out.println(f5);        System.out.println(f6);    }}
package com.thz_02;import java.lang.reflect.Constructor;//通过反射来获取构造public class ClassConstructorDemo {    public static void main(String[] args) throws Exception {        //获取公共的构造方法        //1、获取Class对象        Class c1 = Class.forName("com.thz_02.Student");        Class c2 = Student.class;        Class c3 = new Student().getClass();        //2、获取其所有的公共构造,不管带不带参,只要是用public修饰的        System.out.println("获取全部的被public修饰的构造");        Constructor[] cons = c1.getConstructors();        for (Constructor con : cons) {            System.out.println(con);        }        //获取单个的public修饰的构造        System.out.println("获取带参的被public修饰的构造");        Constructor con = c1.getConstructor(String.class,int.class,int.class);        System.out.println(con);        System.out.println("获取不带参的被public修饰的构造");        Constructor con1 = c1.getConstructor();        System.out.println(con1);        System.out.println("获取不带参的同一对象不同方法获得的Class对象的被public修饰的构造");        Constructor con2 = c2.getConstructor();        System.out.println("判断不同方法得到的Class对象的公共构造的差异");        //内容相同,但是地址值有点问题        System.out.println(con1==con2);        System.out.println(con1.equals(con2));        //获取其他构造,declared公开的,公然的        Constructor[] decon = c1.getDeclaredConstructors();        System.out.println("C1得所有构造");        for (Constructor allcon : decon) {            System.out.println(allcon);        }        //根据参数获取单个的构造        System.out.println("根据参数获取单个的构造之无参");        Constructor cons1 = c1.getDeclaredConstructor();        System.out.println(cons1);        System.out.println("根据参数获取单个的构造之String name");        Constructor cons2 = c1.getDeclaredConstructor(String.class);        System.out.println(cons2);    }}
package com.thz_04;import java.lang.reflect.Method;//获取其方法public class ClassMethodDemo {    public static void main(String[] args) throws Exception {        //创建Class对象        //Class c = new Student().getClass();        //Class c = Student.class;        Class c = Class.forName("com.thz_04.Student");        //获取其全部的public方法,包括了来自它的父类Object的public方法        Method[] m = c.getMethods();        for (Method method : m) {            System.out.println(method);        }        System.out.println("---------------------");        //调用某一个public方法c.getMethod(方法名,方法参数.class)        Method m1 = c.getMethod("wait");        System.out.println(m1);        System.out.println("---------------------");        //获取全部的方法包括私有,不包含来自父类的        Method[] dm = c.getDeclaredMethods();        for (Method method : dm) {            System.out.println(method);        }        System.out.println("---------------------");        //调用某一个方法包括私有private void method(int age){        Method m2 = c.getDeclaredMethod("method",int.class);        System.out.println(m2);    }}
package com.thz_05;import java.lang.reflect.Constructor;import java.lang.reflect.Method;import java.util.ArrayList;//2:我给你ArrayList<Integer>的一个对象,我想在这个集合中添加一个字符串数据,如何实现呢?public class ClassTest {    public static void main(String[] args) throws Exception {        //1、先创建一个ArrayList<Integer>的一个对象        ArrayList<Integer> al = new ArrayList<>();        //2、获取它的Class对象        Class c = al.getClass();        //3、获取它的add方法,参数是泛型,可看为Object        Method add = c.getMethod("add",Object.class);        //4、取消权限检测,使用方法        add.setAccessible(true);        add.invoke(al, "hello");        //5、检查        for (Object obj : al) {            System.out.println(obj);        }    }}
原创粉丝点击