【Java基础】Java中的反射机制
一、反射的理解
(1)正射
在理解反射这个概念之前,我们先来理解Java中的“正射”。
我们在编写代码时,当需要使用到某一个类的时候,必定先会去了解这是一个什么类,是用来做什么的,有怎么样的功能。
之后我们才对这个类进行实例化,之后再使用这个类的实例化对象进行操作。
Person person = new Person();
person.sleep("8:00");
(2)反射
上面的栗子介绍了什么是“正射”,以及“正射”的一般代码实现;
而反射则是在代码一开始编写时不知道要初始化的类是什么。因此,自然也无法使用new关键字来创建对象了。
而当我们之后得到我们要初始化的类的名称及路径时,我们就可以使用JDK提供的反射API进行反射调用。
Class clazz = Class.forName("com.test.domain.Person");
Method method = clazz.getMethod("sleep", String.class);
Constructor constructor = clazz.getConstructor();
Object object = constructor.newInstance();
method.invoke(object, "8:00");
以上两段代码,其结果都是一样的,但是其实现的过程却有很大的差别:
- 第一段代码在未运行前就已经确定了要运行的类(Person);
- 第二段代码则是在整个程序运行时从某些地方(例:配置文件)获取到相应的字符串值才能知道要运行的类("com.test.domain.Person")。
二、反射的应用
在我们日常的生产环境中,很少会直接使用到反射,但这并不代表反射在实际应用中很少。相反反射在Java中的框架使用得十分的多,反射是框架设计的灵魂:
①:spring、hibernate中会使用到反射机制,最常见的就是使用XML配置文件获取对应的类,然后再加载;
②:真的好多啊。。。
三、反射的常用函数
(1)获取反射中的class对象
在反射中,要获取一个类或调用一个类的方法,首先必须要获取到该类的对象,在Java API中,获取Class类对象三种方法:
①:Class.forName("类的路径名");
Class clazz = Class.forName("com.test.domain.Person");
②:利用已有类对象的getClass()方法;
Person person = new Person();
Class clazz = person.getClass();
③:对于在编译前就已经知道的类,可以使用.class属性;
Class clazz = Person.class;
(2)通过反射创建类对象
通过反射建立类的对象,Java API提供了两种方式:
①:通过class对象的newInstance()方法;
Class clazz = Class.forName("com.test.domain.Person");
Person person = (Person)clazz.newInstance();
②:通过Constructor对象的newInstance()方法;
Class clazz = Class.forName("com.test.domain.Person");
Constructor con = clazz.getConstructor();
Person person = (Person)con.newInstance();
(3)通过反射操作成员变量
①:获取所有成员getFields()&getDeclaredFields();
使用getFields()方法可以获取Class类的成员变量,但是无法获取私有属性。
Class clazz = Class.forName("com.test.domain.Person");
Field[] fields = clazz.getFields();
for (Field field : fields) {
System.out.print(field.getName());
}
②:获取单个成员getField()&getDeclared
③:修改成员变量的值set(Object obj, Object value)
Class clazz = Class.forName("com.test.domain.Person");
Person person = (Person)clazz.newInstance();
Field field = clazz.getField("name");
field.set(person, "张三");
当属性为private时,这是我们无法直接使用set()方法修改它的值,此时应该使用setAccessible()方法取得访问权限:
Class clazz = Class.forName("com.test.domain.Person");
Person person = (Person)clazz.newInstance();
Field field = clazz.getDeclaredField("name");
field.setAccessible(true);
field.set(person, "张三");
(4)通过反射操作成员方法
①:获取所有方法getMethods()&getDeclaredMethods()
②:获取单个成员getMethod()&getDeclaredMethod()
操作方法与操作变量相差不大,在获取到对应方法之后使用invoke()方法执行即可。同理,遇见私有方法时,也需要使用setAccessible(true)方法获取访问权限。
Class clazz = Class.forName("com.test.domain.Person");
Person person = (Person)clazz.newInstance();
Method method = clazz.getMethod("setName", String.class);
method.setAccessible(true);
method.invoke("李四");
注:通常情况下,即便得到的是当前类,private修饰的属性或方法也是没有权限访问的,你需要设置访问权限setAccessible(true)来取得访问权限,但在实际上,这已经破坏了规则,所以应该尽量少地使用。
【Java基础】Java中的反射机制的更多相关文章
- Java基础系列 - 泛型和反射机制
package com.test5; import java.lang.reflect.Field; import java.lang.reflect.Method; /** * Java泛型和反射机 ...
- 【Java基础】java中的反射机制与动态代理
一.java中的反射机制 java反射的官方定义:在运行状态下,可以获取任意一个类的所有属性和方法,并且可通过某类任意一对象实例调用该类的所有方法.这种动态获取类的信息及动态调用类中方法的功能称为ja ...
- 浅说Java中的反射机制(二)
写过一篇Java中的反射机制,不算是写,应该是抄了,因为那是别人写的,这一篇也是别人写的,摘抄如下: 引自于Java基础--反射机制的知识点梳理,作者醉眼识朦胧.(()为我手记) 什么是反射? 正常编 ...
- Java开发培训基础知识解析之反射机制
Java是老牌编程语言,是当前应用最广泛的编程语言之一.想要学习Java你就一定要掌握Java基础知识,而反射对于初学Java的人来说绝对是非常重要的知识点.什么是反射?如何理解反射机制?如何使用反射 ...
- java中的反射机制在Android开发中的用处
JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法和属性:这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反 ...
- java中的反射机制,以及如何通过反射获取一个类的构造方法 ,成员变量,方法,详细。。
首先先说一下类的加载,流程.只有明确了类这个对象的存在才可以更好的理解反射的原因,以及反射的机制. 一. 类的加载 当程序要使用某个类时,如果该类还未被加载到内存中,则系统会通过加载,连接,初始化三 ...
- 浅说Java中的反射机制(一)
在学习传智播客李勇老师的JDBC系列时,会出现反射的概念,由于又是第一次见,不免感到陌生.所以再次在博客园找到一篇文章,先记录如下: 引用自java中的反射机制,作者bingoideas.(()为我手 ...
- Java基础-Java中的堆内存和离堆内存机制
Java基础-Java中的堆内存和离堆内存机制 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任.
- Java基础-Java中的内存分配与回收机制
Java基础-Java中的内存分配与回收机制 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一. 二.
- java 中利用反射机制获取和设置实体类的属性值
摘要: 在java编程中,我们经常不知道传入自己方法中的实体类中到底有哪些方法,或者,我们需要根据用户传入的不同的属性来给对象设置不同的属性值,那么,java自带的反射机制可以很方便的达到这种目的,同 ...
随机推荐
- RecyclerView 添加自定义分割线
默认的浅灰色的分割线在某些时候并不能满足我们的要求,这时就需要自定义分割线了. 我们可以通过两种方式来实现:调用 DividerItemDecoration.setDrawable 方法或者继承实现 ...
- iOS 13 presentViewController
升级了iOS 13,发现代码中使用presentViewController的都变成了这样的,顶部留了一部分 查看present样式,iOS 13 默认自动适配,需要在present的时候,设置sty ...
- canves做的时钟目前已经开源
canves做的时钟目前已经开源 git地址: https://github.com/jidanji/canves-clock/tree/1.0.1 项目截图 时流过的时间变得有颜色,其他的没有颜色.
- Centos7启动防火墙时报错Failed to start IPv4 firewall with iptables
今天在虚拟机的Linux系统(centos7)里安装Redis,准备学习一下布隆过滤器呢,安装完后使用Windows本机访问不了虚拟机里的Redis,telnet不通能够ping通.于是就去看防火墙, ...
- 从零开始的vue学习笔记(一)
前言 项目要用vue.js,今天开始自学vue.js官方教程,记录下自己的学习摘要,方便后面查阅(此笔记按照学习天数,每天一篇) Vue.js是什么 Vue是一套用于构建用户界面的渐进式框架,Vue ...
- python3 TensorFlow训练数据集准备 下载一些百度图片 入门级爬虫示例
从百度图片下载一些图片当做训练集,好久没写爬虫,生疏了.没有任何反爬,随便抓. 网页: 动态加载,往下划会出现更多的图片,一次大概30个.先找到保存每一张图片的json,其对应的url: 打开调试,清 ...
- 《C#并发编程经典实例》学习笔记—2.8 处理 async Task 方法的异常
异常处理一直是所有编程语言不可避免需要考虑的问题,C#的异步方法的异常处理和同步方法并无差别,同样要借助 try catch 语句捕获异常. 首先编写一个抛出异常的方法 static async Ta ...
- Java实现Kafka的生产者和消费者例子
Kafka的结构与RabbitMQ类似,消息生产者向Kafka服务器发送消息,Kafka接收消息后,再投递给消费者.生产者的消费会被发送到Topic中,Topic中保存着各类数据,每一条数据都使用键. ...
- zhy2_rehat6_mysql02 - 5.7主从搭建.txt
1.0------------锁库: mysql>FLUSH TABLES WITH READ LOCK; 这个命令是全局读锁定,执行了命令之后所有库所有表都被锁定只读.一般都是用在数据库联机备 ...
- ES6.x
类 class Animal{ constructor(name){ this.name=name } Spack(){ console.log(name) } } class Dog extends ...