Java反射机制

《Scratch图形化等级考试(1~4级)历届真题解析》专栏总目录 ❤️ 专栏名称:《🌸 专栏介绍:中国电子学会《全国青少年软件编程等级考试》Scratch图形化等级考试(1~4级)历届真题解析。🚀 订阅专栏:原价 99.9,🔥 火爆订阅中 🔥,限时 19.9。订阅后可阅读专栏内所有文章,本专栏持续更新中,欢迎订阅! 阅读详情
一、什么是反射机制

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

二、Java反射机制提供的功能

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

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

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

(4)在运行时调用任意一个对象的成员变量和方法。

(5)生成动态代理。

三、反射机制的优点与缺点

优点:

(1)能够运行时动态获取类的实例,大大提高系统的灵活性和扩展性。

(2)与Java动态编译相结合,可以实现无比强大的功能。

缺点:

(1)使用反射的性能较低

(2)使用反射相对来说不安全

(3)破坏了类的封装性,可以通过反射获取这个类的私有方法和属性。

四、如何创建Class实例

要想明白如何创建Class实例需要掌握以下4个知识点

1.创建Class实例的过程:源文件经过编译(javac.exe)以后,得到一个或多个.class文件。.class文件经过运行(java.exe)这步,就需要进行类的加载(通过JVM的类的加载器),记载到内存中的缓存,每一个放入缓存中的.class文件就是一个Class的实例。

2.Class的一个对象,对应着一个运行时类。相当于一个运行时类本身充当了Class的一个实例。

3.java.lang.Class是反射的源头。接下来涉及到反射的类都在java.lang.reflect子包下。

4.实例化Class的方法(三种)

    // 1.调用运行时类本身的.class属性
    Class clazz1 = Person.class;
    System.out.println(clazz1.getName());

    // 2.通过运行时类的对象获取
    Person p = new Person();
    Class clazz2 = p.getClass();
    System.out.println(clazz2.getName());

    // 3.通过Class的静态方法来获取,通过此方式,体会一下反射的动态性。
    String className = "cn.net.ecode.Person";
    Class clazz3 = Class.forName(className);
    System.out.println(clazz3.getName());
    
    System.out.println(clazz1 == clazz2);//true
    System.out.println(clazz1 == clazz3);//true

注:

(1)结果是 clazz1 、clazz2、clazz3为同一个对象,这里请记住一句话:所有的类都是 Class 类的对象。即类也是一个对象,它是Class的对象,它的类型称为类类型。

(2)对于开发而言,我更推荐使用第三种,原因很简单:因为第三种是一个字符串,而不是一个具体的类名,这样的话我们可以把这样的字符串配置在配置文件中去了,这样更方便后期代码的维护。

在这里大家可以根据下面这张图体会一下Java的反射机制。


五、有了Class实例以后可以做什么?

这个知识点我用一个实例来给大家分析一下,这里新建一个 Animal类,在整个案例中,我们都用到这个 Animal类来讲解。

Animal.java

public class Animal {
	private String name;
	public int age;
	static String desc = "我是一个动物";

	public Animal() {
		super();
	}

	private Animal(String name, int age) {
		super();
		this.name = name;
		this.age = age;
	}

	private int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	public static String getDesc() {
		return desc;
	}

	public static void setDesc(String desc) {
		Animal.desc = desc;
	}
	
	public static void info() {
		System.out.println("动物");
	}

	public void show(String desc) {
		System.out.println("我是一个:" + desc);
	}

	@Override
	public String toString() {
		return "Animal [name=" + name + ", age=" + age + "]";
	}

应用一:可以创建对应的运行时类的对象。

  //调用空参的构造器创建运行时类对象
	@Test
	public void test1() throws Exception {
		//获取Class对象,字符串为包名+类名
		Class clazz = Class.forName("review.Animal");
		// 创建运行时类的对象。使用newInstance(),实际上是调用了运行时类的空参的构造器。
		// 要想能够创建成功,①要求对应的运行时类要有空参的构造器。②构造器的权限修饰符的权限要足够。
		Object obj = clazz.newInstance();
		Animal animal = (Animal) obj;
		System.out.println(animal);
	}
	//调用指定构造器创建运行时类对象
	@Test
	public void test2() throws Exception {
		//获取Class对象
		Class clazz = Animal.class;
		//获取两参的构造方法,参数是个可变参数
		Constructor cons = clazz.getDeclaredConstructor(String.class,int.class);
		//设置取消访问检查,因为权限修饰符为private
		cons.setAccessible(true);
		//创建对象,参数为构造方法的实参
		Animal animal = (Animal)cons.newInstance("Tom",10);
		System.out.println(animal);
	}

此处有两个异常需要注意:

(1)由于Animal类的两参构造函数的权限修饰符为private,所以需要使用getDeclaredConstructor()来获取。否则会报java.lang.NoSuchMethodException异常。

(2)因为权限修饰符为private,要想访问这个构造函数,需要取消访问检查。否则会报java.lang.IllegalAccessException异常。

应用二:获取对应的运行时类的完整的类的结构。(我们可以获取到类的属性,方法,构造器,接口,泛型,异常,包,父类,内部类等结构,此处我们就用类的属性,方法,构造器来做讲解)

   //获取运行时类的构造器
     @Test
     public void test5() throws Exception {
	String className = "review.Animal";
	Class clazz = Class.forName(className);
	Constructor[] cons = clazz.getDeclaredConstructors();
	for (Constructor c : cons) {
           System.out.println(c);
	}
     } 

  //获取运行时类中所有的方法
     @Test
public void test3() {
	 Class clazz = Animal.class;
	 Method[] m2 = clazz.getDeclaredMethods();
	 for (Method m : m2) {
		 //1.获取方法的权限修饰符
		 String str = Modifier.toString(m.getModifiers());
		 System.out.print(str + " ");
		 //2.获取方法的返回值类型
		 Class returnType = m.getReturnType();
		 System.out.print(returnType.getName() + " ");
		 //3.获取方法的方法名
		 System.out.print(m.getName() + " ");

		 System.out.println();
	 }
      }
  //获取属性的各个部分的内容
  @Test
public void test4() {
	Class clazz = Animal.class;
	Field[] fields1 = clazz.getDeclaredFields();
	for (Field f : fields1) {
		//1.获取每个属性的权限修饰符
		int i = f.getModifiers();
		String str1 = Modifier.toString(i);
		System.out.print(str1 + " ");
		//2.获取每个属性的变量类型
		Class type = f.getType();
		System.out.print(type.getName() + " ");
		//3.获取属性名
		System.out.print(f.getName());

		System.out.println();
	}
  }
由此可以看出,有了Class实例后,我们可以获取到运行时类的完整结构。
应用三:可以调用对应的运行时类中指定的结构(某个指定的方法,属性,构造器)。

//1.调用非public的属性
Field f1 = clazz.getDeclaredField("name");
f1.setAccessible(true);
f1.set(animal, "Jerry");
System.out.println(animal);
//调用public的属性
Field f2 = clazz.getField("age");
f2.set(animal, 9);
System.out.println(animal);
//调用静态属性
Field f3 = clazz.getDeclaredField("desc");
System.out.println(f3.get(animal));
//2.调用非public的方法
Method m1 = clazz.getDeclaredMethod("getAge");
m1.setAccessible(true);
int age = (Integer) m1.invoke(animal);
System.out.println(age);
//调用public方法
Method m2 = clazz.getDeclaredMethod("show",String.class);
Object returnValue = m2.invoke(animal, "金毛");
System.out.println(returnValue);
//调用static方法
Method m3 = clazz.getDeclaredMethod("info");
m3.setAccessible(true);
//对于调用静态方法,一下三种方式都可以。
m3.invoke(Animal.class);
//m3.invoke(animal);
//m3.invoke(null);
//3.调用指定构造器创建运行时类对象
Class clazz = Animal.class;
Constructor cons = clazz.getDeclaredConstructor(String.class, int.class);
cons.setAccessible(true);
Animal animal = (Animal) cons.newInstance("Tom", 10);
System.out.println(animal);

注:

    (1)在我们获取运行时类的构造函数、成员方法、成员变量时,我们要根据权限去使用对用的方法。在这里我们做一下区分:

①getXXX()方法是获取运行时类及其父类中所有的声明为public方法

②getDeclaredXXX()方法是获取运行时类本身生声明的所有方法,不用去管权限修饰符是什么

如果我们只需要获取运行时类自身的方法,我们直接使用getDeclaredXXX()方法是最为方便、有效的。

     (2)根据上面的代码大家可以看到每次使用构造函数、成员方法、成员变量之前要判断是否要添加取消访问检查,其实我们不用管他们的权限修饰符,每次要使用这些之前都加上取消访问检查就可以了。

反射的基本知识点就介绍到这,上面列举的知识获取的运行时类的构造方法、成员方法、成员变量的信息,其实我们还可以获取到接口、泛型、内部内、异常、包路径、泛型等信息,只要学会了上面方法的使用,那么学习其他方法的使用也是同理的。大家赶紧动手试一下吧!



[Python从零到壹] 十三.机器学习之聚类算法四万字总结全网首发(K-Means、BIRCH、树状聚类、MeanShift) 欢迎大家来到“Python从零到壹”,在这里我将分享约200篇Python系列文章,带大家一起去学习和玩耍,看看Python这个有趣的世界。所有文章都将结合案例、代码和作者的经验讲解,真心想把自己近十年的编程经验分享给大家,希望对您有所帮助,文章中不足之处也请海涵。Python系列整体框架包括基础语法10篇、网络爬虫30篇、可视化分析10篇、机器学习20篇、大数据分析20篇、图像识别30篇、人工智能40篇、Python安全20篇、其他技巧10篇。您的关注、点赞和转发就是对秀璋最大的支持,知识无价人有情,希望 阅读详情

相关推荐

bcftools学习笔记(一)

欢迎关注"生信修炼手册"!本篇主要介绍index, view, query, sort, reheader这五个命令。1. indexindex命令用于对VCF文件建立索...

庐州月光的博客 6012

JAVA重点类 反射 动态语言 静态语言 动态代理

1、Java反射机制概述 Reflection (反射)是被视为动态语言(就是有了反射,才让java动态)的关键,反射机制允许程序在执行期借助于Reflection API取得任何类的内部信息,并能直接操作任意对象的内部属性及方法。 加载完类之后,在堆内存的方法区中就产生了一个Class类型的对象(类对象:一个类只有一个Class对象) ,这个对象就包含了完整的类的结构信息。我们可以通过这个对象看到类的结构。这个对象就像一面镜子,透过这个镜子看到类的结构,所以,我们形象的称之为:反射。 ...

chengqingshihuishui的博客 452

TI毫米波雷达人体生命体征(呼吸、心跳)信号提取算法(IWR6843ISK+DCA1000EVM)

本篇内容介绍的算法主要为传统的提取算法,但可实现在1m内呈现良好的检测效果,能够提取出非常可观的呼吸和心跳波形,但在超出1m的距离后便不适用这个算法了。远距离检测呼吸和心跳始终是这个领域一个很大的挑战。要实现远距离检测可在提取相位信号、分离呼吸和心跳信号上进行改进处理,例如线性解调提取相位、改进的VMD分离呼吸和心跳算法。

m0_61934621的博客 3万+

类的封装,继承与多态(Java8.6实战练习)

1.建立一个人类(Person)和学生类(Student),功能要求如下: a. Person中包含4个数据成员name, addr, gender, age,分别表示姓名、地址、性别和年龄。设计一个输出方法talk()来显示这4种属性。 b. Student类继承Person类,并增加成员Math、English存放数学与英语成绩。用1个六参构造方法、1个两参构造方法、1个无参构造方法和覆...

Lyuwalle的博客 2751

SiamFC++笔记

SiamFC++: Towards Robust and Accurate Visual Tracking with Target Estimation Guidelines 文章根据这些思路:引入分类和目标状态估计分支(G1),无歧义的分类得分(G2),无先验知识的跟踪(G3)和评估质量得分(G4)来设计SiamFC ++。 SiamRPN ++和SiamFC ++的比较(红色部分代表得分高的区域): guide: G1 : 分类和状态估计任务的分离:分类任务将目标从干扰物和背景中分类出来,目标状态

木木JL的博客 9435

从单应矩阵到实际距离:Apriltag测距完整实现指南

本文提供了基于Apriltag实现高精度视觉测距与姿态估计的完整指南。详细阐述了从相机标定、单应矩阵分解到欧拉角与距离计算的完整流程,并深入探讨了四个解的歧义选择、工程实践中的滤波优化与多Tag融合等关键问题,旨在帮助开发者在机器人、AR等应用中实现稳定可靠的距离检测与姿态估计。

n7o8p的博客 559

构造函数

构造函数:可以让对象有不同的值 若一个类中没有定义任何构造函数,则会有一个隐藏的的无参构造函数 权限修饰符 类名(){ return; } public class Car{ String band=BYD; int wheelNumber=4; //显示初始化 public Car(){} //无参构造函数 public...

weixin_45276189的博客 1013

单细胞转录组聚类分析R包——SC3的应用

前言 在做单细胞相关聚类分析的过程中,为了研究异质性,发现了一种专门用于单细胞转录组的聚类分析R包——SC3(single cell consensus clustering,单细胞一致性聚类)。该聚类算法发表于Nature Methods(2017),能够让单细胞RNA-seq基于转录组特征对细胞类型进行定量表征。这是一种用户友好的无监督聚类工具,它通过一致方法将多个聚类解决方案组合在一起,从而得到高精度和鲁棒性的分群结果。SC3包的官方具体使用教程见:http://www.bioconductor.or

m0_51042606的博客 5005

java的反射机制浅谈

一、java的反射机制浅谈最近研究java研究得很给力,主要以看博文为学习方式。以下是我对java的反射机制所产生的一些感悟,希望各位童鞋看到失误之处不吝指出。受到各位指教之处,如若让小生好好感动,说不定会请各位吃饭哦!1.何谓反射机制根据网文,java中的反射机制可以如此定义:JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。2.反射机制如何实现谈到反射机

Winiex's Blog 12万+

Python FastAPI 面试题及参考答案

FastAPI 的路由机制是其核心功能之一,用于将不同的 URL 路径映射到相应的处理函数。通过定义路由,可以构建出功能丰富的 API。在 FastAPI 中,使用装饰器来定义路由。在这个示例中,是一个装饰器,它将根路径"/"的 GET 请求映射到read_root函数。当客户端发送一个 GET 请求到根路径时,FastAPI 会调用read_root函数并返回结果。

大模型大数据攻城狮的专栏 2248

Android 系统低内存lowmemorykiller关于阈值修改 minfreeAbsKbytes优化

在系统rom定制化开发中,在对于运行内存ram 1G和2G的设备中,对于内存使用高峰期时,minfreeAbsKbytes优化很关键 调整合理的minfree,让内存合理的使用很关键,接下来分析相关功能的实现

安卓兼职framework和app工程师的博客 524

Java 反射机制

Java 反射机制是在运行状态中,对于任意一个类,都能够获得这个类的所有属性和方法,对于任意一个对象都能够调用它的任意一个属性和方法。这种在运行时动态的获取信息以及动态调用对象的方法的功能称为Java 的反射机制。     Class 类与java.lang.reflect 类库一起对反射的概念进行了支持,该类库包含了Field,Method,Constructor类(每个类都实现了Member

点滴记录 2万+

手把手教你学Simulink——基于Simulink的模糊自适应PI调节FOC电流环

本文提出基于模糊自适应PI控制的FOC电流环优化方案,针对传统PI控制参数固化、抗扰性差等问题,通过模糊逻辑在线调整PI参数。方案采用双输入(电流误差及变化率)和三输出(ΔKp/ΔKi/PI调节)结构,实现动态响应时间<30μs(提升38%)、超调<5%(降低71%)、参数摄动下误差<±0.4A(精度提升73%)。详细介绍了Simulink建模步骤,包括模糊规则设计(7语言变量、49条规则)、隶属度函数配置及自适应PI实现逻辑,并提供实机部署建议。仿真结果表明,该方法显著提升系统鲁棒性,特

MHD0815的博客 79

Java的反射机制

定义在Java运行时环境中,对于任意一个类,能否知道这个类有哪些属性和方法?对于任意一个对象,能否调用它的任意一个方法?答案是肯定的。这种动态获取类的信息以及动态调用对象的方法的功能来自于Java 语言的反射(Reflection)机制。反射(Reflection)是Java语言的特性之一,能够让Java程序在运行时动态地执行类的方法、构造方法等。可以说有了反射,不管什么类在我们面前都毫无隐私可言,什么privateprotecteddefault。

晓的博客 1287

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

Java中的反射机制

在我的上篇文章模拟JDK动态代理实现中涉及到了反射机制,学无止境,在此系统的学习一下Java中的反射机制。首先给出Java反射机制的定义: JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。 从以上的描述中可以看出Java中的动态特性,那么

yhao的博客 9072

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

JAVA反射机制总结

JAVA反射机制总结JAVA反射机制总结 反射的概述 什么是反射 为什么用反射机制 反射机制的关键 获取Class对象 获得构造器的方法 获得属性的方法 获得方法信息的方法 关于getMethods和getDeclaredMethods的区别 反射总结 巨人的肩膀反射的概述什么是反射? 反射的概念是由Smith在1982年首次提出的,主要是指程序可以访问、检测和修改他状态或行为的一种能力。 JAVA

Bing_ka的专栏 2101

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

Java-反射机制(超详解)_java反射机制

新星计划,等你来造,一起学习进步!点击跳转活动奖励:❀【新秀奖】新注册用户发布第一篇文章(500字以上)获得电子【新秀勋章】;❀【基础奖】完成任务挑战用户可获专属电子勋章(潜力新星)+抽奖机会(百分百中奖)❀【特别奖】各导师评选团队综合top5,获实力新星实体证书/实体奖牌红色款二选一+APP作者推荐关注+实力(1)Reflection(反射)是被视为动态语言的关键,反射机制允许程序在执行期 借助于ReflectionAPI取得任何类的内部信息,并能直接操作任意对象的内 部属性及方法。

2501_90250883的博客 1445

什么是java反射机制

1反射机制是什么 反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。 2反射机制能做什么 反射机制主要提供了以下功能:  在运行时判断任意一个对象所属的类; 在运行时构造任意一个类的对象; 在运行时判断任意一个类所...

陈旭媛 1299

对Java中反射机制的理解

简单的说,反射机制就是在程序的运行过程中被允许对程序本身进行操作,比如自我检查,进行装载,还可以获取类本身,类的所有成员变量和方法,类的对象,还可以在运行过程中动态的创建类的实例,通过实例来调用类的方法,这就是反射机制一个比较重要的功能了。那么要通过程序来理解反射机制,首先要理解类的加载过程。 在Java程序执行的时候,要经历三个步骤:加载、连接和初始化。首先程序要加载到JVM的方法区中,然...

小Gd 的博客 1万+

Java 反射机制介绍

JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。Java反射机制在框架设计中极为广泛,需要深入理解 反射基础 RRIT(Run-Time Type Identification)运行时类型识别。在《Thinking in Java》一书第十四章中有提到,其作用是在运行时识别一个对象的类型和类的信息。主要有两种方式:一种是“传统的”RTTI,它假定

vincent_wen0766的博客 785

java反射机制的用处_java反射机制原理详解 java的反射机制用处在哪?

Java中的反射机制的原理和用途是什么?java反射机制的实现原理java反射机制有什么用,具体举例说明增加程序的灵活性。 如struts中。请CSS布局HTML小编今天和大家分享的派发控制。 当请CSS布局HTML小编今天和大家分享来到时。struts通过查询配置文件。找到该请CSS布局HTML小编今天和大家分享对应的action。已经方法。 然后通过反射实例化action。并调用响应metho...

weixin_30696571的博客 409
上一篇: 2016年最新J2EE基础入门教程目录(完结版)
下一篇: Java动态代理
sdecode
博客等级 码龄10年 1粉丝 8原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值