反射 (一) 初体验

127 阅读1分钟

一 初体验。 得到类实例 。

准备几个类


class Person {
    public String name;
    @Override

public String toString() {
        return "Person{" +
                "name='" + name + ''' +
                '}';
    }
}

class Stu extends Person {
    public Stu() {
        this.name = "stu";
    }
    @Override
    public String toString() {
        return "Stu{" +
                "name='" + name + ''' +
                '}';
    }
}

class Teacher extends Person {
    public Teacher() {
        this.name = "teahcer";
    }

    @Override
    public String toString() {
        return "Teacher{" +
                "name='" + name + ''' +
                '}';
    }
}

2 获取类实例 。

public static void main(String[] args) throws ClassNotFoundException {
    Person person = new Stu();

    Class c1 = person.getClass();

    System.out.println(c1.hashCode());

    Class c2 = Class.forName("com.company.Stu");
    System.out.println(c2.hashCode());

    Class c3 = Class.forName("com.company.Teacher");
    System.out.println(c3.hashCode());

    Class c4 = Stu.class;
    System.out.println(c4.hashCode());

}

image.png

二 有哪些类实例

package com.company;

import java.lang.annotation.ElementType;

//test class
public class Test04 {


    public static void main(String[] args) {

        Class c1 = Object.class;
        Class c2 = Comparable.class;
        Class c3 = String[].class;
        Class c4 = int[][].class;
        Class c5 = Override.class;
        Class c6 = ElementType.class;
        Class c7 = Integer.class;
        Class c8 = void.class;
        Class c9 = Class.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);

    }
}

image.png

三 从内存去分析。

类的加载过程 。 1 类的加载。
将class 文件的字节码,加载到内在中,并将静态数据转成方法区的动行时数据结果。 2 类的链接 验证,符合JVM 规范。 准备,为static 分配内存, 解析。 3 类的初始化。 执行类构造器 <clinit>

package com.company;

public class Test05 {
    public static void main(String[] args) {
        A a = new A();
        System.out.println(A.m);
    }
}


class A {

    static  {
        System.out.println("1static -->");
        m = 100;
    }

    public static int m = 100;

    public A() {
        System.out.println("2 construct");

    }
}

总结:

  1. 加载到内在,产生了一class 对象。
  2. 链接结束后 m = 0
  3. 初始化, <clinit> 把 static 和定义的代码都执行。

四 动态创建对象。

一定要有无参constructor

Class c1 = Class.forName("xxx")

User user = (User)c1.newInstance();