• 07 反射 01获取class的三种方法


    1、获取Class的三种方法

    /*
            * 1、反射机制
            *   通过Java语言中反射机制可以操作字节码文件(可以读和修改字节码文件)
            *   通过反射机制可以操作代码片段(class文件)
            * 2、反射机制的相关类在哪个包下:java.lang.reflect.*
            * 3、反射机制相关的类有哪些?
            *   java.lang.Class 代表整个字节码
            *   java.lang.reflect.Method 代表字节码中方法字节码
            *   java.lang.reflect.Construct 代表字节码中的构造方法字节码
            *   java.lang.reflect.Field   代表字节码中的属性字节码,代表类中的成员变量
            *
            *
            * */
    
            /*
            * 要操作一个类的字节码,需要首先获取到这个类的字节码,怎么获取java.lang.Close实例?
            * 三种方式:
            *   第一种:Class c = Class.forName("完整类名带包名");
            *   第二种:Class c = 对象.geClass()
            *   第三种:java语言中任何一种类型,包括基本数据类型,它都有class属性,Class c = "任何类型“.class
            * Class.forName()
            * 1、静态方法
            * 2、方法的参数是一个字符串
            * 3、字符串需要的是一个完整的类名
            * 4、完整类名必须带有包名,java.lang包不能省略
            *
            * */
            Class c1 = null;  //代表String.Class类型
            Class c2 = null;
            Class c3 = null;
            try {
                c1 = Class.forName("java.lang.String");
                c2 = Class.forName("java.lang.Integer");  //代表Integer类型
               
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }
    
    
            //java中任何一个对象都有一个方法:getClass()
            String  s = "abc";
            Class x = s.getClass();  //x代表的String.class字节码文件,x代表String类型
            System.out.println(c1 == x);   //==比较的是字节码的内存地址,字节码文件装载到JVM的时候,值装载一份
            
            //java语言中任何一种类型,包括基本数据类型,它都有class属性
            Class  z = String.class;  //代表String类型
            Class f = Date.class;   //代表Date类型
            Class e = double.class;   //代表double类型
            Class r = int.class;  //代表int类型
            

    2、通过反射实例化对象

     //普通创建
            User user = new User();
            System.out.println(user);
    
            try {
                //重点:通过反射机制,获取Class,通过Class来实例化对象
                Class c = Class.forName("User");
                //会调用USer的无参构造方法,完成User的创建;
                //重点是:newInstance调用的是无参构造,必须保证无参构造是存在的
                Object obj = c.newInstance();  
                System.out.println(obj);   //User@4554617c
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (InstantiationException e) {
                e.printStackTrace();
            }

    3、反射机制的灵活性

    *
    * 获取Class,能干什么?
    * 操作字节码文件
    *  java 代码写一遍,再不改变java源代码的基础之上,可以做到不同对象的实例化
    * 非常之灵活,符合OCP原则,对修改关闭,对扩展开放
    *
    * 后期要歇息高级框架,而工作中需要使用高级框架,而高级框架都是使用反射机制,有利于学习框架底层的东西
    * */
      //这种就写死了,只能创建一个User类型的对象
            User user = new User();
    
            //一下代码是灵活的,代码不需要改动,可以修改配置文件,配置文件修改后,可以创建出不同的实例对象
            try {
                //通过IO流读取classinfo.properties文件
                FileReader fr = new FileReader("src/classinfo.properties");
                //创建属性类对象
                Properties pro = new Properties();
                //加载
                pro.load(fr);
    
                //通过key获取value
                String className = pro.getProperty("className");
    
                //通过反射机制实例化对象
                Class c1 = Class.forName(className);
                Object obj = c1.newInstance();
                System.out.println(obj);
                //关闭流
                fr.close();
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (InstantiationException e) {
                e.printStackTrace();
            }

    4、Class.forName()发生了什么

    /*
    * 研究一下:Class.forName()发生了什么
    * 重点:只希望一个类的静态代码块执行,其他一律不执行
    *   你可以使用:Class.forName("完整类名")
    *   这个方法的执行会导致类加载,类加载时,静态代码块执行
    * 
    * 提示:
    *   后面JDBC技术的时候我们还需要
    * */
    
    public class ReflectTest01 {
        public static void main(String[] args) {
            //静态代码块在类加载时加载,并且只执行一次
            try {
                Class.forName("MyClass");
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }
    
    
        }
    }
    class MyClass{
        //静态代码块在类加载时执行,并且只执行一次
        static{
            System.out.println("静态代码块执行了");
        }
    }

    5、获取路径的绝对路径

      //这种路径的缺点就是:移植性差,在idea中默认的路径是project的根
            // 这个代码假设离开了idea,换到其他的位置,可能当前路径就不是project的根了,这个路径就无效了
            // FileReader reader = new FileReader("classinfo.properties");
            //接下来说一种通用的路径表示方法,这种编写是通用的是
            //注意:试用一下通用方式的前提是:这个文件必须在类路径下,什么是类路径下,方式在src下都是类路径 src类的根路径
            /*
            * Thread.currentThread():当前线程
            * getContextClassLoader():是线程对象的方法,可以获取当前线程的类加载器
            * getResource:这是类加载器对象的方法,当前线程的类加载器默认从类的根目录获取资源
            * 可以拿到一个文件的绝对路径:/D:/java_base/out/production/chapter15/classinfo.properties
             *
            * */
            String path = Thread.currentThread().getContextClassLoader().getResource("classinfo.properties").getPath();
            System.out.println(path);
    
            //获取db.properties的绝对路径(从类的根路径下作为起点开始)
            String path2 = Thread.currentThread().getContextClassLoader().getResource("integer/db.properties").getPath();
            System.out.println(path2);

    6、类加载器

      /*
          * java.util下提供一个资源绑定器,便于获取属性配置文件中的内容
          * 但是以这种方式的时候,属性配置文件xxx.properties必须放到类路径下
          *
          * */
            //资源管理器,只能绑定xxx.properties文件,并且这个文件必须在类路径下,在写文件名的时候,路径后面的扩展名不能写
         
            ResourceBundle bundle  = ResourceBundle.getBundle("classinfo");
    
            String className = bundle.getString("className");
  • 相关阅读:
    jira:7.12.3版本搭建(破解版)
    traefik添加多证书
    人肉分析sorted(lst, key=lambda x: (x.isdigit(), x.isdigit() and int(x) % 2 == 0, x.islower(), x.isupper(), x))过程
    jquery实现checkbox全选/反选/取消
    k8s简单集群搭建
    第十二周编程总结
    第十周作业
    第九周编程总结
    第七周编程总结
    第五周编程总结
  • 原文地址:https://www.cnblogs.com/xiaoming521/p/15853499.html
Copyright © 2020-2023  润新知