Java Class 类型信息RTTI

知识图谱

理解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 都是一样的道理。

文章参考:

https://blog.csdn.net/javazejian/article/details/70768369#class%E5%AF%B9%E8%B1%A1%E7%9A%84%E5%8A%A0%E8%BD%BD

https://blog.csdn.net/justloveyou_/article/details/72466105

猜你喜欢

转载自blog.csdn.net/sjh_389510506/article/details/88794870