文章42
标签13
分类3

反射

反射

Class类

在面向对象的世界里,万事万物皆对象
class类也是对象,是java.lang.Class的实例对象

如何表示class这个对象

任何类都是Class的实例对象,这个实例对象有三种表示方法,在下方代码处演示

package com.greedring;

public class Test {
    public static void main(String[] args) {
        Foo foo1 = new Foo();
        //第一种表示方式 ==> 实际在告诉我们任何一个类都要有个隐含的静态成员变量class
        Class class1 = Foo.class;

        //第二种表示方式  已知改类的对象,通过getClass方法
        Class class2 = foo1.getClass();

        /*class1 和 class2 表示了Foo类的类类型(class type)
         *万事万物皆对象,
         *类也是对象,是Class类的实例对象
         *这个对象我们称为该类的类类型
         */
        //不管class1 或者 class2都代表了Foo类的类类型,一个类只可能是Class类的一个实例对象
        System.out.println(class1 == class2);

        //第三种表达方式
        Class class3 = null;
        try {
            class3 = Class.forName("com.greedring.Foo");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        System.out.println(class2 == class3);

        //可以通过类的类类型,创建该类的对象实例 ==> 可以通过class1、class2 or class3创建Foo的实例
        try {
            Foo foo = (Foo) class1.newInstance();
            foo.print();
        } catch (InstantiationException | IllegalAccessException e) {
            e.printStackTrace();
        }
    }
}

class Foo {
    void print(){
        System.out.println("Foo");
    }
}

Class.forName(类的全称)

既表示类的类型,又表示动态加载类
编译时刻加载类是静态加载类,运行时刻加载类是动态加载类

基本的数据类型、void关键字都存在类类型

package com.greedring;

import java.lang.reflect.Method;

public class Test {
    public static void main(String[] args) {
        String s = "hello";
        Test.printClassMessage(s);//通过反射获取Test中,所有String类的基本信息

        System.out.println("===================================================");

        Integer n1 = 1;
        Test.printClassMessage(n1);//通过反射获取Test中,所有Integer类的基本信息
    }


    /*
    打印类的信息,包括类的成员函数、成员变量
    obj 该对象所属类的信息
     */
    public static void printClassMessage(Object obj) {
        //要获取类的信息 首先要获取类的类类型
        Class c = obj.getClass();//传递的是哪个子类的对象 c就是该子类的类类型
        //获取类的名称
        System.out.println("类的名称为:" + c.getName());
        /*
        Method类,方法对象
        一个成员方法就是一个Method对象
        getMethods()方法获取的所有的public的函数,包含父类继承而来的
        getDeclaredMethods()获取的是所有该类自己声明的方法,不问访问权限
         */
        Method[] ms = c.getMethods();//c.getDeclaredMethods();
        for (int i = 0; i < ms.length; i++) {
            //得到方法的返回值类型的类类型
            Class returnType = ms[i].getReturnType();
            System.out.print(returnType.getName() + " ");
            //得到方法的名称
            System.out.print(ms[i].getName() + "(");
            //获取参数类型 ==> 得到的是参数列表类型的类类型
            Class[] paramTypes = ms[i].getParameterTypes();
            for (Class class1 : paramTypes) {
                System.out.print(class1.getName()+",");
            }
            System.out.println(")");
        }
    }
}

Java反射是什么

在运行过程中获取当前类的所有属性的方法

如何Java反射

编译====class字节码文件(class对象)====结果

每去创建对象的时候,JVM的过程:加载(将类文件读写到内存)、连接(安全检查)、实例化
在程序运行中,先获取class对象,通过class对象拿到当前类的所有属性和方法

本文作者:GreedRing
本文链接:http://greedring.com/2019/09/18/JavaSE21/
版权声明:本文采用 CC BY-NC-SA 3.0 CN 协议进行许可