Java面向对象之 类加载及 通过反射获取类的结构信息

Java面向对象之 类加载及 通过反射获取类的结构信息,第1张

Java面向对象之 类加载及 通过反射获取类的结构信息

文章目录

1、类加载

1.1、基本说明1.2、类加载时机1.3、类加载过程图1.4、类加载各阶段完成任务

1.4.1、加载阶段1.4.2、连接阶段-验证1.4.3、连接阶段-准备1.4.4、连接阶段-解析1.4.5、Initialization(初始化) 2、通过反射获取类的结构信息

2.1、第一组: java.lang.Class 类2.2、第二组: java.lang.reflect.Field 类2.3、第三组: java.lang.reflect.Method 类2.4、第四组: java.lang.reflect.Constructor 类

1、类加载 1.1、基本说明

package classload_;

import reflection.Cat;

public class Test {
    public static void main(String[] args) {
        Cat cat = new Cat();
    }
}
1.2、类加载时机

1.3、类加载过程图

1.4、类加载各阶段完成任务

1.4.1、加载阶段

1.4.2、连接阶段-验证

1.4.3、连接阶段-准备

package classload_;


public class ClassLoad02 {
    public static void main(String[] args) {

    }
}

class A {
    // 属性-成员变量-字段
    // 分析类加载的链接阶段-准备 属性是如何处理的
    // 1. n1 是实例属性, 不是静态变量, 因此在准备阶段, 是不会分配内存的
    // 2. n2 是静态变量, 分配内存 n2 是默认初始化 0, 而不是 20
    // 3. n3 是 static final 是常量, 它和静态变量不一样, 因为一旦赋值就不变 n3 = 30
    public int n1 = 10;
    public static int n2 = 20;
    public static final int n3 = 30;
}
1.4.4、连接阶段-解析

1.4.5、Initialization(初始化)

package classload_;


public class ClassLoad03 {
    public static void main(String[] args) {
        // 分析
        // 1. 加载 B 类, 并生成 B 的 class 对象
        // 2. 链接 num = 0
        // 3. 初始化阶段
        // 依次自动收集类中的所有静态变量的赋值动作和静态代码块中的语句, 并合并
        

        // new B();  // 类加载
        // System.out.println(B.num);  // 100, 如果直接使用类的静态属性, 也会导致类的加载

        // 看看加载类的时候, 是有同步机制控制
        
        B b = new B();
    }
}

class B {
    static {
        System.out.println("B 静态代码块被执行");
        num = 300;
    }

    static int num = 100;

    public B() {  // 构造器
        System.out.println("B() 构造器被执行");
    }
}
2、通过反射获取类的结构信息 2.1、第一组: java.lang.Class 类

2.2、第二组: java.lang.reflect.Field 类

2.3、第三组: java.lang.reflect.Method 类

2.4、第四组: java.lang.reflect.Constructor 类

package reflection;

import org.junit.jupiter.api.Test;

import java.lang.annotation.Annotation;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;


public class ReflectionUtils {
    public static void main(String[] args) {

    }

    @Test
    public void api_02() throws ClassNotFoundException, NoSuchMethodException {
        // 得到Class对象
        Class personCls = Class.forName("reflection.Person");
        // getDeclaredFields: 获取本类中所有属性
        // 规定 说明: 默认修饰符是 0, public是 1, private是 2, protected是 4, static是 8, final是 16
        Field[] declaredFields = personCls.getDeclaredFields();
        for (Field declaredField : declaredFields) {
            System.out.println("本类中所有属性=" + declaredField.getName()
                    + " 该属性的修饰符值=" + declaredField.getModifiers()
                    + " 该属性的类型=" + declaredField.getType());
        }

        // getDeclaredMethods: 获取本类中所有方法
        Method[] declaredMethods = personCls.getDeclaredMethods();
        for (Method declaredMethod : declaredMethods) {
            System.out.println("本类中所有方法=" + declaredMethod.getName()
                    + " 该方法的访问修饰符值=" + declaredMethod.getModifiers()
                    + " 该方法返回类型" + declaredMethod.getReturnType());

            // 输出当前这个方法的形参数组情况
            Class[] parameterTypes = declaredMethod.getParameterTypes();
            for (Class parameterType : parameterTypes) {
                System.out.println("该方法的形参类型=" + parameterType);
            }
        }

        // getDeclaredConstructors: 获取本类中所有构造器
        Constructor[] declaredConstructors = personCls.getDeclaredConstructors();
        for (Constructor declaredConstructor : declaredConstructors) {
            System.out.println("====================");
            System.out.println("本类中所有构造器=" + declaredConstructor.getName());  // 这里只是输出名

            Class[] parameterTypes = declaredConstructor.getParameterTypes();
            for (Class parameterType : parameterTypes) {
                System.out.println("该构造器的形参类型=" + parameterType);
            }
        }
    }

    // 第一组方法API
    @Test
    public void api_01() throws ClassNotFoundException, NoSuchMethodException {

        // 得到Class对象
        Class personCls = Class.forName("reflection.Person");
        // getName: 获取全类名
        System.out.println(personCls.getName());  // reflection.Person
        // getSimpleName: 获取简单类名
        System.out.println(personCls.getSimpleName());  // Person
        // getFields: 获取所有public修饰的属性, 包含本类以及父类的
        Field[] fields = personCls.getFields();
        for (Field field : fields) {  // 增强for
            System.out.println("本类以及父类的属性=" + field.getName());
        }
        // getDeclaredFields: 获取本类中所有属性
        Field[] declaredFields = personCls.getDeclaredFields();
        for (Field declaredField : declaredFields) {
            System.out.println("本类中所有属性=" + declaredField.getName());
        }
        // getMethods: 获取所有public修饰的方法, 包含本类以及父类的
        Method[] methods = personCls.getMethods();
        for (Method method : methods) {
            System.out.println("本类以及父类的方法=" + method.getName());
        }
        // getDeclaredMethods: 获取本类中所有方法
        Method[] declaredMethods = personCls.getDeclaredMethods();
        for (Method declaredMethod : declaredMethods) {
            System.out.println("本类中所有方法=" + declaredMethod.getName());
        }
        // getConstructors: 获取所有public修饰的构造器, 包含本类
        Constructor[] constructors = personCls.getConstructors();
        for (Constructor constructor : constructors) {
            System.out.println("本类的构造器=" + constructor.getName());
        }
        // getDeclaredConstructors: 获取本类中所有构造器
        Constructor[] declaredConstructors = personCls.getDeclaredConstructors();
        for (Constructor declaredConstructor : declaredConstructors) {
            System.out.println("本类中所有构造器=" + declaredConstructor.getName());  // 这里只是输出名
        }
        // getPackage: 以Package形式返回 包信息
        System.out.println(personCls.getPackage());  // reflection
        // getSuperClass: 以Class形式返回父类信息
        Class superclass = personCls.getSuperclass();
        System.out.println("父类的class对象=" + superclass);//
        // getInterfaces: 以Class[]形式返回接口信息
        Class[] interfaces = personCls.getInterfaces();
        for (Class anInterface : interfaces) {
            System.out.println("接口信息=" + anInterface);
        }
        //getAnnotations:以Annotation[] 形式返回注解信息
        Annotation[] annotations = personCls.getAnnotations();
        for (Annotation annotation : annotations) {
            System.out.println("注解信息=" + annotation);//注解
        }
    }
}

class A {
    public String hobby;

    public void hi() {

    }

    public A() {
    }

    public A(String name) {
    }
}

interface IA {
}

interface IB {

}

@Deprecated
class Person extends A implements IA, IB {
    // 属性
    public String name;
    protected static int age;  // 4 + 8 = 12
    String job;
    private double sal;

    // 构造器
    public Person() {
    }

    public Person(String name) {
    }

    // 私有
    private Person(String name, int age) {

    }

    // 方法
    public void m1(String name, int age, double sal) {

    }

    protected String m2() {
        return null;
    }

    void m3() {

    }

    private void m4() {

    }
}

控制台输出

本类中所有属性=name 该属性的修饰符值=1 该属性的类型=class java.lang.String
本类中所有属性=age 该属性的修饰符值=12 该属性的类型=int
本类中所有属性=job 该属性的修饰符值=0 该属性的类型=class java.lang.String
本类中所有属性=sal 该属性的修饰符值=2 该属性的类型=double
本类中所有方法=m1 该方法的访问修饰符值=1 该方法返回类型void
该方法的形参类型=class java.lang.String
该方法的形参类型=int
该方法的形参类型=double
本类中所有方法=m2 该方法的访问修饰符值=4 该方法返回类型class java.lang.String
本类中所有方法=m4 该方法的访问修饰符值=2 该方法返回类型void
本类中所有方法=m3 该方法的访问修饰符值=0 该方法返回类型void
本类中所有构造器=reflection.Person
该构造器的形参类型=class java.lang.String
该构造器的形参类型=int
本类中所有构造器=reflection.Person
该构造器的形参类型=class java.lang.String
本类中所有构造器=reflection.Person

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5707558.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-17
下一篇 2022-12-17

发表评论

登录后才能评论

评论列表(0条)

保存