Java的类与Class

  • RTTI(RunTime Type Identification)运行时类型识别
  • 一个Class对象就是类的说明书
    • JVM根据这个说明书创建出来一个类的实例
  • instanceof
  • 强制类型转换

Object类

  • public方法:
    • clone
    • equals
    • finalize
    • getClass
    • hashCode
    • notify
    • notifyAll
    • toString
    • wait

Class对象的生命周期

  • 在第一次被使用时被加载
    image.png

Class和Classloader

1. Classloader负责从外部系统中加载一个类

  • 这个类对应的Java文件并不一定需要存在
    • 可以从网络获取字节流,文件的本质是字节流
    • 可以动态在内存中生成(Classloader)
  • 这个字节码并不一定需要存在
  • 这是Java世界丰富的应用的基石

    2. Classloader的双亲委派加载模型

  • 外部系统是不安全的,完全可以伪造java.lang.*类

  • Classloader loadClass会先查看parent有没有加载,父类加载了自己就不会加载
    image.png
  • 内置类都会由顶端的类加载器加载,所以伪造java.lang.*类是无效的

    3. Java语言规范与Java虚拟机规范

  • class的文件可以不由Java文件生成,所以JVM的运行可以不必依赖Java文件

    • Java语言和虚拟机的联系其实就是字节码,但是字节码可以不由Java语言生产
    • 这种分离提供了在JVM上运行其他语言的可能
  • Java Language Specification(JLS),Java语言规范
  • Java Virtual Machine Specification(JVMS),Java虚拟机规范

反射

  • 为什么叫反射?
  • 假如想:

    • 根据参数动态创建一个对象?
    • 根据参数动态调取一个方法?
    • 根据参数动态获取一个属性?
      1. // 根据参数动态创建一个对象
      2. // 反射代码编写时,并不知道未来要创建的对象是一个什么
      3. public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
      4. String className = args[0];
      5. Class c = Class.forName(className);
      6. Object obj = c.getConstructor().newInstance();
      7. }
      8. // 动态调用方法
      9. public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
      10. String methodName = args[0];
      11. MyObj obj = new MyObj();
      12. obj.getClass().getMethod(arg[0]).invoke(obj);
      13. }
  • Class

    • Class.forName()
  • Method
    • Method.invoke
  • Field
    • Field.get
  • 反射无处不在
    • Spring源码分析