首页 > 编程语言 >java的反射

java的反射

时间:2023-01-18 15:25:15浏览次数:36  
标签:aClass java String 反射 println 修饰 父类 public

一. 反射的由来

vip

 

编译阶段:将java文件编译成字节码文件。

加载过程:通过类加载器,在方法区中加载类的静态属性和静态方法,在堆中存放该类的反射类对象。

运行过程:执行方法。

二. 反射的用法

首先创建Dog类

public class Dog {
    public String name;
    public int age;
    public String color;

    public Dog(){}

    public Dog(String name, Integer age, String color) {
        this.name = name;
        this.age = age;
        this.color = color;
    }

    public void run(){
        System.out.println(name + "在跑步");
    }

    public void sleep(){
        System.out.println(name + "在睡觉");
    }

    @Override
    public String toString() {
        return "Dog{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", color='" + color + '\'' +
                '}';
    }
}

反射对象的方法使用

public class Reflection03 {
    public static void main(String[] args) throws Exception{
        Class<?> aClass = Class.forName("com.hspedu.Dog");
        // class com.hspedu.Dog  aClass引用指向的是Dog类的Class【反射对象】
        System.out.println(aClass);
        // class java.lang.Class aClass对象的运行类型Class【反射类】
        System.out.println(aClass.getClass());
        // 1.获取类的路径
        String name = aClass.getName();
        System.out.println(name);
        // 2.获取包名
        Package aPackage = aClass.getPackage();
        System.out.println(aPackage);
        // 3.1 获取无参构造器
        // public com.hspedu.Dog()
        Constructor<?> constructor1 = aClass.getConstructor();
        System.out.println(constructor1);
        // 3.2 获取带参构造器
        // public com.hspedu.Dog(java.lang.String,java.lang.Integer,java.lang.String)
        Constructor<?> constructor2 = aClass.getConstructor(String.class, Integer.class, String.class);
        System.out.println(constructor2);
        // 4 获取对象【无参】
        Object o = aClass.newInstance();
        // com.hspedu.Dog
        System.out.println(o.getClass());
        // 5.设置属性
        Field dogName = aClass.getField("name");
        dogName.set(o,"Tom");
        Field age = aClass.getField("age");
        age.set(o,8);
        Field color = aClass.getField("color");
        color.set(o,"白色");
        System.out.println(o);
        // 6.调用方法
        Method run = aClass.getMethod("run");
        run.invoke(o);
        Method sleep = aClass.getMethod("sleep");
        sleep.invoke(o);
        // 7.一次性得到反射对象的属性
        Field[] fields = aClass.getFields();
        for (Field field : fields) {
            System.out.println(field.getName());
        }


    }
}

三. 获取反射对象

public class Reflection04 {
    public static void main(String[] args) throws Exception{
        // 获取反射对象
        // 方式1:编译阶段,通过Class.forName(类的路径)
        Class<?> aClass = Class.forName("com.hspedu.Dog");
        System.out.println(aClass.hashCode());
        // 方式2:加载阶段,类名.class
        Class<Dog> dogClass = Dog.class;
        System.out.println(dogClass.hashCode());
        // 方式3:类加载器
        Class<?> aClass1 = ClassLoader.getSystemClassLoader().loadClass("com.hspedu.Dog");
        System.out.println(aClass1.hashCode());
        // 方式4:基本数据类型.class
        Class<Integer> integerClass = int.class;
        System.out.println(integerClass.hashCode());
        // 方式5:包装类.TYPE
        Class<Integer> type = Integer.TYPE;
        System.out.println(type.hashCode());

    }
}

运行结果:

1554874502
1554874502
1554874502
1846274136
1846274136

说明同一个类的反射对象只有一个。

 四. 类加载解读

1. 静态加载和动态加载

加载包括:静态加载和动态加载 静态加载:在编译阶段,加载所有的类,遇到没有import导入的类,编译异常; 动态加载:在运行阶段,加载所需要的类,如果没有,不出现编译异常,但是肯定有运行异常。 动态加载:反射【五种方式】; 静态加载:new ;调用静态成员;子类被加载时,父类也被加载。

2. 类加载的具体过程

类加载图解:

vip

这里的初始化,是静态成员的初始化,静态成员随着类的加载而加载。

类加载三个阶段的主要任务:

vip

 五.综合案例,获取类的结构信息

public class Reflection06 {
    public static void main(String[] args) throws Exception{
        Class<?> aClass = Class.forName("com.hspedu.Student");
        // 1.获取本类及其父类的public修饰的属性
        Field[] fields = aClass.getFields();
        for (Field field : fields) {
            System.out.println("本类及其父类的public修饰的属性: " + field.getName());
        }
        // 2.获取父类的public修饰的属性
        Class<?> superclass3 = aClass.getSuperclass();
        Field[] fields1 = superclass3.getFields();
        for (Field field : fields1) {
            System.out.println("父类的public修饰的属性: "+field.getName());
        }
        // 3.获取本类中的所有属性
        Field[] declaredFields1 = aClass.getDeclaredFields();
        for (Field declaredField : declaredFields1) {
            System.out.println("本类的所有属性: " + declaredField.getName());
        }
        // 4.获取父类的所有属性
        Class<?> superclass = aClass.getSuperclass();
        Field[] declaredFields2 = superclass.getDeclaredFields();
        for (Field field : declaredFields2) {
            System.out.println("父类的所有属性: " + field.getName());
        }

        // 5.获取本类以及父类的public修饰的方法
        Method[] methods = aClass.getMethods();
        for (Method method : methods) {
            System.out.println("本类以及父类的public修饰的方法: " + method.getName());
        }

        // 6.获取父类的public修饰的方法
        Class<?> superclass1 = aClass.getSuperclass();
        Method[] methods1 = superclass1.getMethods();
        for (Method method : methods1) {
            System.out.println("父类的public修饰的方法: " + method.getName());
        }

        // 7.获取本类的所有方法
        Method[] declaredMethods = aClass.getDeclaredMethods();
        for (Method declaredMethod : declaredMethods) {
            System.out.println("本类的所有方法: " + declaredMethod.getName());
        }

        // 8.获取父类的所有方法
        Class<?> superclass2 = aClass.getSuperclass();
        Method[] declaredMethods1 = superclass1.getDeclaredMethods();
        for (Method method : declaredMethods1) {
            System.out.println("父类的所有方法: " + method.getName());
        }

        // 9.获取本类的public修饰的无参构造器
        Constructor<?>[] constructors = aClass.getConstructors();
        for (Constructor<?> constructor : constructors) {
            System.out.println("本类的public修饰的无参构造器: " + constructor.getName());
        }
        // 获取本类指定的带参构造器
        Constructor<?> constructor1 = aClass.getConstructor(String.class, String.class);
        System.out.println(constructor1);

        // 10.获取父类的public修饰的无参构造器
        Class<?> superclass4 = aClass.getSuperclass();
        Constructor<?>[] constructors1 = superclass4.getConstructors();
        for (Constructor<?> constructor : constructors1) {
            System.out.println("父类的public修饰的无参构造器: " + constructor.getName());
        }
        // 获取父类指定的带参构造器
        Constructor<?> constructor = superclass4.getConstructor(String.class, int.class);
        System.out.println(constructor);

        // 11.获取本类所有的构造器
        Constructor<?>[] declaredConstructors = aClass.getDeclaredConstructors();
        for (Constructor<?> declaredConstructor : declaredConstructors) {
            System.out.println(declaredConstructor);
        }

        // 12.获取父类的所有构造器
        Class<?> superclass5 = aClass.getSuperclass();
        Constructor<?>[] declaredConstructors1 = superclass5.getDeclaredConstructors();
        for (Constructor<?> constructor2 : declaredConstructors1) {
            System.out.println(constructor2);
        }

        // 13.获取本类的实现的接口
        Class<?>[] interfaces = aClass.getInterfaces();
        for (Class<?> anInterface : interfaces) {
            System.out.println(anInterface);
        }


    }
}

interface i1 {

}

interface i2 {

}

class Person {
    private String name;
    int age;
    protected String nation;
    public String gender;

    public Person() {}
    public Person(String name,int age){
        this.name = name;
        this.age = age;
    }
    private Person(String name, String nation) {
        this.name = name;
        this.nation = nation;
    }

    public void p1(){

    }
    protected void p2(){

    }
    void p3(){

    }
    private void p4(){

    }

}

class Student extends Person implements i1,i2{
    private String stuId;
    String hobby;
    protected String job;
    public int height;

    public Student(){}
    public Student(String stuId,String hobby){
        this.stuId = stuId;
        this.hobby = hobby;
    }
    private Student(String stuId,int height){
        this.height = height;
        this.stuId = stuId;
    }

    public void s1(){

    }
    protected void s2(){

    }
    void s3(){

    }
    private void s4(){

    }
}

 运行结果:

本类及其父类的public修饰的属性: height
本类及其父类的public修饰的属性: gender
父类的public修饰的属性: gender
本类的所有属性: stuId
本类的所有属性: hobby
本类的所有属性: job
本类的所有属性: height
父类的所有属性: name
父类的所有属性: age
父类的所有属性: nation
父类的所有属性: gender
本类以及父类的public修饰的方法: s1
本类以及父类的public修饰的方法: p1
本类以及父类的public修饰的方法: wait
本类以及父类的public修饰的方法: wait
本类以及父类的public修饰的方法: wait
本类以及父类的public修饰的方法: equals
本类以及父类的public修饰的方法: toString
本类以及父类的public修饰的方法: hashCode
本类以及父类的public修饰的方法: getClass
本类以及父类的public修饰的方法: notify
本类以及父类的public修饰的方法: notifyAll
父类的public修饰的方法: p1
父类的public修饰的方法: wait
父类的public修饰的方法: wait
父类的public修饰的方法: wait
父类的public修饰的方法: equals
父类的public修饰的方法: toString
父类的public修饰的方法: hashCode
父类的public修饰的方法: getClass
父类的public修饰的方法: notify
父类的public修饰的方法: notifyAll
本类的所有方法: s4
本类的所有方法: s3
本类的所有方法: s1
本类的所有方法: s2
父类的所有方法: p4
父类的所有方法: p3
父类的所有方法: p1
父类的所有方法: p2
本类的public修饰的无参构造器: com.hspedu.Student
本类的public修饰的无参构造器: com.hspedu.Student
public com.hspedu.Student(java.lang.String,java.lang.String)
父类的public修饰的无参构造器: com.hspedu.Person
父类的public修饰的无参构造器: com.hspedu.Person
public com.hspedu.Person(java.lang.String,int)
private com.hspedu.Student(java.lang.String,int)
public com.hspedu.Student(java.lang.String,java.lang.String)
public com.hspedu.Student()
private com.hspedu.Person(java.lang.String,java.lang.String)
public com.hspedu.Person(java.lang.String,int)
public com.hspedu.Person()
interface com.hspedu.i1
interface com.hspedu.i2
View Code

 

标签:aClass,java,String,反射,println,修饰,父类,public
From: https://www.cnblogs.com/zwgitOne123/p/17058019.html

相关文章