Java中的反射(1)

Java中的反射

一、概念:

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

2、反射 (Reflection) 是 Java 的特征之一,它允许运行中的 Java 程序获取自身的信息,并且可以操作类或对象的内部属性。

Oracle 官方对反射的解释是:

Reflection enables Java code to discover information about the fields, methods and constructors of loaded classes, and to use reflected fields, methods, and constructors to operate on their underlying counterparts, within security restrictions.
 The API accommodates applications that need access to either the public members of a target object (based on its runtime class) or the members declared by a given class. It also allows programs to suppress default reflective access control.

In a word,通过反射,我们可以在运行时获得程序或程序集中每一个类型的成员和成员的信息。程序中一般的对象的类型都是在编译期就确定下来的,而 Java 反射机制可以动态地创建对象并调用其属性,这样的对象的类型在编译期是未知的。所以我们可以通过反射机制直接创建对象,即使这个对象的类型在编译期是未知的。

3、反射的核心是 JVM 在运行时才动态加载类或调用方法/访问属性,它不需要事先(写代码的时候或编译期)知道运行对象是谁。

4、反射就是把java类中的各种成分映射成一个个的Java对象

例如:一个类有:成员变量、方法、构造方法、包等等信息,利用反射技术可以对一个类进行解剖,把个个组成部分映射成一个个对象。

二、Class类的使用

1、在面向对象的世界里,万事万物皆对象。

Java语言中,静态的成员、普通的数据类型类是不是对象呢?

类是谁的对象呢?

类是对象,类是java.lang.Class类的实例对象

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

There is a class named Class

2.案例

package com.tedu.reflect;
public static ClassDemo{
	public static void main(String[] args){
		//Foo的实例对象如何表示
		Foo foo1=new Foo();
		//Foo这个类也是一个实例对象,Class类的实例对象,如何表示呢?
		//任何一个类都是Class的实例对象,这个实例对象有三种表达方式
			//1、实际告诉我们任何一个类都有一个隐含的静态成员
			Class c1=Foo.class;
			//2、已知该类的对象通过getClass方法
			Class c2=foo1.getClass();
			/*官网 c1,c2表示了Foo类的类类型(class type)
			*万事万物皆对象,类也是对象,是Class类的实例对象
			*这个对象我们称为该类的类类型
			**/
			//3、(有异常try.catch)
			Class c3=Class.forName("com.tedu.reflect.Foo");
		//通过类的类类型创建该类的对象实例——>通过c1/c2/c3创建的Foo的实例
				Foo foo=(Foo)c1.newInstanstance();//有异常try.catch
				
}
class Foo{

}

3.Class.forName(“类的全称”);

不仅代表了类的类类型,还代表了动态加载类

请大家区分编译和运行

编译时刻加载类是静态加载类,运行时刻加载类是动态加载类

//new创建对象是静态加载类,在编译时刻就需要加载所有的可能使用到的类

三、反射是什么呢?

当我们的程序在运行时,需要动态的加载一些类这些类可能之前用不到所以不用加载到jvm,而是在运行时根据需要才加载,这样的好处对于服务器来说不言而喻,举个例子我们的项目底层有时是用mysql,有时用oracle,需要动态地根据实际情况加载驱动类,这个时候反射就有用了,假设 com.java.dbtest.myqlConnection,com.java.dbtest.oracleConnection这两个类我们要用,这时候我们的程序就写得比较动态化,通过Class tc = Class.forName(“com.java.dbtest.TestConnection”);通过类的全类名让jvm在服务器中找到并加载这个类,而如果是oracle则传入的参数就变成另一个了。这时候就可以看到反射的好处了,这个动态性就体现出java的特性了!举多个例子,大家如果接触过spring,会发现当你配置各种各样的bean时,是以配置文件的形式配置的,你需要用到哪些bean就配哪些,spring容器就会根据你的需求去动态加载,你的程序就能健壮地运行。

1、Java 反射机制主要提供了以下功能

在运行时判断任意一个对象所属的类。

在运行时构造任意一个类的对象。

在运行时判断任意一个类所具有的成员变量和方法。

在运行时调用任意一个对象的方法

反射的常用类和函数:Java反射机制的实现要借助于4个类:Class,Constructor,Field,Method;

其中class代表的是类对象,Constructor-类的构造器对象,Field-类的属性对象,Method-类的方法对象,通过这四个对象我们可以粗略的看到一个类的各个组成部分。其中最核心的就是Class类,它是实现反射的基础,它包含的方法我们在第一部分已经进行了基本的阐述。应用反射时我们最关心的一般是一个类的构造器、属性和方法,下面我们主要介绍Class类中针对这三个元素的方法:

1、得到构造器的方法

Constructor getConstructor(Class[] params) -- 获得使用特殊的参数类型的公共构造函数, 
Constructor[] getConstructors() -- 获得类的所有公共构造函数 
Constructor getDeclaredConstructor(Class[] params) -- 获得使用特定参数类型的构造函数(与接入级别无关) 
Constructor[] getDeclaredConstructors() -- 获得类的所有构造函数(与接入级别无关) 

2、获得字段信息的方法

Field getField(String name) -- 获得命名的公共字段 
Field[] getFields() -- 获得类的所有公共字段 
Field getDeclaredField(String name) -- 获得类声明的命名的字段 
Field[] getDeclaredFields() -- 获得类声明的所有字段 

3、获得方法信息的方法

Method getMethod(String name, Class[] params) -- 使用特定的参数类型,获得命名的公共方法 
Method[] getMethods() -- 获得类的所有公共方法 
Method getDeclaredMethod(String name, Class[] params) -- 使用特写的参数类型,获得类声明的命名的方法 
Method[] getDeclaredMethods() -- 获得类声明的所有方法 

在程序开发中使用反射并结合属性文件,可以达到程序代码与配置文件相分离的目的,反射机制让代码具有通用性,可变化的内容都是写到配置文件中,修改配置文件创建的对象不一样了,调用的方法也不同了,但Java代码不需要做任何改动。

如果我们想要得到对象的信息,一般需要“引入需要的‘包.类’的名称——通过new实例化——取得实例化对象”这样的过程。使用反射就可以变成“实例化对象——getClass()方法——得到完整的‘包.类’名称”这样的过程。

正常方法是通过一个类创建对象,反射方法就是通过一个对象找到一个类的信息。

四、 补充:

1、如果只希望一个类的静态代码块执行,其他一律不执行可以使用:

​ Class.forName(“完整类名”);

​ 这个方法的执行会导致类加载类时静态代码块执行

2、元注解中@Retention(RetentionPolity.SOURCE)表示该注解只被保留在Java源文件中

​ @Retention(RetentionPolity.CLASS)表示该注解被保留在CLASS文件中

​ @Retention(RetentionPolity.RUNTIME)表示该注解被保留在CLASS文件中并且可以被反射机制读取到

3、类路径:凡是在src下的都是类路径下,src是类的根路径

String path=Thread.currentThread().getContextClassLoader().getResource("相对路径").getPath();
Thread.currentThread()  当前线程对象
getContextClassLoader()  获得当前线程类加载器对象
getResource("相对路径")   获取资源,当前线程的类加载器默认从类的根路径下加载资源

采用以上代码,可以拿到一个文件的绝对路径

4、类加载器

专门负责加载的命令/工具 ClassLoader

JDK自带了三个类加载器

①启动类加载器(父加载器),专门加载:jre/lib/rt.jar

②扩展类加载器(母加载器),专门加载:jre/lib/ext/*.jar

③应用类加载器,加载classpath中的jar包(类)

双亲委派机制:为保证类加载安全,优先从启动类加载器加载,无法加载则通过扩展类加载器加载,无法加载才通过应用类加载器加载。

注:资料源自慕课网,知乎等平台,有错误之处希望大家及时指正,感谢大家。

热门文章

暂无图片
编程学习 ·

C语言 介绍

一.C的历史 编程语言的发展过程: 第1代语言 机器语言↓ 第2代语言 汇编语言↓ 第3代语言 高级语言——结构化:C,Fortran,Basic,Pascal↓分界线:1980s面向对象(OO):Algo,Simula67,Ada,SmallTalkC++,Java,C#结构化语言的缺陷: 操作和数据是分离的C语言的起源: 1969…
暂无图片
编程学习 ·

BIO、NIO、AIO基本概念

BIO 采用BIO通信模型的服务端,通常由一个独立的Acceptor线程负责监听客户端的连接,它接收到客户端连接请求之后为每个客户端创建一个新的线程进行链路处理,处理完成后,通过输出流返回应答给客户端,线程销毁。 BIO主要的问题在于每当有一个新的客户端请求接入时,服务端必须…
暂无图片
编程学习 ·

如何将PDF转换成jpg图片?教你2种免费方法

如何将PDF格式的文件转换成JPG图片?有时为了方便需要将PDF转成图片来使用,直接截图不仅耗费时间,而且像素很不清晰,有没有其他方便快捷转出高清图片的方法呢? 方法1: 这个方法最方便就在于不用下载安装软件,甚至都不需要注册登录,只要有网络,手机和电脑都能快速操作完…
暂无图片
编程学习 ·

怎么才能最短时、高效、踏实的学习 Python?

作者:飞绝眷岭 链接:https://www.zhihu.com/question/28530832/answer/58656332 来源:知乎 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。Dataquest 这个网站上提供了一系列和数据分析相关的python教程,从python基本语法到data analysis的基本函数…
暂无图片
编程学习 ·

TCP协议中的粘包分包问题

使用TCP协议进行网络游戏开发的时候,有粘包和分包两个问题。 粘包和分包是利用Socket在TCP协议下内部的优化机制,在使用TCP协议进行数据的传输进行通讯的时候,会出现粘包分包问题的话,是由于优化导致,即内部的数据传输机制所导致的。 在客户端调用Send()方法传送数据,每传…
暂无图片
中恒嘉业 ·

Heap Sort 讲解

Heap Sort sorts a group of unordered elements using the Heap data structure. The sorting algorithm using a Min Heap is as follows: Heapify all elements into a Min HeapRecord and delete the top elementPut to top element into an array T that stores all so
暂无图片
cgfy ·

8. 源码分析之ConsumeQueue

源码分析之ConsumeQueue 消息发送时数据在ConsumeQueue的落地 ​ 连续发送5条消息,消息是不定长,首先所有信息先放入 Commitlog中,每一条消息放入Commitlog的时候都需要上锁,确保顺序的写入。 ​ 当Commitlog写成功了之后。数据…
暂无图片
coreui ·

Heap Sort 讲解

Heap Sort sorts a group of unordered elements using the Heap data structure. The sorting algorithm using a Min Heap is as follows: Heapify all elements into a Min HeapRecord and delete the top elementPut to top element into an array T that stores all so
暂无图片
coreui ·

[react] 你觉得react上手快不快?它有哪些限制?

[react] 你觉得react上手快不快?它有哪些限制? 相对vue来说不快。 限制 需要学习JSX需要工程化的配置需要对原生JavaScript有相当的掌握react只是一个UI层面的库,像vue内置了动画处理、keep-alive等功能,react则需要去找第三方库…
暂无图片
未来博客 ·

Heap Sort 讲解

Heap Sort sorts a group of unordered elements using the Heap data structure. The sorting algorithm using a Min Heap is as follows: Heapify all elements into a Min HeapRecord and delete the top elementPut to top element into an array T that stores all so
暂无图片
未来博客 ·

[react] 你觉得react上手快不快?它有哪些限制?

[react] 你觉得react上手快不快?它有哪些限制? 相对vue来说不快。 限制 需要学习JSX需要工程化的配置需要对原生JavaScript有相当的掌握react只是一个UI层面的库,像vue内置了动画处理、keep-alive等功能,react则需要去找第三方库…
暂无图片
建站日记 ·

[react] 你觉得react上手快不快?它有哪些限制?

[react] 你觉得react上手快不快?它有哪些限制? 相对vue来说不快。 限制 需要学习JSX需要工程化的配置需要对原生JavaScript有相当的掌握react只是一个UI层面的库,像vue内置了动画处理、keep-alive等功能,react则需要去找第三方库…
暂无图片
建站日记 ·

STL Practice —— 【map (1)】

Description 给出学生姓名和分数&#xff0c;要求你输入姓名查询分数。 Input 输入包含T组测试数据。 开头是一个正整数T (0<T<10)&#xff0c;为测试数据数量。 对于每组测试数据&#xff0c;第一行是一个正整数N (0<N<100000)。 接下来有N行&#xff0c;每行包…
暂无图片
mfbz ·

AOV网是否存在回路-拓扑排序-C++

拓扑排序是对测试AOV网是否存在回路的方法&#xff01; 拓扑排序的过程中&#xff0c;由于需要查找所有以某顶点为尾的弧&#xff0c;即找到该顶点的所有出边&#xff0c;故图要采用邻接表的存储方式。但拓扑排序较邻接表的存储方式有一点不同&#xff0c;由于要查找入度为0的点…
暂无图片
mfbz ·

[react] 你觉得react上手快不快?它有哪些限制?

[react] 你觉得react上手快不快&#xff1f;它有哪些限制&#xff1f; 相对vue来说不快。 限制 需要学习JSX需要工程化的配置需要对原生JavaScript有相当的掌握react只是一个UI层面的库&#xff0c;像vue内置了动画处理、keep-alive等功能&#xff0c;react则需要去找第三方库…
暂无图片
珊珊日记 ·

AOV网是否存在回路-拓扑排序-C++

拓扑排序是对测试AOV网是否存在回路的方法&#xff01; 拓扑排序的过程中&#xff0c;由于需要查找所有以某顶点为尾的弧&#xff0c;即找到该顶点的所有出边&#xff0c;故图要采用邻接表的存储方式。但拓扑排序较邻接表的存储方式有一点不同&#xff0c;由于要查找入度为0的点…
暂无图片
珊珊日记 ·

8. 源码分析之ConsumeQueue

源码分析之ConsumeQueue 消息发送时数据在ConsumeQueue的落地 ​ 连续发送5条消息&#xff0c;消息是不定长&#xff0c;首先所有信息先放入 Commitlog中&#xff0c;每一条消息放入Commitlog的时候都需要上锁&#xff0c;确保顺序的写入。 ​ 当Commitlog写成功了之后。数据…