Java中类的加载机制和反射相关概念

90 阅读3分钟

本篇文章主要知识点

因为最近在刷面试题,遇到了很多的基础问题都出了错,所以利用空闲时间大肆的回顾下基础,顺便总结出了一些知识点来进行分享,如果能帮助到你请点个赞吧!
1.Java一个类中代码的执行次序
2.当一个子类继承父类时,子类实例化时,子类和父类代码的执行次序
3.final关键词的一些验证
4.反射到底都能获取类的什么东西

下面我们来依次进行试验:

1 Java中代码的执行次序

我们来新建一个类,一个类中的东西也无非就是属性(private、public修饰等等)方法(private、public修饰等等)静态代码块非静态代码块构造方法(有参和无参)

class People {
    private String str = "People";

    private static final String VALUE = "I am people static VALUE";

    public People() {
        System.out.println("people 无参实例化");
    }

    public People(String str) {
        this.str = str;
        System.out.println("people 全参实例化");
    }

    static {
        //System.out.println(str);编译错误
        System.out.println(VALUE);
        System.out.println("I am people static part");
    }

    {
        System.out.println("I am people no static part");
    }

    public void method1() {
        System.out.println("I am people method1");
    }
}

public class article0604 {
    public static void main(String[] args) {
        People people=new People();
    }
}

运行结果:
在这里插入图片描述
由此我们知道了一个类中代码的执行机制(次序):
在这里插入图片描述

2 子类继承父类时代码的执行次序

下面我们把People作为父类,再创建一个Student子类:

class Student extends People {

    private String str = "Student";

    public Student() {
        System.out.println("student 无参实例化");
    }

    public Student(String str) {
        this.str = str;
        System.out.println("student 全参实例化");
    }

    static {
        System.out.println("I am student static part");
    }

    {
        System.out.println("I am student no static part");
    }

    @Override
    public void method1() {
        System.out.println("I am student method1");
    }
}

public class article0604 {
    public static void main(String[] args)  {
        Student student = new Student();
    }
}

运行结果:
在这里插入图片描述
由此我们可以得知:
在这里插入图片描述

3 final关键词的一些验证

首先看下Java中对于final关键字的一些解释:
final:用来说明最终属性,表明一个类不能派生出子类,或者成员方法不能被覆盖,或者成员域的值不能被改变,用来定义常量

final修饰的类不能被继承:
在这里插入图片描述
final修饰的变量子类也不能继承
在这里插入图片描述
反射也不行

Class<?> clazz = Class.forName("test0604.Student");
Field[] fields = clazz.getFields();
System.out.println("参数个数:" + fields.length);
for (Field field : fields) {
    System.out.println(field);
}

运行结果:
0

4 反射到底都能获取类的什么东西

我们就以上边Student类来进行测试:

 public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException {
        Class<?> clazz = Class.forName("test0604.Student");
        //获取参数
        Field[] fields = clazz.getFields();
        Field[] declaredFields = clazz.getDeclaredFields();
        /*
        clazz.getDeclaredMethods()
        反映由这个class对象表示的类或接口声明的所有字段。 这包括公共、受保护、默认(包)访问和私有字段,但不包括继承字段。
         */
        Method[] declaredMethods = clazz.getDeclaredMethods();
        Method[] methods = clazz.getMethods();
        System.out.println("Declared方法:" + declaredMethods.length);
        System.out.println("public方法:" + methods.length);
        System.out.println("Declared参数:" + declaredFields.length);
        System.out.println("public参数:" + fields.length);
        System.out.println("遍历fields:");
        for (Field field : fields) {
            System.out.println(field);
        }
        System.out.println("遍历declaredFields:");
        for (Field field : declaredFields) {
            System.out.println(field);
        }
        System.out.println("遍历declaredMethods:");
        for (Method d : declaredMethods) {
            System.out.println(d);
        }
        System.out.println("遍历methods:");
        for (Method d : methods) {
            System.out.println(d);
        }

输出结果:
在这里插入图片描述
在这里注意下:
clazz.getDeclaredMethods():反映由这个class对象表示的类或接口声明的所有字段。 这包括公共、受保护、默认(包)访问和私有字段,但不包括继承字段。