neu java实训之 反射总结

一. 反射是什么?

对于任意一个类,知道一个类的字节码文件, 就能够知道这个类的属性和方法,就能够调用它的任意一个方法和属性。

二. 反射怎么用?

比如我要获取类Student的各个属性。

1. 首先获取Class对象,有三种方式:

1.1. 使用Object类中getClass方法(不常用, 因为都已经有对象了)

Student stu1 = new Student();
Class stuClass = stu1.getClass();

1.2. 任何数据类型(包括基本数类型)都有一个"静态"的class属性
(需要导入类的包,依赖性强,不导包就会报错)

Class stuClass = Student.class;

1.3. 通过Class类的静态方法: forName(String className)(常用)

Class stuClass3 = Class.forName("com.neu.Student");

2. 通过调用Class方法实现反射

  1. 获取构造器并调用
    1 public Constructor[] getConstructors():所有"公有的"构造方法
    2 public Constructor[] getDeclaredConstructors():获取所有的构造方法(包括私有、受保护、默认、公有)
    3 public Constructor getConstructor(Class… parameterTypes): 获取单个的"公有的"构造方法:
    4 public Constructor getDeclaredConstructor(Class… parameterTypes):获取"某个构造方法"可以是私有的,或受保护、默认、公有;
    5 Constructor–>newInstance(Object… initargs) 调用constructor生成实例对象, 用Object接受

  2. 获取成员变量并更改:
    1 Field[ ] getFields(): 获取所有的"共有字段", 批量
    2 Field[ ] getDeclaredFields(): 获取所有字段, 包括私有、受保护、默认、共有,批量
    3 public Field getField(String fieldName): 获取某个"共有的"字段
    4 public Field getDeclaredField(String fieldName): 获取某个字段(可以私有)
    5 Field --> public void set(Object obj,Object value): 1. obj:要设置的字段所在对象; 2. value:要为字段设置的值;

  3. 获取成员方法并调用
    1 public Method[] getMethods():获取所有"公有方法";(包含了父类的方法也包含Object类)
    2 public Method[] getDeclaredMethods():获取所有的成员方法,包括私有的(不包括继承的)
    3 public Method getMethod(String name,Class<?>… parameterTypes):参数: 1. name方法名 2.Class … : 形参的Class类型对象
    4 public Method getDeclaredMethod(String name,Class<?>… parameterTypes)
    5 Method --> public Object invoke(Object obj,Object… args):参数:obj: 要调用方法的对象 args: 调用方法时所传递的实参

调用static的方法时, 用null做Object的实参

实训时讲师的代码如下:

    public static void main(String[] args) throws Exception {
        //ActionClass action = getActionClass();

        //什么是反射?
        //反射是 分析类 的程序。
        /*获得操作对象有3种方式:
            1. 类名.class
            2. Class.forName("类路径")
            3. 对象.getClass()
        */
        /*System.out.println(Main.class.getName());
        System.out.println(Class.forName("a.b.c.d.e.Main"));
        System.out.println(new Main().getClass());*/
        //获得操作对象
        /*Class<Main> c1 = Main.class;
        Class c2 = Class.forName("a.b.c.d.e.Main");
        Class c3 = new Main().getClass();*/

        //利用反射分析 My类
        Class<My> clazz = My.class;
        System.out.print(Modifier.toString(clazz.getModifiers()) + " ");
        System.out.print(clazz.getName() +" ");//类路径
        System.out.println(" extends " + clazz.getGenericSuperclass().getTypeName());//父类
       // System.out.println(clazz.getGenericInterfaces().length);//所有接口



        //获取my类的所有属性
        Field[] fields = clazz.getDeclaredFields();
        for(Field f : fields){
            System.out.print(Modifier.toString(f.getModifiers()) +" ");
            System.out.print(f.getType().getName() +" ");
            System.out.println(f.getName());
        }

        //获取构造方法
        Constructor[] cons = clazz.getDeclaredConstructors();
        for(Constructor c : cons){
            System.out.println(c.getParameterCount());
            Class[] params = c.getParameterTypes();
            for(Class p : params){
                System.out.print(p + " ");
            }
        }

        System.out.println();
        //实例方法
        Method[] methods = clazz.getMethods();
        for(Method m : methods){
            System.out.print(m.getReturnType() + " ");
            System.out.print(m.getName() + "( ");
            Class[] types = m.getParameterTypes();
            for(Class t : types){
                System.out.print(t.getTypeName() + " ");
            }
            System.out.println(" ) ");
        }

    }
       public static void main(String[] args) throws Exception {
        //ActionClass action = getActionClass();

        //什么是反射?
        //反射是 分析类 的程序。
        /*获得操作对象有3种方式:
            1. 类名.class
            2. Class.forName("类路径")
            3. 对象.getClass()
        */
        /*System.out.println(Main.class.getName());
        System.out.println(Class.forName("a.b.c.d.e.Main"));
        System.out.println(new Main().getClass());*/
        //获得操作对象
        /*Class<Main> c1 = Main.class;
        Class c2 = Class.forName("a.b.c.d.e.Main");
        Class c3 = new Main().getClass();*/

        //利用反射分析 My类
        /*Class<My> clazz = My.class;
        System.out.print(Modifier.toString(clazz.getModifiers()) + " ");
        System.out.print(clazz.getName() +" ");//类路径
        System.out.println(" extends " + clazz.getGenericSuperclass().getTypeName());//父类
       // System.out.println(clazz.getGenericInterfaces().length);//所有接口



        //获取my类的所有属性
        Field[] fields = clazz.getDeclaredFields();
        for(Field f : fields){
            System.out.print(Modifier.toString(f.getModifiers()) +" ");
            System.out.print(f.getType().getName() +" ");
            System.out.println(f.getName());
        }

        //获取构造方法
        Constructor[] cons = clazz.getDeclaredConstructors();
        for(Constructor c : cons){
            System.out.println(c.getParameterCount());
            Class[] params = c.getParameterTypes();
            for(Class p : params){
                System.out.print(p + " ");
            }
        }

        System.out.println();
        //实例方法
        Method[] methods = clazz.getMethods();
        for(Method m : methods){
            System.out.print(m.getReturnType() + " ");
            System.out.print(m.getName() + "( ");
            Class[] types = m.getParameterTypes();
            for(Class t : types){
                System.out.print(t.getTypeName() + " ");
            }
            System.out.println(" ) ");
        }*/


        Class<My> clazz = My.class;
        //获取无参构造
        Constructor<My> c = clazz.getDeclaredConstructor(null);
        //构造方法的作用: 1.实例化对象 2.属性赋值
        //创建对象(利用反射创建 My类的对象)
        My my = c.newInstance(null);
        System.out.println(my);
        System.out.println(my.getId());
        System.out.println(my.getName());

        //构造2
        /*c = clazz.getDeclaredConstructor(int.class,String.class);
        my = c.newInstance(100,"zyw");
        System.out.println(my.getId());
        System.out.println(my.getName());*/


        //反射调实例方法
        Method m1 = clazz.getMethod("setId", int.class);
        //实例方法 必须对象调用
        //invoke(对象,参数值列表)
        m1.invoke(my, 123);
        m1 = clazz.getMethod("getId", null);
        Object result = m1.invoke(my, null);
        System.out.println(result);

        //调用静态方法
        m1 = clazz.getMethod("test");
        //null 表示不用传对象
        m1.invoke(null);
    }
  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值