zoukankan      html  css  js  c++  java
  • java 反射 类装载器

    前言:

         java语言允许通过程序化的方式间接对Class进行操作,Class文件由类装载器装载后,在jvm中将形成一份描述Class结构的元信息对象,通过该元信息对象可以获知Class的结构信息,如构造函数,属性和方法等,

    java允许用户借由这个与Class相关的元信息对象间接调用Class对象的功能,这就为使用程序化方式操作Class对象开辟了途径。

    实例:

    下面一个Car类拥有两个构造函数,一个方法及三个属性

    package reflect;
    
    public class Car {
        private String brand; //品牌
        private String color; //颜色
        private int maxSpeed; //转速
    
        public Car(){}
    
        public Car(String brand, String color, int maxSpeed){
            this.brand = brand;
            this.color = color;
            this.maxSpeed = maxSpeed;
        }
        public void say(){
            System.out.println("brand:"+ brand + ", color:"+ color +", maxSpeed:"+ maxSpeed);
        }
    
    //set和get 方法省略

    一般情况下,我们会使用如下代码创建Car的实例:

    Car car = new Car();
    car.setBrand("红旗");

    这种是采用传统方式直接调用目标类,下面我们可以使用java反射机制以一种间接的方式操控目标类:

    public class ReflectTest {
    
        public static Car initByDefaultConst() throws Throwable{
            // 1. 通过类装载器获取Car类的对象
            ClassLoader loader = Thread.currentThread().getContextClassLoader();
            //使用全限定名来找class类
            Class clazz = loader.loadClass("reflect.Car");
    
            /*Class clazz = Class.forName("reflect.Car");*/  //另一种方式获取class
    
            // 2. 获取类的默认构造器对象并通过它实例化Car
            Constructor cons = clazz.getDeclaredConstructor((Class[])null);
            Car car = (Car)cons.newInstance();
    
            // 3. 通过反射方法设置属性
            Method setBrand = clazz.getMethod("setBrand", String.class);
            setBrand.invoke(car,"红旗");
            Method setColor = clazz.getMethod("setColor", String.class);
            setColor.invoke(car,"黑色");
            Method setMaxSpeed = clazz.getMethod("setMaxSpeed", int.class);
            setMaxSpeed.invoke(car,200);
            return car;
        }
        @Test
        public void test() throws Throwable{
            Car car = initByDefaultConst();
            car.say();
        }
    }

    运行以上程序,在控制台打印如下: brand:红旗, color:黑色, maxSpeed:200

    上述的程序只是用了很少的api,java反射包为我们提供了很多的方法,可以细查。

    其余扩展:

    类装载器ClassLoader的工作机制:

       类装载器就是寻找类的节码文件并构造出类在jvm内部表示对象的组件,在java中,类装载器把一个类装入jvm中,需要经过如下步骤:

            1.  装载:查找和导入Class文件

       2.  链接:执行校验,准备和解析步骤,其中解析步骤是可以选择的

        2.1. 校验:检查载入Class文件数据的正确性

        2.2. 准备: 给类的静态变量分配存储空间

        2.3. 解析:将符号引用转换成直接引用

       3.  初始化:对类的静态变量,静态代码块执行初始化工作

    JVM装载类使用 “全盘负责委托机制”,

    全盘负责”是指当一个ClassLoader装载一个类时(除非显式的使用另一个ClassLoader),该类所依赖及引用的类也由这个ClassLoader载入;

    委托机制”是指先委托父装载器寻找目标类,只有在找不到的情况下才从自己的类路径中查找并装载目标类。

    这一点是从安全角度考虑的,试想,如果有一个人编写了一个恶意的基础类(如java.lang.String)并装载到JVM中,将会引起多么可怕的后果,

    但是由于有了“全盘负责委托机制”,java.lang.String永远是根装载器来装载的,这样就避免了上述安全隐患的发生。

       

  • 相关阅读:
    silverlight的Datagrid控件列绑定属性笔记
    VC字符串处理整理
    Combobox实现多项选择 Silverlight下“Combobox”怎样实现多项选择?
    C# 类初始化顺序
    Silverlight程序设置断点无法进入调试的解决方案
    有哪些适合新手练手的Python项目?
    Ubuntu 终端常用命令
    浅析python 中__name__ = '__main__' 的作用
    py thon 多线程(转一篇好文章)
    python os.path模块
  • 原文地址:https://www.cnblogs.com/xinde123/p/7601091.html
Copyright © 2011-2022 走看看