1,什么是反射

反射机制是java语言提供的一种基础功能,它能够赋予成语在运行时进行自省的能力。通过反射我们可以直接操作类或者对象,例如:可以通过反射去获取某个对象的类的定义,属性,方法,还可以修改类的定义。

2,反射中的包

2.1反射包

java中专门的反射包java.lang.reflect,反射包下包含了很多类,具体可以参考jdk,这里我们用到的有Field类的成员变量,Method方法,Constructor构造器。

2.2AccessibleObject

关于反射有一点需要特意注意一下,就是反射包提供的AccessibleObject类中的setAccessible方法。

他的子类很多也重写了这个方法,这里的所谓的setAccessible顾名思义,就是指的是成员变量前面的用于修饰的public、protected、private,这个方法也就意味着我们可以在运行时通过反射去修改类的成员变量的访问限制。

setAccessible的应用场景非常广泛,各种框架:开发、测试、依赖注入。例如在数据库O/R Mapping框架中,我们在加载或者持久化数据的时候,框架通常会利用反射做这个事情,而不需要开发者自己去实现。

还有个典型的应用场景,就是绕过API的访问控制。我们在开发的过程中,有时候,可能需要调用内部的API去做一些事情,比如,自定义的高性能的NIO框架需要显示的释放DirectBuffer,使用反射绕开限制是一种常见的办法。

2.2Modifier

反射包中还有一个重要的类Modifier,该类是静态类,其中的方法也是静态方法。 

Modifier.Class类中getModifiers()函数返回一个用于描述类,构造器,方法和域的修饰符的整形数值。、 

调用Modifier.toString()方法将整型数值转变成字符串,也是就我们熟悉的public,private,static,final等修饰符。

2.3代码实例

/**
* 创建一个user类
* 可不在与main方法同一个类中创建
*/
class User{ //定一个成员变量:姓名
private String name; //无参构造
public User(){}
//有参构造
public User(String name) {
this.name = name;
}
//get方法
public String getName() {
return name;
}
//set方法
public void setName(String name) {
this.name = name;
}
}
/**
* 测试Class类的函数和反射库中的函数
*/
public class TestReflectController { public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException, NoSuchFieldException { //获得User类的Class对象
Class<?> cc = User.class; //下面这个是通过new出来的对象,并通过set给成员变量赋值
User user1 = new User();
user1.setName("hello");
//下面这个是通过构造器的方式 //1.有参构造器
//先得到有参构造器的信息,再根据构造器的信息,由newInstance()函数创建一个User对象
Constructor<?> constructor = cc.getConstructor(String.class);
//这个constructor.newInstance方法就是反射包下java.lang.reflect.Constructor类下的newInstance方法
User user2 = (User) constructor.newInstance("world");
System.out.println(user1.getName());//hello
System.out.println(user2.getName());//world //2.无参构造器
Constructor<?> constructor1 = cc.getConstructor();
//无参构造不能够像1一样赋值
//User user3 = (User) constructor1.newInstance("熊本");
User user3 = (User) constructor1.newInstance();
user3.setName("熊本");
System.out.println(user3.getName());//熊本 //由无参构造器创建对象时,可不必获得构造器,直接由Class对象调用newInstance()方法。
Class<?> cc2 = User.class;
User user4 = (User) cc2.newInstance();
user4.setName("同学");
System.out.println(user4.getName());//同学 //3.下面2个输出语句可看出cc保存类信息,输出的是“class + 类名”。cc.newInstance()是具体类的对象。
System.out.println(cc);//class com.newframe.controllers.api.User
System.out.println(cc.newInstance());//com.newframe.controllers.api.User@3a03464 //4.AccessibleObject、Field类
//首先得到有参构造函数的信息,然后根据构造函数实例化一个对象。
//由getDeclaredField()函数得到类里面的私有成员变量,访问私有成员变量要用setAccessible()函数设置访问权限。
//Field类对象得到成员变量后还可以设置该变量的值,使用set()方法。
Constructor<?> constructor2 = cc.getConstructor(String.class);
User user5 = (User) constructor2.newInstance("改变前:100");
Field field = cc.getDeclaredField("name");
field.setAccessible(true);
field.set(user5,"改变后:50");
System.out.println(user5.getName());//改变后:50 //5.Method.invoke
//首先根据获得的构造函数信息实例化一个对象
//然后由函数名获得类中的公有函数,getMethod("函数名")
//invoke()方法执行由getMethod()获得的函数,这里获得的函数是getter()
//对于获得的有参函数,invoke(对象)里只添加对象名。
Constructor<?> constructor3 = cc.getConstructor(String.class);
User user6 = (User) constructor3.newInstance("你好世界");
//getName是User实体类中的方法
System.out.println(cc.getMethod("getName").invoke(user6));//你好世界 //对于获得到的无参函数,在调用getMethod()函数时,要在getMethod()中指定被获得函数的"函数名"和"参数类型"
//并且在执行该函数(即调用invoke()函数时),要指定对象和参数类型的具体实例。
User user7 = (User) cc.newInstance();
Method method = cc.getMethod("setName", String.class);
method.invoke(user7,"你好哇,这个世界");
System.out.println(user7.getName());//你好哇,这个世界 //6.Modifier类
//Class类中getModifiers()函数返回一个用于描述类,构造器,方法和域的修饰符的整形数值。、
//调用Modifier.toString()方法将整型数值转变成字符串,也是就我们熟悉的public,private,static,final等修饰符。
System.out.println(Modifier.toString(cc.getModifiers()));//无
System.out.println(Modifier.toString(constructor.getModifiers()));//public
System.out.println(Modifier.toString(field.getModifiers()));//private
System.out.println(Modifier.toString(method.getModifiers()));//public //同时,Modifier类还有一些判断修饰符是不是某一类型的方法。
System.out.println(Modifier.isPublic(cc.getModifiers()));
System.out.println(Modifier.isPublic(constructor.getModifiers())); }
}

3,数组的反射

public class TestReflectArray {

    public static void main(String[] args) throws ClassNotFoundException {
//新建4个不同的数组
//一维数组
int[] a = new int[3];
int[] b = new int[4];
//二维数组
int[][] c = new int[3][4];
//String类型的数组
String[] d = new String[3]; //可以对比各个数组所属的类是否相同
System.out.println(a.getClass() == b.getClass());//true
//System.out.println(a.getClass() == c.getClass());不同类型的数组不同比较
System.out.println(a.length == c.length);//但是可以比较长度,true
System.out.println(a.getClass().getName());//[I
System.out.println(d.getClass().getName());//[Ljava.lang.String;
System.out.println(a.getClass().getSuperclass().getName());//java.lang.Object //利用反射生成一个数组
int[] e = (int[]) Array.newInstance(int.class,3);
//0为数组索引下标,1为数字值
Array.set(e,0,1);
Array.set(e,1,2);
Array.set(e,2,3);
System.out.println(Array.get(e,0));
System.out.println(Array.get(e, 1));
System.out.println(Array.get(e, 2)); //利用反射获取数组类型常用的一些方式
Class<?> cc = String[].class;
Class<?> cc1 = Class.forName("[I");
Class<?> cc2 = Class.forName("[Ljava.lang.String;"); System.out.println(cc);
System.out.println(cc1);
System.out.println(cc2); //通过已有的对象获取数组的类型
Class<?> cc3 = e.getClass();
System.out.println(cc3);
//根据类型信息获取数组内成员的类型
Class<?> cc4 = cc3.getComponentType();
System.out.println(cc4);//int
}
}

java中的反射整理的更多相关文章

  1. Java中的反射和注解

    前言 在Java中,反射机制和注解机制一直是一个很重要的概念,那么他们其中的原理是怎么样呢,我们不仅仅需要会使用,更要知其然而之所以然. 目录 反射机制 反射如何使用 注解定义 注解机制原理 注解如何 ...

  2. java中的反射机制在Android开发中的用处

    JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法和属性:这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反 ...

  3. 浅说Java中的反射机制(二)

    写过一篇Java中的反射机制,不算是写,应该是抄了,因为那是别人写的,这一篇也是别人写的,摘抄如下: 引自于Java基础--反射机制的知识点梳理,作者醉眼识朦胧.(()为我手记) 什么是反射? 正常编 ...

  4. 浅说Java中的反射机制(一)

    在学习传智播客李勇老师的JDBC系列时,会出现反射的概念,由于又是第一次见,不免感到陌生.所以再次在博客园找到一篇文章,先记录如下: 引用自java中的反射机制,作者bingoideas.(()为我手 ...

  5. java中动态反射

    java中动态反射能达到的效果和python的语法糖很像,能够截获方法的实现,在真实方法调用之前和之后进行修改,甚至能够用自己的实现进行特别的替代,也可以用其实现面向切片的部分功能.动态代理可以方便实 ...

  6. 第89节:Java中的反射技术

    第89节:Java中的反射技术 反射技术是动态的获取指定的类,和动态的调用类中的内容(没有类前就可以创建对象,将对象的动作完成,这就是动态的获取指定的类). 配置文件把具体实现的类名称定义到配置文件中 ...

  7. java笔记十:java中的反射

    Java中,反射是一种强大的工具.它使您能够创建灵活的代码,这些代码可以在运行时装配,无需在组件之间进行源代表链接.反射允许我们在编写与执行时,使我们的程序代码能够接入装载到JVM中的类的内部信息,而 ...

  8. 【Java基础】java中的反射机制与动态代理

    一.java中的反射机制 java反射的官方定义:在运行状态下,可以获取任意一个类的所有属性和方法,并且可通过某类任意一对象实例调用该类的所有方法.这种动态获取类的信息及动态调用类中方法的功能称为ja ...

  9. java中使用反射获取pojo(实体)类的全部字段值

    说起反射.不得不说它实在是太强大了,通过反射就能够轻轻松松拿到各种东东,假设你想在项目中解除对某个类的依赖,能够考虑用反射. 今天跟大家分享的是通过java中的反射,获取pojo类的全部字段值. 为什 ...

随机推荐

  1. list转换string

    方法1 "".join 若list中为字符型 str = "".join(list) >>> L=['a','b','c'] >> ...

  2. 你们都在用IntelliJ IDEA吗?或许你们需要看一下这篇博文

    写在前面 以前一直用的elipce,如今入坑IntelliJ IDEA,没想到啊.深深的爱上了它,强大到无所不能: "工欲善其事必先利其器",IntelliJ IDEA作为一个非常 ...

  3. will not be managed by Spring/ [managed: 15; max: 15]

    检查事务配置 检查 mybatis 配置文件扫描路径是否正确 <!-- 自动扫描 --> <context:component-scan base-package="com ...

  4. redis实战笔记

    3.1 字符串命令 3.2 列表命令 3.3 集合命令 3.4散列命令 3.5有序集合命令 3.6发布与订阅命令 3.7其他命令 3.7.1 排序 3.7.2键的过期时间

  5. 分享一个VueCli 3.0的项目模板

    个人搭建的Vue项目模板 默认自带  Vuex  Less 封装内容如下 vue.config axios 封装 vue 配置环境文件 vue 自定义路径映射 (cli3.0取消了默认@ 映射src的 ...

  6. 论文笔记:Learning wrapped guidance for blind face restoration

    这篇论文主要是讲人脸修复的,所谓人脸修复,其实就是将低清的,或者经过压缩等操作的人脸图像进行高清复原.这可以近似为针对人脸的图像修复工作.在图像修复中,我们都会假设退化的图像是高清图像经过某种函数映射 ...

  7. python 字符串转化为json、post请求

    在json模块有2个方法, loads():将json数据转化成dict数据 dumps():将dict数据转化成json数据 load():读取json文件数据,转成dict数据 dump():将d ...

  8. Git初始配置和基本使用

    初次运行Git前的配置 本文是在安裝完git以后首先应做到一些配置,安装教程可以参考廖雪峰git教程 用户信息 当安装完 Git 应该做的第一件事就是设置你的用户名称与邮件地址. 这样做很重要,因为每 ...

  9. java----tomcat

    下载: 测试使用一般下载zip格式,在服务器上布置tomcat使用直接安装格式(install) https://tomcat.apache.org/download-90.cgi 使用 在windo ...

  10. 在被vue组件引用的 js 文件里获取组件实例this

    思路: 通过调用函数 把 组件实例this  传递 到 被应用的 js文件里 实例: 文件结构 在SendThis.vue 文件中引用 了modalConfig.js import modalConf ...