Java进阶 学习 day1 : 反射机制

1.反射是什么

程序中的反射指程序运行状态中,

1、对于给定的一个类(Class)对象,可以获得这个类(Class)对象的所有属性和方法;

2、对于给定的一个对象(new XXXClassName<? extends Object>),都能够调用它的任意一

个属性和方法。

这种动态获取类的内容以及动态调用对象的方法和获取属性的机制,就叫做Java反射机制

2.反射有什么用

直接new User()不就可以了,为什么要用这种反射写法?

实例化一个User()对象,不使用反射,如果想再实例化其他对象比如new Person(),那么

就需要修改源代码,并重新编译。使用反射后就不需要修改源代码只需要灵活改动类描述就

可以了,不需要重新再编译。 如下代码所示

//类描述,可根据需要实例化的描述而改动
    String className = "com.tledu.pojo.User";
    //使用反射中API创建对象
    Class.forName(className).newInstance();

反射的优缺点:

优点:

        增加程序的灵活性,避免固有逻辑写死到程序中

        代码相对简洁,可以提高程序的复用性

缺点:

        相比于直接调用反射有比较大的性能销毁

        内部暴露和安全隐患

3.反射怎么用

3.1        获取类对象的三种方式

//获取类对象的三种方式
Class<User> clazz1 = User.class;
Class<?> clazz2 = Class.forName("com.tledu.mjw.User");
Class<? extends User> clazz3 = new User().getClass();

3.2        类中属性的获取

一些方法

        System.out.println("包名:"+clazz.getPackage());
        System.out.println(clazz.getName()); //com.tledu.pojo.User 全类名
        System.out.println("类名:"+clazz.getSimpleName());
        //getFields():可以获取本类及父类中的所有公共的属性
        Field[] fields = clazz.getFields();
        for (Field field : fields) {
       //     System.out.println(field.getName());
        }
        //getDeclaredFields():获取本类中的所有的属性
        Field[] declaredFields = clazz.getDeclaredFields();
        for (Field declaredField : declaredFields) {
       //     System.out.println(Modifier.toString(declaredField.getModifiers()) +"              "+declaredField.getType().getSimpleName()+"  "+declaredField.getName());
        }

        //获取指定的公共的属性对象
        Field field = clazz.getField("age");
        //System.out.println(Modifier.toString(field.getModifiers()) +"  "+field.getType().getSimpleName()+"  "+field.getName());

        //获取父类
        Class<? super User> superclass = clazz.getSuperclass();
        //System.out.println(superclass.getSimpleName());

        //获取类加载器
        //System.out.println(clazz.getClassLoader());

3.3        类中方法的获取

        //getMethods() 获取本类及父类中的公共的方法
        Method[] methods = clazz.getMethods();
        for (Method method : methods) {
       //     System.out.println(method.getName());
        }

        //获取本类中的所有的方法
        Method[] declaredMethods = clazz.getDeclaredMethods();
        for (Method declaredMethod : declaredMethods) {
         //   System.out.println(Modifier.toString(declaredMethod.getModifiers())+"  "+declaredMethod.getReturnType().getSimpleName()+"  "+declaredMethod.getName()+" "+ Arrays.toString(declaredMethod.getParameterTypes()));
        }

        //获取某个方法通过反射的方式调用执行
        Method method = clazz.getMethod("eat", String.class, Integer.class);
        //invoke用来调用方法的,第一个参数表示要执行的方法所属对象,后面的可变参数表示该执行方法的传入值
        method.invoke(user,"西瓜",3);

        //私有方法的调用
        Method method2 = clazz.getDeclaredMethod("run");
        //开启对私有方法的访问权限
        method2.setAccessible(true);
        method2.invoke(user);

3.4        类中构造方法的获取

        Class clazz = User.class;
         //获取构造器对象
        Constructor constructor = clazz.getConstructor();
        //System.out.println(constructor.getName());

        //Constructor[] constructors = clazz.getConstructors(); 获取本类中的公共构造
        Constructor[] constructors = clazz.getDeclaredConstructors(); //获取本类中所有的构造
        for (Constructor constructor1 : constructors) {
         //   System.out.println(Arrays.toString(constructor1.getParameterTypes()));
        }

        //创建一个User对象 通过构造
        Constructor constructor1 = clazz.getDeclaredConstructor(String.class, String.class);
        constructor1.setAccessible(true);
        User o = (User)constructor1.newInstance("tom", "boy");
        System.out.println(o);

3.5        利用反射创建对象

        Class<User> clazz = User.class;
        Class<? extends User> aClass = new User().getClass();
        Class clazz2 = Class.forName("com.tledu.pojo.User");

        //需求:
        //   创建出对象


//        new User();
//        new Person();
//        new Grade();
//        new Student();
//        new ......

        String clazzName = "Person";
        String str = "com.tledu.pojo."+clazzName;
        Class.forName(str).newInstance();

3.6        反射破局单例

利用反射创建出来的对象,不会遵从单例模式下只返回同一个对象的情况

正常的创建对象情况下,单例模式返回的为同一个对象
//        Apple apple = Apple.getInstance();
//        Apple apple2 = Apple.getInstance();
//
//        System.out.println(apple);
//        System.out.println(apple2);
//反射破局单例
Class clazz = Apple.class;
Constructor declaredConstructor = clazz.getDeclaredConstructor();
//给该方法权限
declaredConstructor.setAccessible(true);
System.out.println(declaredConstructor.newInstance());
System.out.println(declaredConstructor.newInstance());

3.7        反射的其他用法

反射常用来封装工具类或者在框架的底层实现

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值