知识图谱
理解Class对象
类是程序的一部分,每个类都有对应的class对象,在编译的时候把java文件转换为class文件。Class类也是类的一种,但比较特别,Class类是你创建的类的类型信息,比如你创建一个shapes类,那么,Java会生成一个内容是shapes的Class类的对象。Class 只有私有构造函数,没有public构造函数。Class类的作用是运行时提供或获得某个对象的类型信息,常与反射一起使用。
类加载机制/初始化机制
流程图
过程参考开始的大图。
类的加载机制(初始化) 和 实例化区别?
实例化 是指创建一个类的实例(对象)的过程;不同于类的初始化。
类的加载机制(初始化)时机?
定义:指为类中各个类成员(被static修饰的成员变量)赋初始值的过程,是类生命周期中的一个阶段。在对类的静态成员引用时, 就会加载这个类。
时机
- 创建类实例 new 方法
- 访问类的静态变量(static final修饰的常量除外)
- 调用静态方法
- 反射
- 初始化一个类的时候,如果发现其父类还没有进行过初始化,则需要先触发其父类的初始化
静态变量、代码块、静态代码块、构造方法执行顺序?
public class RTTIDemo {
public static String A = "静态字段";
{
System.out.println("代码块执行");
}
static {
System.out.println("静态代码块");
}
public RTTIDemo(){
System.out.println("构造方法");
}
public static void method(){
System.out.println("静态方法");
}
public static void main(String[] args) {
RTTIDemo rttiDemo = new RTTIDemo();
RTTIDemo rttiDemo1 =new RTTIDemo();
rttiDemo1.method();
}
}
打印结果:
静态代码块
代码块执行
构造方法
代码块执行
构造方法
静态方法
由于静态变量是在类初始化的时候就已经赋值和初始化了,所以是最先执行的,现在有结论了:
静态变量——静态代码块——代码块——构造方法(其中,静态变量和代码块只会执行一次,而代码块会随着每次对象实例化都会去执行)
获取Class方法
- Class.forName(“类全路径”) 包名+类名
- 类字面常量Class<People> class = People.class
- 类的实例化对象.getClass()
People p = new People();
p.getClass()
类字面常量
定义:People.class
不同于Class.forName("People"),类字面常量可以在编译期间进行检查,且更高效
基本类型字面常量为八种基本类型,没有String
Class类常用方法
- getClassLoader():返回该Class对象对应的类的类加载器
- isInterface() :判定指定的 Class 对象是否表示一个接口类型
- Constructor[] constructor1 = peopleClass.getConstructors() 获取所有的构造函数数组
- Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes)
- newInstance() 创建类的新实例,调用的是此类的默认构造方法(没有默认无参构造器会报错)
- public T newInstance(Object ... initargs)
Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes)
获取public,private 默认的给定参数的构造方法 Constructor constructor2 = peopleClass.getDeclaredConstructor(String.class, int.class);
public T newInstance(Object ... initargs)
返回指定参数格式的构造方法创建的对象:People people = (People) constructor.newInstance("sjh");
例子:
public class People {
private String name;
public int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public People() {
}
private People(String name) {
this.name = name;
}
private People(String name, int age) {
this.name = name;
}
public static void main(String[] args) {
Class<People> peopleClass = People.class;
try {
Constructor constructor = peopleClass.getConstructor(String.class);
Constructor constructor2 = peopleClass.getDeclaredConstructor(String.class, int.class);
Constructor[] constructor1 = peopleClass.getConstructors();
System.out.println(constructor1.length);
System.out.println(constructor2.newInstance("sjh", 2));
try {
People people = (People) constructor.newInstance("sjh");
System.out.println(people.getName());
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
} catch (Exception e) {
e.printStackTrace();
}
}
Constructor constructor = peopleClass.getConstructor(String.class); 这句代码会报错,没有这个方法,因为getConstructor 只能运用public的方法,getDeclaredConstructor 可以用public ,private 和默认修饰符的构造方法。从这里也能知道newInstantce()方法的用法。把这些类比到Method , Field 都是一样的道理。
文章参考: