【JavaSE】反射机制,Class类与动态代理 包括解除私有分装constructor.setAccessible(true)和class.getConstructor().newInstance


反射概要

Java Reflection

Reflection(反射)是被视为动态语言的关键,反射机制允许程序在执行期借助于Reflection API取得任何类的内部信息,并能直接操作任意对象的内部属性及方法

Java反射机制提供的功能

在运行时判断任意一个对象所属的类
在运行时构造任意一个类的对象
在运行时判断任意一个类所具有的成员变量和方法
在运行时调用任意一个对象的成员变量和方法
生成动态代理

Java反射机制研究及应用

反射相关的主要API:
java.lang.Class:代表一个类
java.lang.reflect.Method:代表类的方法
java.lang.reflect.Field:代表类的成员变量
java.lang.reflect.Constructor:代表类的构造方法

一、 Class类和实例化Class类对象

Class类

在Object类中定义了以下的方法,此方法将被所有子类继承:
      public final Class getClass()
以上的方法返回值的类型是一个Class类,此类是Java反射的源头, 实际上所谓反射从程序的运行结果来看也很好理解,即:可以通过对象反射求出类的名称

反射可以得到的信息:某个类的属性、方法和构造器、某个类到底实现了哪些接口。对于每个类而言,JRE 都为其保留一个不变的 Class 类型的对象。一个 Class 对象包含了特定某个类的有关信息。

  • Class本身也是一个类
  • Class 对象只能由系统建立对象
  • 一个类在 JVM 中只会有一个Class实例
  • 一个Class对象对应的是一个加载到JVM中的一个.class文件
  • 每个类的实例都会记得自己是由哪个 Class 实例所生成
  • 通过Class可以完整地得到一个类中的完整结构

在这里插入图片描述
注意:Declared代表全部,可以访问全部东西包括私有
因此有很多方法都类似 比如
getDeclaredConstructors();//获取类的所有构造方法,包括公有和私有的
getDeclaredMethods();//返回此Class对象所表示的类或接口的全部方法
getDeclaredFields();// 返回此Class对象所表示的类或接口的全部Field。

实例化Class类对象(四种方法)

前提:若已知具体的类,通过类的class属性获取,该方法 最为安全可靠,程序性能最高
      实例:Class clazz = String.class;

前提:已知某个类的实例,调用该实例的getClass()方法获取Class对象
      实例:Class clazz = “www.xyd.com”.getClass();

前提:已知一个类的全类名,且该类在类路径下,可通过Class类的静态方法forName()获取,可能抛出ClassNotFoundException(这个是最常用的)
      实例:Class clazz = Class.forName(“java.lang.String”);

其他方式(不做要求)
      ClassLoader cl = this.getClass().getClassLoader();
      Class clazz4 = cl.loadClass(“类的全类名”);

public class text {
   
    public static void main(String[] args) {
   
        Person p = new Person();
        Class clazz = p.getClass();//clazz对象中就包含对象p所属的Person类的所有的信息

        //实例化Class类对象
        Class c0 = Person.class;//通过类名.class创建指定类的Class实例

        Class c1 = p.getClass();//通过一个类的实例对象的getClass()方法,获取对应实例对象的类的Class实例

        try {
   
            //通过Class的静态方法forName(String className)来获取一个类的Class实例
            //forName(String className)方法中的参数是你要获取的Class实例的类的全路径(包名.类名)
            Class c2 = Class.forName("D:\\JavaProjects\\b站草稿\\反射\\src\\Person.java");
            //这个是获取Class实例的常用方式
        } catch (ClassNotFoundException e) {
   
            e.printStackTrace();
        }
    }
}

二、运行时创建类对象并获取类的完整结构

实现的全部接口: Interface

所继承的父类: Superclass

全部的构造器: Constructor

全部的方法: Method

全部的Field: Field

1.实现的全部接口和继承的父类

使用反射可以取得:
1.实现的全部接口
      public Class<?>[] getInterfaces()
确定此对象所表示的类或接口实现的接口。

2.所继承的父类
      public Class<? Super T> getSuperclass()
返回表示此 Class 所表示的实体(类、接口、基本类型)的父类的 Class。

public class text1 {
   
    public static void main(String[] args) {
   
        try {
   
            Class clazz = Class.forName("Student");//通过包名.类名的字符串,调用Class.forName方法获取指定类的Class实例

            Class superclazz = clazz.getSuperclass();//获取父类
            System.out.println("父类:" + superclazz.getName());

            Class[] interfaces = clazz.getInterfaces();//获取接口
            for (Class anInterface : interfaces) {
   
                System.out.println("接口:" + anInterface);
            }

        } catch (ClassNotFoundException e) {
   
            e.printStackTrace();
        }
    }
}

2.获取公有的构造器和包括私有的全部构造器

public Constructor[] getConstructors( )
     返回此 Class 对象所表示的类的所有public构造方法。
public Constructor[] getDeclaredConstructors( )
     返回此 Class 对象表示的类声明的所有构造方法。

Constructor类中:
     取得修饰符: public int getModifiers( );
     取得方法名称: public String getName( );
     取得参数的类型:public Class<?>[] getParameterTypes( );


import java.lang.reflect.Constructor;
import java.lang.reflect.TypeVariable;

public class text2 {
   
    public static void main(String[] args) {
   
        try {
   
            Class clazz = Class.forName("Student");//通过包名.类名的字符串,调用Class.forName方法获取指定类的Class实例

            Constructor[] constructors = clazz.getConstructors();//获取public的方法
            for (Constructor c : constructors) {
   
                //getModifiers取得方法的修饰符,返回数组1代表public
                System.out.println("方法名为:" + c.getName() + "修饰符为:" + c.getModifiers());
            }

            //输出方法加参数
            for (Constructor c1 : constructors) {
   
                System.out.println(c1);
            }

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


            Constructor[] constructors1 = clazz.getDeclaredConstructors();//获取类的所有构造方法,包括公有和私有的
            for (Constructor c1 : constructors1) {
   
                //getModifiers取得方法的修饰符,返回数组1代表public,返回数组2代表是private
                System.out.println("方法名为:" + c1.getName() + "修饰符为:" + c1.getModifiers());
            }
        } catch (ClassNotFoundException e) {
   
            e.printStackTrace();
        }
    }
}
//
方法名为:Student修饰符为:1
方法名为:Student修饰符为:1
public Student(java
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值