• java反射(易懂)


    1、反射的介绍

    (1)Reflection(反射)是被视为动态语言的关键,反射机制允许程序在执行 期 借助于ReflectionAPI取得任何类的内部信息,并能直接操作任意对象的内 部属性及方法。
    (2)加载完类之后,在堆内存的方法区中就产生了一个Class类型的对象(一个类只有一个Class对象),这个对象就包含了完整的类的结构信息。我们可以通过这个对象看到类的结构。这个对象就像一面镜子,透过这个镜子看到类的结构,所以,我们形象的称之为:反射。

    2、反射API

    2.1、获取类对应的字节码的对象(三种)

    1.调用某个类的对象的getClass()方法,即:对象.getClass();

     User user  = new User();
     Class uClass= user.getClass();
    
    • 1
    • 2
    1. 调用类的class属性类获取该类对应的Class对象,即:类名.class
    Class userClass = User.class;
    
    • 1
    1. 使用Class类中的forName()静态方法(最安全,性能最好)即:Class.forName(“类的全路径”)
    Class aClass = Class.forName("com.ref.User");
    
    • 1

    2.2、Class类的常用方法

    //返回指定类名namegClass对象
    1.static glassforName(String name)
    //返回指定类名namegClass对象
    2.Object newlnstance()
    //调用缺省构造函数,返回Class对象的一个实例
    3.getName()
    //返回此Class对象所表示的实体(类,接口,数组类或void)的名称。
    4.Class getSuperClass()
    //返回当前Class对象的父类的Class对象获取当前Class对象的接口
    5.Class[] getinterfaces()
    //返回该类的类加载器
    6.ClassLoader getClassLoader()
    //返回一个包含某些Constructor对象的数组
    7.Constructor[]getConstructors()
    //返回一个Method对象,此对象的形参类型为paramType
    8.Method getMothed(String name,Class.. T)
    //返回Field对象的一个数组
    9.Field[] getDeclaredFields()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    2.3、哪些类型可以有class对象

    1.class:外部类,成员(成员内部类,静态内部类),局部内部类,匿名内部类。
    2.interface:接口
    3. [ ]:数组
    4. enum:枚举
    5. annotation:注解 @interface
    6. primitive type:基本数据类型
    7. void

            Class c1 = Object.class; //类
            Class c2 = Comparator.class; //接口
            Class c3 = String[].class; //数组
            Class c4 = int[][].class; //二维数组
            Class c5 = Override.class; //注解
            Class c6 = ElementType.class; //枚举
            Class c7 = Integer.class; //基本数据类型
            Class c8 = void.class; //void
            Class c9 = Class.class; //Class
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    运行结果

    class java.lang.Object
    interface java.util.Comparator
    class [Ljava.lang.String;
    class [[I
    interface java.lang.Override
    class java.lang.annotation.ElementType
    class java.lang.Integer
    void
    class java.lang.Class
    
    Process finished with exit code 0
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    3、反射在类的应用

    3.1、创建类对象

    package com.ref;
    
    import lombok.AllArgsConstructor;
    import lombok.Data;
    import lombok.NoArgsConstructor;
    
    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    public class User {
        private String name;
        private Integer id;
        //普通方法
        public void say(){
            System.out.println("卷起来,伙计们");
        }
        public void play(){
            System.out.println("玩起来,伙计们");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    3.2、获取class对象

      //通过包名获取class对象
      Class<?> aClass = Class.forName("com.ref.User");
      //通过class类获取class对象
      Class<User> userClass = User.class;
      //通过User类的对象获取class对象
      Class<? extends User> aClass1 = new User().getClass();
      //返回值为true 验证了一个类只有一个class对象
      System.out.println(aClass.hashCode()==userClass.hashCode());
      //打印的是User类对应的字节码对象
      System.out.println(aClass);//class com.ref.User
      //获取User类对应的字节码对象userClass的名字
      System.out.println(userClass.getName());//com.ref.User
      //通过User类对应的字节码对象,获取User类的类名
      System.out.println(aClass.getSimpleName());//User
      //通过User类对应的字节码对象,获取User类对应的包对象
      System.out.println(aClass.getPackage());//package com.ref
      //通过User类对应的字节码对象,先获取User类对应的包对象,再获取这个包对象的名字
      System.out.println(aClass.getPackage().getName());//com.ref
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    3.3、获取类的属性并设置属性值

        Class c1 = User.class;
            Field[] fields = c1.getFields();//获取public的属性值
            for(Field field:fields){
                //属性都是private修饰 输出为null
                System.out.println(field);
            }
            fields = c1.getDeclaredFields();
            for(Field field:fields){
                //输出: private java.lang.String com.ref.User.name
                //     private java.lang.Integer com.ref.User.id
                System.out.println(field);
            }
           Field name = c1.getDeclaredField("name");
    //不能直接操作因为是**私有属性**,我们需要关闭程序的安全检测,属性或者方法的setAccessible(true) .
            name.setAccessible(true);
            name.set(user,"神仙");
            //输出:神仙
            System.out.println(user.getName());     
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    3.4、调用普通方法

     Class c1 = User.class;
     //通过反射调用普通方法
     User user =(User)c1.newInstance();
     //通过反射获取一个方法
     Method setName = c1.getDeclaredMethod("setName", String.class);
     //invoke :激活的意思
     //(对象名,"方法的值")
     setName.invoke(user,"大学生");
      //输出:大学生
     System.out.println(user.getName());
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    4、创建对象的5种方式

    new关键字

     User user = new User();
    
    • 1

    Class.newInstance方法

    //通过反射获取类对象
    Class<User> userClass = User.class;
    //通过类对象创建
     User user = userClass.newInstance();
    
    • 1
    • 2
    • 3
    • 4

    Constructor.newInstance方法

     Class<User> userClass = User.class;
     //通过构造器创建对象
     Constructor<User> declaredConstructor =  userClass.getDeclaredConstructor();
    User user = declaredConstructor.newInstance("张三", 20);
    
    • 1
    • 2
    • 3
    • 4

    Clone方法

    无论何时我们调用一个对象的clone方法,JVM就会创建一个新的对象,将前面的对象的内容全部拷贝进去,用clone方法创建对象并不会调用任何构造函数。 要使用clone方法,我们必须先实现Cloneable接口并复写Object的clone方法。

    public class User implements Cloneable {
        private String name;
        private Integer id;
        @Override
        public User clone() throws CloneNotSupportedException {
            return (User) super.clone();
        }
        public static void main(String[] args) throws CloneNotSupportedException {
            User user = new User();
            Object clone = user.clone();
            //false
            System.out.println(clone == user);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    反序列化

    1、通过序列化,将对象的状态写在流里面:
    先构造一个对象流ObjectOutputStream oss,使用oos的writeObject的方法将实例对象user1的状态写到流(字节流文件user1.ser)里面。
    2、根据需要把该流读取出来重新构造一个相同的对象:
    先构造一个对象流ObjectInputStream ois读取字节流文件user1.ser,使用ois的readObject的方法重新构造一个相同的对象user1。

    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    public class User implements Serializable {
        private String name;
        private Integer id;
        public static void main(String[] args) throws IOException, ClassNotFoundException {
            ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("user1.ser"));
            User user1 = new User("张三",10);
            oos.writeObject(user1);
            oos.close();
            ObjectInputStream ois = new ObjectInputStream(new FileInputStream("user1.ser"));
            User user2 = (User) ois.readObject();
            System.out.println("user2"+user2);
            ois.close();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    在这里插入图片描述

  • 相关阅读:
    Springboot整合RokectMQ
    【踩坑专栏】多模块项目boot模块启动后web模块404
    案例分享:Qt激光加工焊接设备信息化软件研发(西门子PLC,mysql数据库,用户权限控制,界面设计,参数定制,播放器,二维图,期限控制,参数调试等)
    机器学习之分类回归模型(决策数、随机森林)
    垃圾回收 -标记清除算法
    字符串的API
    哥德尔奖得主Cynthia Dwork:实现算法公平性,长路漫漫
    go语言中的协程和Java中线程以及进程的区别
    Springboot整合Shiro+JWT实现认证授权
    轻量封装WebGPU渲染系统示例<21>- 3D呈现元胞自动机之生命游戏(源码)
  • 原文地址:https://blog.csdn.net/m0_59879385/article/details/127809440