存在Class对象:
- 外部类,成员内部类,静态内部类,局部内部类,匿名内部类【四大内部类】;
- 接口,枚举,数据
- 注解,基本数据类型,void;
Class常用方法:
Class cls = Class.forName(String str); //获取str的Class对象;
obj.getClass() = cls;
cls.getClass();//显示运行内存;
cls.getPackage(); //包名;
cls.getName();//全类名;
cls.newInstance(); //获取反射对象,编译对象是Object;
//对类的成员变量中,获取了成员对象后,需要将反射对象作为一个变量传入,
获取Class对象:
-
由配置文件的全类名:Class.forName();
-
参数传递:类名.class,eg String.class
-
运行阶段,已经有类对象:对象.getClass()【返回运行类型】;
- .getClass()返回的运行类型,指的就是对应的Class对象,
-
类加载器时【本质】,
ClassLoader cl = 对象.getClass().getClassLoader(); Class cls = cl.loaderClass("类全名");
-
基础类型:
Class<Integer> i = int.class; Class<Integer> type = Integer.TYPE;
类加载:
-
静态加载:编译时加载相关的类,没有则编译失败,依赖性强;
-
动态加载:运行时加载需要的类,如果运行时不用该类,则不报错,降低依赖性,也降低效率;
-
类加载的时机:
- 创建对象的时候;
- 当子类被加载的时候;
- 当调用子类静态成员的时候【调用静态常量属性除外】;
- 通过反射;
-
类加载流程:
- javac 编译 生成字节码文件;
- java 运行:类的加载分为三个阶段:
- 加载:将类的Class文件读入内存,并创建一个Class对象,此过程由类的加载器完成;
- 连接【将类的二进制数据合并到JRE中】:
- 验证:安全验证;
- 准备:对静态变量分配空间,并默认初始化;
- 解析:符号引用转化为直接引用;
- 初始化:jvm负责对类的静态成员进行初始化【显式初始化,静态代码块等】;
- 类加载后的内存布局:
- 方法区:类的字节码二进制数据;
- 堆区:类的Class对象【数据结构】;