java虚拟机

参考网站:java语言和虚拟机规范 https://docs.oracle.com/javase/specs/index.html

java虚拟机概念

  • java优势:“一次编译到处执行”,可轻松地跨平台运行(虚拟机的功劳,虚拟机可以跨平台)
  • java虚拟机的功能:负责其硬件和操作系统独立性、编译代码以及保护用户免受恶意程序侵害的 能力
  • java虚拟机是一种抽象计算机(像计算机一样,具有指令集并运行时操作各种内存区域)
  • java虚拟机与java无关,只知道特定的二进制格式即class文件格式
    • java编译成class文件后,虚拟机能对其中的指令集(字节码)、符号表、其他辅助信息进行处理
  • 为安全期间,java虚拟机对class文件中的代码施加了强大的语法和结构约束。但是,任何具有可以用有效的class文件【本地,网络地址】表示的功能的语言都可以由java虚拟机托管

    class文件概念

  1. class结构
    1. 魔数(magic)
    2. 副版本号(minor_version)
    3. 主版本号(major_version)
    4. 常量池计数器(constant_pool_count)
      1. 常量数据区
    5. 访问标志(access_flags)
    6. 类索引(this_class)
    7. 父类索引(super_class)
    8. 接口计数器(interfaces_count)
      1. 接口信息器
    9. 字段计数器(fields__count)
      1. 字段信息数据区
    10. 方法计数器(methods_count)
      1. 方法信息数据区
    11. 属性计数器(attribute_count)
      1. 属性信息数据区
  2. 什么是类加载
    1. 将class文件加载到虚拟机运行内存,生成对应的class对象的过程
    2. 编译器【java->class】->类加载->运行期 class对象的过程
    3. 一个java文件 对应 一个class文件 对应 一个class对象
  3. 类加载过程步骤
    1. 加载:将class文件加载到虚拟机的过程,class文件 -> class对象
    2. 连接:
      1. 验证:验证class文件格式是否正确
      2. 准备:为静态变量开辟空间,给定对应的默认值
      3. 解析:将父类和接口的引用指向具体的父类和接口的内存地址
    3. 初始化:给静态变量声明值,然后调用静态代码块
  4. java文件、class文件、class对象的区别
    1. 相同:内容都相同只是体现的形式不同
    2. 不同:
      1. java文件包含程序员看懂代码和程序员编写的区域
      2. class文件是为jvm虚拟机能够读懂
      3. class对象是将class文件加载到虚拟机运行内存中的体现,
      4. class对象也成为模板对象,包含声明类的信息,反射技术需要依赖class对象
  5. 类加载时机:每个类只会被加载一次,生成一个类模板对象
    1. 遇到创建new时
    2. 遇到静态方法时
    3. 遇到访问静态字段(属性)时
    4. 子类初始化会触发父类的初始化
    5. 接口定义了方法,直接或间接实现该接口类的初始化,会触发接口的初始化
    6. 使用反射API对某个类进行反射调用时,初始化这个类
    7. 虚拟机启动时,初始化用户指定的主类
  6. java实例化对象
    1. new创建【编译器】
      1. 在编译器确定实例类型和方法属性调用位置
      2. 程序运行时无法动态修改
      3. new实例化动作底层依赖当前class模板
      4. 程序主要对象实例化方法
    2. Reflect反射【运行期】
      1. 是一种动态机制,运行时能根据class模板完成类的实例化及属性方法的操作
      2. 能通过方法打破修饰符的限制类外访问私有方法
      3. 三方工具和框架都大量使用反射,保证框架的灵活和可拓展性,通过配置童泰实例不同类
        1. 数据库框架MyBatis支持动态查询,返回结果可以动态指定
      4. 反射速度慢
  7. 反射学习内容:动态实例化对象、动态操作对象属性、动态操作对象方法、打破限制符

    class

  • 获取Class方法使用
    • 类名.class属性
    • 对象.getClass()
    • Class.forNorName(“类的全限定符 包 类名”) ```java // 获取类的模板对象 Class Student.class; Class new Student().getClass(); Class Class.forName(“com.radiate.Student”);

T newInstance(); // 反射创建对象

// 查看 // 包获取 Package getPackage(); // 获取包信息

// 类获取 String getName(); // 获取类的完全名 Class<? super T> getSuperclass(); // 获取父类

// 接口获取 Class<?>[] getInterfaces(); // 获取所有实现父接口

// 构造器获取 Constructor<?>[] getConstructors(); // 公有(public)构造器 Constructor<?>[] getDeclaredConstructors() // 所有构造器 Constructor getDeclaredConstructor(Class…param) // 指定公有构造器 Constructor getDeclaredConstructor(Class…param) // 指定构造器

// 方法获取 Method getMethod(String name, Class<?>…parameterTypes);// 指定公有方法名,可选方法形参对象 Method getDeclaredMethod(String name, Class<?>…parameterTypes); // 所有方法名 Method[] getMethods(); // 所有公有(public)方法对象 Method[] getDeclaredMethods(); // 所有方法对象(含父类) Parameter[] Constructor.getParameters(); // 该构造器的参数对象

// 属性、字段获取 Field[] getFields(); // 公有字段对象数组 Field[] getDeclaredFields(); // 所有字段对象数组 Field getField(String name); // 指定公有字段对象 Field getDeclaredFields(String name) // 指定字段对象

// 参数获取 int getParameterCount(); // 获取参数数量 Parameter[] Constructor.getParameters(); // 该构造器的参数对象 Parameter[] getParameters(); // 获取参数信息 Class<?> getReturnType(); // 获取返回值 int getModifiers(); // 获取修饰符编号 // Modifier.toString(getModifiers()) // 编号转字符串英文名

// 反射调用 T Constructor.newInstance(Object…ages); // 调用构造器 void setAccessible(boolean flag); // 设置访问权限(用于修改private权限) void set(Object obj, Object value); // 设置字段值(静态方法obj能使用null) Object invoke(Object, obj, Object…args); // obj: 调用底层方法的对象(静态方法可以直接null) // args: 方法调用所需的参数 // return: 获取并返回方法原有的返回值,Object类型需要判断和转换

  1. <a name="rO6k5"></a>
  2. #
  3. class指令集查看(java反编译)
  4. ```java
  5. > javac test.java
  6. > javap -c test.class

image.png