第一章 反射

第一章 反射

 

什么是反射(Reflection)? 反向 映射

编译时不确定哪个类被加载,在运行时才加载 探知 使用。 (能够在运行时,观察并修改自己运行时行为的特性)

主要的功能:

在运行时判断任意一个对象所属的类 在运行时构造任意一个类的对象 初始的类.class 的类型是Class 实例化对象的 类.getClass 的类型是 实例化对象的类 在运行时判断任意一个类所具有的属性和方法 所有的包括超类等等 在运行时调用任意一个对象的方法

java程序正常走的时候,不知道私有的属性和方法 也不能使用 反射是运行时就可以知道私有的属性 方法也能使用!

Java反射常用API java.lang.Class<T>类:核心类 通过Class类获取类的属性 方法等内容信息 java.lang.reflect.Constructor<T>类:表示类的构造方法 java.lang.reflect.Field类:表示类的属性 java.lang.reflect.Method类:

使用反射的基本步骤

1.导入java.lang.reflect.*; 2.获得需要操作的类的java.lang.Class对象 3.调用Class的方法获取Field、Method等对象 4.使用反射API操作实例成员

类的类型或者对象是Class 属性是Field 方法 Method

反射入口类

Class是Java反射机制的起源和入口 1.每个类都有自己相关的Class对象 2.提供了获取类信息的相关方法

  1. Class类存放类的结构信息 类名 父类 接口 构造方法 方法 属性 注解

怎么获取Class实例?

1.对象实例.getClass() 2.类或者接口.class 3.Class.forName("完全限定名"); 运用工厂模式

获取类的基本信息

方法 说明 String getName() 以字符串形式返回该类型的名称 String getSimpleName() 以字符串形式返回该类型的简称 Package getpackage() 获取该类型所在的包 Class getSuperClass() 返回该类型的超类的Class实例 Class[] getInterfaces() 返回该类型的全部接口的Class实例 int getModifiers() 返回该类型的所有修饰符,由public private final static abstract对应的int常量组成,返回 的整数应由Modifier工具类解码 Class[] getDeclaredClasses() 返回该类型中包含的全部内部类的Class实例 Class getDelaringClass() 返回该类型所在的容器类的Class实例

if (sj2.getModifiers()== Modifier.PUBLIC){
   System.out.println("public");
}

 

反射实例化方法有两种:

1.newInstance(); 无参

Sj1 sj1 = Sj1.class.newInstance();

2.通过构造函数 可以无参 可以有参

try {
   //获取构造函数并反射实例化
   Constructor constructor = Sj1.class.getDeclaredConstructor(String.class);
   //设置访问权限
   constructor.setAccessible(true);
   //调用构造函数
   Object news = constructor.newInstance("News");
   Sj1 sj=(Sj1)news;
   System.out.println(sj.getName());
}catch (Exception e){
e.printStackTrace();
}

 

 

获取对应类型所包含构造方法的方法 可变参数 0~n个

Constructor getConstructor(Class..params) 返回该类型指定参数的public构造 方法,构造方法的参数列表与 params所指定的类型列表所匹配 Constructor[] getConstructors() 返回该类型的所有public构造方法 Constructor getDelaredConstructor(Class..params)返回该类型的指定参数的构造方法,访问级别不限 Constructor getDelaredConstructors()返回该类型的所有构造方法,访问级别不限

 

访问属性的方法

方法 说明

xxx getXxx(Object obj)xxx为数据类型,若表示的是一个静态属性,obj可以为null Object get(Object obj) 以Object返回obj中相关属性的值 void setXxx(Object obj,xxx val) 将obj中相关属性设置为val,xxx为数据类型 void set(Object obj,xxx val) 将obj中相关属性设置为val void setAccessible(boolean flag)对相关属性设置访问权限,设置为true可以禁 止Java语言访问检查,会破坏封装

 

   //通过反射加载一个实例  属性的操作
           Class aClass = Class.forName("entity.Yong");
           //获取实例
           Yong o =(Yong) aClass.newInstance();
           //获取username参数
           Field name = aClass.getDeclaredField("username");
           //设置权限
           name.setAccessible(true);
           //输出值
           System.out.println(name.get(o));
           //赋值
           name.set(o,"孙");
           System.out.println(name.get(o));

 

获取对应类型所包含方法的方法

 

Method getMethod(String name, 返回该类型中指定public方法,name指定 Class..params) 名称,params 指定参数列表 Method[] getDeclaredMethods() 返回该实例中所有的public方法 Method getDeclaredMethod(String name, 返回该类型中指定方法 Class..params) 与访问修饰符无关 Method[] getDeclaredMethods() 返回该实例中全部方法与访问修饰符无关

  try {
           //通过反射加载一个实例
           Class<?> aClass = Class.forName("entity.Yong");
           //获取实例
           Yong yong = (Yong) aClass.newInstance();
           //获取方法
           Method sd = aClass.getDeclaredMethod("sd");
           //设置权限
           sd.setAccessible(true);
           //调用方法
           sd.invoke(yong);
      } catch (Exception e) {
e.printStackTrace();
      }

 

调用方法 invoke();

invoke(Object obj,Object...params) 在源代码中我们看到return ((Boolean) super.h.invoke(this, m1, new Object[] { obj })) .booleanValue(); 那么this就是$Proxy0 对象。这里需要注意的是,它并非是被代理对象(ManagerImpl)。其第二个参数传递的是$Proxy0 类中数据域,其类型是Method,是被封装过的被代理对象(ManagerImpl)的方法

如果调用静态的方法,第一个参数为null

 

Array类的部分常用方法

 

static Object newInstance(Class componentType创建元素类型为componentType ,int length) 长度为length的数组 static Object newInstance(Class componentType创建元素类型为componentType ,int.. demensions) 维度是demensions.length,长度为demensions中元素 的长度的数组 static int getLength(Object arr) 返回数组arr的长度 static xxx getXxx(Object obj,int index) 以基本数据类型返回数组arr中索引 为index的元素 static xxx getXxx(Object obj,int index) 以Object类型返回数组arr中索引 为index的元素 staticvoid setXxx(Object obj,int index,xxx val) 将val设置为数组arr中索引 为index的元素 static xxx set(Object obj,Object index) 将val设置为数组arr中索引 为index的元素

posted @ 2021-01-04 10:13  编码小高  阅读(53)  评论(0编辑  收藏  举报