注解与反射(3)
反射
哪些类型可以有class对象
class:外部类,成员(成员内部类,静态内部类),局部内部类,匿名内部类。
interface:接口
[]:数组
enum:枚举
annotation:注解@interface
primitive type:基本数据类型
void
package com.yangxu.Annotation.reflection;
import java.lang.annotation.ElementType;
public class Test03 {
public static void main(String[] args) {
Class c1 = Object.class;
Class c2 = Override.class;
Class c3 = Comparable.class;
Class c4 = String[].class;
Class c5 = int[][].class;
Class c6 = void.class;
Class c7 = Integer.class;
Class c8 = Class.class;
Class c9 = ElementType.class;
System.out.println(c1);
System.out.println(c2);
System.out.println(c3);
System.out.println(c4);
System.out.println(c5);
System.out.println(c6);
System.out.println(c7);
System.out.println(c8);
System.out.println(c9);
int[] a = new int[10];
int[] b = new int[100];
//目的是了解一个类中同一类型同一维度的对象,就是同一个Class
System.out.println(a.getClass().hashCode()==b.getClass().hashCode());
}
}
Java内存分析
类的加载与ClassLoader的理解
三个过程:加载——>链接——>初始化
-
加载:将class文件字节码内容加载到内存中,并将这些静态数据转换成方法区的运行时数据结构,然后生成一个代表这个类的java.lang.Class对象.
-
链接:将Java类的二进制代码合并到JVM的运行状态之中的过程。
- 验证:确保加载的类信息符合JVM规范,没有安全方面的问题
- 准备:正式为类变量(static)分配内存并设置类变量默认初始值的阶段,这些内存都将在方法区中进行分配。
- 解析:虚拟机常量池内的符号引用(常量名)替换为直接引用(地址)的过程。
-
初始化
- 执行类构造器()方法的过程。类构造器()方法是由编译期自动收集类中所有类变量的赋值动作和静态代码块中的语句合并产生的。(类构造器是构造类信息的,不是构造该类对象的构造器)。
- 当初始化一个类的时候,如果发现其父类还没有进行初始化,则需要先触发其父类的初始化。
- 虚拟机会保证一个类的()方法在多线程环境中被正确加锁和同步。
具体的:
package com.yangxu.Annotation.reflection;
public class ReviewLearned {
public static void main(String[] args) {
MyView myView = new MyView();
System.out.println(MyView.num);
}
}
//加载:生成一个MyView的Class类文件
//链接:将static里面的变量初始化,此时num = 0
//初始化:<clinit>()方法,所有类变量的赋值搜集,和静态代码块中的内容合并组成
//具体的:
//clinit(){
// int num = 10;
// static int num = 100;
// }
class MyView{
static {
System.out.println("这是静态代码块");
int num = 10;
}
static int num = 100;
public MyView() {
System.out.println("这是无参构造器");
}
}
画图的理解: