Java的反射技术(Class类,Constructor类,Method类, Field类)

2023-11-15

Java编码时知道类和对象的具体信息,此时直接对类和对象进行操作即可,无需反射 如果编码时不知道类或者对象的具体信息,此时应该使用反射来实现

为什么要使用反射

  1. 反射就是把Java类中的各种成分映射成一个个的java对象。例如,一个类有:成员变量,方法,构造方法,包等等信息,利用反射技术可以对一个类进行解剖,把各个组成部分映射成一个个对象。

反射技术常见于框架中。
比如类的名称放在XML文件中,属性和属性值放在XML文件中,需要在运行时读取XML文件,动态获取类的信息。
在编译时根本无法知道该对象或类可能属于哪些类,程序只依靠运行时信息来发现该对象和类的真实信息。

反射的作用:创建对象、操作属性、调用方法

如何使用反射

掌握反射技术的要点在于:如何从一个class中反射出各个组成部分。反射出来的对象怎么用。

Class类

Class类:代表一个类,是Java反射机制的起源和入口,用于获取与类相关的各种信息
提供了获取类信息的相关方法(Class类继承自Object类)

Class类是所有类的共同的图纸
每个类有自己的对象,同时每个类也看做是一个对象,有共同的图纸Class,存放类的结构信息,能够通过相应方法取出相应的信息:类的名字、属性、方法、构造方法、父类和接口。

总之,只要是在源程序中出现的类型,都有各自的Class实例对象,例如,int,void…
反射就是把Java类中的各种成分映射成一个个的java对象。例如,一个类有:成员变量,方法,构造方法,包等等信息,利用反射技术可以对一个类进行解剖,把各个组成部分映射成一个个对象。

那么,既然反射的作用是创建对象、操作属性、调用方法,要实现以上3个作用,需要用到下面介绍的3个类:Constructor类,Method类, Field类

Constructor类

(1)Constructor类代表某个类中的一个构造方法
得到某个类所有的构造方法:
例子:

Constructor [] constructors= Class.forName("java.lang.String").getConstructors();

得到某一个构造方法:
例子: //获得方法时要用到类型

 Constructor constructor = Class.forName(“java.lang.String”).getConstructor(StringBuffer.class);	

(2)创建实例对象:
通常方式:

String str = new String(new StringBuffer("abc"));

反射方式:

String str = (String)constructor.newInstance(new StringBuffer("abc"));

Class.newInstance()方法:
例子:


String obj = (String)Class.forName("java.lang.String").newInstance();

该方法内部先得到默认的构造方法,然后用该构造方法创建实例对象。

Method类

Method类代表某个类中的一个成员方法
得到类中的某一个方法——
例子:

Method charAt = Class.forName("java.lang.String").getMethod("charAt", int.class);

调用方法——
通常方式:

System.out.println(str.charAt(1));

反射方式:

System.out.println(charAt.invoke(str, 1)); 

如果传递给Method对象的invoke()方法的第一个参数为null,这有着什么样的意义呢?说明该Method对象对应的是一个静态方法!
jdk1.4和jdk1.5的invoke方法的区别:
Jdk1.5:public Object invoke(Object obj,Object… args)
Jdk1.4:public Object invoke(Object obj,Object[] args),即按jdk1.4的语法,需要将一个数组作为参数传递给invoke方法时,数组中的每个元素分别对应被调用方法中的一个参数,所以,调用charAt方法的代码也可以用Jdk1.4改写为 charAt.invoke(“str”, new Object[]{1})形式。

Field类

Field类代表某个类中的一个成员变量
问题:得到的Field对象是对应到类上面的成员变量,还是对应到对象上的成员变量?类只有一个,而该类的实例对象有多个,如果是与对象关联,哪关联的是哪个对象呢?所以字段fieldX 代表的是x的定义,而不是具体的x变量。(注意访问权限的问题)
示例代码:

ReflectPoint point = new ReflectPoint(1,7);
	Field y = Class.forName("cn.itcast.corejava.ReflectPoint").getField("y");
	System.out.println(y.get(point));
	//Field x = Class.forName("cn.itcast.corejava.ReflectPoint").getField("x");
	Field x = Class.forName("cn.itcast.corejava.ReflectPoint").getDeclaredField("x");
	x.setAccessible(true);
	System.out.println(x.get(point));

实例演示

首先,我们自定义一个Person类,它是我们将要进行反射的目标。.
在这个类里面,我们定义了:
1.构造方法
2.实例方法
3.属性

package cn.itcast.reflect;

import java.io.InputStream;
import java.util.List;

public class Person {

	public String name = "yaoer";
	private int password = 123;
	private static int age = 23;

	public Person() {
		System.out.println("person");
	}

	public Person(String name) {
		System.out.println(name);
	}

	public Person(String name, int password) {
		System.out.println(name + ":" + password);
	}

	private Person(List list) {
		System.out.println("list");
	}

	public void aa1() {
		System.out.println("aaa1");
	}

	public void aa1(String name, int password) {
		System.out.println(name + ":" + password);
	}

	public String aa1(String name, int[] password) {
		return new String("adad");
	}

	private void aa1(InputStream in) {
		System.out.println(in);
	}

	public static void aa1(int num) {
		System.out.println(num);
	}

	public static void main(String[] args) {
		System.out.println("main!");
	}
}

反射:类的构造函数 ,创建类的对象

package cn.itcast.reflect;

import java.lang.reflect.Constructor;
import java.util.ArrayList;
import java.util.List;

import org.junit.Test;

//解剖(反射)类的构造函数 ,创建类的对象
public class Demo2 {

	// 1——反射构造函数:public Person()
	@Test
	public void test1() throws Exception {

		Class<?> clazz = Class.forName("cn.itcast.reflect.Person");
		Constructor<?> c = clazz.getConstructor(null);

		Person p = (Person) c.newInstance(null);

		System.out.println(p.name);
	}

	// 2——反射构造函数:public Person(String name)
	@Test
	public void test2() throws Exception {

		Class<?> clazz = Class.forName("cn.itcast.reflect.Person");
		Constructor<?> c = clazz.getConstructor(String.class);

		Person p = (Person) c.newInstance("xxxooo");

		System.out.println(p.name);
	}

	// 3——反射构造函数:public Person(String name,int password)
	@Test
	public void test3() throws Exception {

		Class<?> clazz = Class.forName("cn.itcast.reflect.Person");
		Constructor<?> c = clazz.getConstructor(String.class,int.class);

		Person p = (Person) c.newInstance("xxxooo",20);

		System.out.println(p.name);
	}
	
	// 4——反射构造函数:private Person(List list)
		@Test
		public void test4() throws Exception {

			Class<?> clazz = Class.forName("cn.itcast.reflect.Person");
			Constructor<?> c = clazz.getDeclaredConstructor(List.class);

			c.setAccessible(true); //暴力反射
			Person p = (Person) c.newInstance(new ArrayList());

			System.out.println(p.name);
		}
		
		@Test
		public void test5() throws Exception {

			Class<?> clazz = Class.forName("cn.itcast.reflect.Person");
			Person p = (Person) clazz.newInstance();
			
		}
}

反射:类中的方法

/**
 * 
 */
package cn.itcast.reflect;

import java.io.FileInputStream;
import java.io.InputStream;
import java.lang.reflect.Method;

import org.junit.Test;

/**
 * 反射类中的方法
 *
 */
public class Demo3 {
	// 反射类的方法: public void aa1(){
	@Test
	public void test1() throws Exception {

		Class clazz = Class.forName("cn.itcast.reflect.Person");
		Method method = clazz.getMethod("aa1", null);
		Object obj = clazz.newInstance();
		method.invoke(obj, null);
	}

	// 反射类的方法: public void aa1(String name,int password){
	@Test
	public void test2() throws Exception {

		Class clazz = Class.forName("cn.itcast.reflect.Person");
		Method method = clazz.getMethod("aa1", String.class, int.class);
		Object obj = clazz.newInstance();
		method.invoke(obj, "yaoer", 24);
	}

	// 反射类的方法: public void aa1(String name,int[] password){
	@Test
	public void test3() throws Exception {

		Class clazz = Class.forName("cn.itcast.reflect.Person");
		Method method = clazz.getMethod("aa1", String.class, int[].class);
		int[] a = new int[] { 1, 2, 3 };
		Object obj = clazz.newInstance();
		System.out.println(method.invoke(obj, "yaoer", a));
	}

	// 反射类的方法:private void aa1(InputStream in)
	@Test
	public void test4() throws Exception {

		Class clazz = Class.forName("cn.itcast.reflect.Person");
		Method method = clazz.getDeclaredMethod("aa1", InputStream.class);// private
		method.setAccessible(true);
		Object obj = clazz.newInstance();
		System.out.println(method.invoke(obj, new FileInputStream("c://1.txt")));// 对应目录下需要存在此文件
	}

	// 反射类的方法:public static void aa1(int num) {
	@Test
	public void test5() throws Exception {

		Class clazz = Class.forName("cn.itcast.reflect.Person");
		Object obj = clazz.newInstance();
		Method m = clazz.getMethod("aa1", int.class);
		m.invoke(obj, 23);
	}

	// 反射类的方法: public static void main(){
	@Test
	public void test6() throws Exception {

		Class clazz = Class.forName("cn.itcast.reflect.Person");
		Method method = clazz.getMethod("main", String[].class);
		// method.invoke(null, new Object[] {new String[] {"aa","bb"}});
		method.invoke(null, (Object) new String[] { "aa", "bb" });
	}

}

反射:类中的字段(属性)

/**
 * 
 */
package cn.itcast.reflect;

import java.lang.reflect.Field;

import org.junit.Test;

/**
 * 反射字段
 *
 */
public class Demo5 {

	// 反射字段:public String name = "yaoer";
	@Test
	public void test1() throws Exception {
		Class clazz = Class.forName("cn.itcast.reflect.Person");
		Object obj = clazz.newInstance();
		Field f = clazz.getField("name");
		// 获取字段的值
		Object val = f.get(obj);

		// 获取字段的类型
		Class type = f.getType();

		if (type.equals(String.class)) {
			String sval = (String) val;
			System.out.println(sval);
		}

		// 设置字段的值
		f.set(obj, "zhuzhu");
		System.out.println(f.get(obj));

	}

	// 反射字段:private int password;;
	@Test
	public void test2() throws Exception {
		Class clazz = Class.forName("cn.itcast.reflect.Person");
		Object obj = clazz.newInstance();
		Field f = clazz.getDeclaredField("password");
		f.setAccessible(true);// 改变访问权限

		System.out.println(f.get(obj));

	}

	// 反射字段:private static int age = 23;
	@Test
	public void test3() throws Exception {
		Class clazz = Class.forName("cn.itcast.reflect.Person");
		Object obj = clazz.newInstance();
		Field f = clazz.getDeclaredField("age");
		f.setAccessible(true);// 改变访问权限

		System.out.println(f.get(obj));

	}

}

反射技术优缺点

  • 优点

反射提高了Java程序的灵活性和扩展性,降低耦合性,提高自适应能力。它允许程序创建和控制任何类的对象,无需提高硬编码目标类
反射是其他一些常用语言,如C、C++、Fortran或者Pascal等不具备的
Java反射技术应用领域很广,如软件测试、JavaBean等
许多流行的开源框架例如Struts、Hibernate、Spring在实现过程中都采用了该技术

  • 缺点

性能问题:使用反射基本上是一种解释操作哦,用于字段和方法接入时要远慢于直接代码。因此Java反射机制只要应用在对;灵活性和扩展性要求很高的系统框架上,普通程序不建议使用
使用反射会模糊程序内部逻辑:程序员希望在代码中看到程序的逻辑,反射等绕过了源代码的技术,因而会带来维护问题。反射代码比相应的直接代码更复杂

参考文章:https://blog.csdn.net/Elias94/article/details/80361035

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Java的反射技术(Class类,Constructor类,Method类, Field类) 的相关文章

  • 枚举的子类化

    有没有一种简单的方法来子类化Javaenum 我问这个问题是因为我有大约 10 个实现相同接口的对象 但它们对某些方法也有相同的实现 因此我想通过将所有相同的实现放置在扩展的中间对象中来重用代码Enum它也是我需要的所有其他类的超类 或许事
  • Android:如何暂停和恢复可运行线程?

    我正在使用 postDelayed 可运行线程 当我按下按钮时 我需要暂停并恢复该线程 请任何人帮助我 这是我的主题 protected void animation music6 music4 postDelayed new Runnab
  • “源兼容性”和“目标兼容性”有什么区别?

    之间有什么关系 区别sourceCompatibility and targetCompatibility 当它们设置为不同的值时会发生什么 根据工具链和兼容性 https docs gradle org current userguide
  • java程序有多少种结束方式?

    我知道使用 System exit 0 可以结束一个java程序 例如 如果我有一个JFrame窗口 它会关闭并结束程序 但我想知道还有多少其他方法 可以关闭它并结束程序 包括发生错误时 程序会被关闭 JFrame也会被关闭吗 添加到其他答
  • 在不支持 CAS 操作的处理器上进行 CompareAndSet

    今天 我在一次采访中被问到下一个问题 如果您在具有不支持 CAS 操作的处理器的机器上调用 AtomicLong 的compareAndSet 方法 会发生什么情况 您能否帮我解决这个问题 并在可能的情况下提供一些全面描述的链接 From
  • 如何以编程方式使用包含多列的 where-in 子句执行 PostgreSQL 查询?

    我的查询是这样的 select from plat customs complex where code t code s in 01013090 10 01029010 90 它在 psql 控制台中运行良好 我的问题是如何在客户端代码中
  • 以相反的顺序打印任何集合中的项目?

    我在 使用 Java 进行数据结构和问题解决 一书中遇到以下问题 编写一个例程 使用 Collections API 以相反的顺序打印任何 Collection 中的项目 不要使用 ListIterator 我不会把它放在这里 因为我想让有
  • 查看Java Agent修改的Java类的源代码

    我需要了解 Java 代理如何修改我的初始类 以便我能够理解代码的作用 build gradle configurations jar archiveName agent2 jar jar manifest attributes Prema
  • 使用 OkHttp 下载损坏的文件

    我编写的下载文件的方法总是会产生损坏的文件 public static String okDownloadToFileSync final String link final String fileName final boolean te
  • 为什么在将 String 与 null 进行比较时会出现 NullPointerException?

    我的代码在以下行中出现空指针异常 if stringVariable equals null 在此语句之前 我声明了 stringVariable 并将其设置为数据库字段 在这个声明中 我试图检测该字段是否有null值 但不幸的是它坏了 有
  • 使用 Proguard 通过 Dropbox.com 库混淆 Android 应用程序

    我刚刚创建了一个需要 Dropbox com API 库的 Android 应用程序 我现在尝试在 发布 模式下构建应用程序 并希望在代码上运行混淆器以对其进行混淆 但是 每当我尝试运行 Proguard 时 都会收到以下错误 Progua
  • Java 8 Stream,获取头部和尾部

    Java 8 引入了Stream http download java net jdk8 docs api java util stream Stream html类似于 Scala 的类Stream http www scala lang
  • Tomcat 6 未从 WEB-INF/lib 加载 jar

    我正在尝试找出我的 tomcat 环境中的配置问题 我们的生产服务器正在运行 tomcat 安装并从共享 NFS 挂载读取战争 然而 当我尝试使用独立的盒子 及其配置 进行同样的战争时 我收到下面发布的错误 有趣的是 如果我将 WEB IN
  • Lombok 不适用于 Eclipse Neon

    我下载了lombok jar lombok 1 16 14 jar 并将其放入我的下载中 然后我点击这个 jar 执行正确地识别了我的 MacOS 上的 Eclipse 实例 然后我选择了我想要的实例 Lombok也在pom xml中指定
  • java实现excel价格、收益率函数[关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • 即使禁用安全性,OAuth 令牌 API 也无法在 Elastic Search 中工作

    我是 Elastic search 新手 使用 Elastic search 版本 7 7 1 我想通过以下方式生成 OAuth 令牌弹性搜索文档 https www elastic co guide en elasticsearch re
  • Spring Data Rest 多对多 POST

    首先 让我解释一下我的用例 这非常简单 有一个用户实体和一个服务实体 我使用 UserService 作为连接实体 连接表 在用户和服务之间建立多对多关联最初 会有一些用户集和一些服务集 用户可以在任何时间点订阅任何服务 在这种情况下 将向
  • 使用 Apache 允许 Glassfish 和 PHP 在同一服务器中协同工作

    是否可以建立从 Java 到 php 文件的桥梁 我有一个用 Java 编写的应用程序 我需要执行http piwik org http piwik org 这是用 PHP 编写的 在服务器中 我正在运行 PHP 但无法从浏览器访问 php
  • 检测到 JVM 正在关闭

    我有一个使用 addShutdownHook 处理 Ctrl C 的 Swing 应用程序 它工作正常 直到我的关闭任务之一调用一个在正常情况下更改 JLabel 文本的函数 此时它挂起 我认为问题是 Swing EDT 已终止或正在等待某
  • 如何让 Firebase 与 Java 后端配合使用

    首先 如果这个问题过于抽象或不适合本网站 我想表示歉意 我真的不知道还能去哪里问 目前我已经在 iOS 和 Android 上开发了应用程序 他们将所有状态保存在 Firebase 中 因此所有内容都会立即保存到 Firebase 实时数据

随机推荐

  • 手把手教你如何 远程控制另一台电脑 保姆教程

    现在win10可以实现两台电脑之间的远程控制 下面我就分享一下如何利用快速助手进行远程控制另一台电脑 每一步都有截图 实验环境 两台win10系统的电脑 一 打开电脑后 需要设置允许电脑进行远程控制 进入 控制面板 系统和安全 系统 远程控
  • python文件操作图形化——python实战项目:单词练习系统

    python 文件操作与图形化编程 目录 python 文件操作与图形化编程 文件基本操作 图形化界面tkinter 单词练习系统 文件基本操作 D Python example txt 文件路径 D Python 文件名 example
  • 并行计算出现 pickle.PicklingError

    from multiprocessing import Pool def my function x return x x if name main inputs 1 2 3 4 5 with Pool 2 as p results p m
  • Unity面试题

    Unity基础面试题 1 什么是协同程序 2 Unity3D中碰撞器和触发器的区别 3 物体发生碰撞的必要条件 4 ArrayList和list的区别 5 如何安全的在不同工程间迁移Asset 6 OnEnable Awake Start的
  • Dubbo高级应用-服务治理

    目录 1 dubbo admin 2 7 x版本安装部署 1 1 下载源码 1 2 部署访问 2 路由规则 2 1 Dubbo API配置 2 2 管理控制台配置 3 规则动态配置 3 1 应用粒度 3 2 服务粒度 4 服务降级 5 集群
  • 集成 CUDA 实现 GPU 加速 OpenCV 计算机视觉

    特点 详细概述了将 OpenCV 与 CUDA 集成以用于实际应用 理解GPU与CUDA编程 通过一些实际示例 探索使用GPU和CUDA的OpenCV加速 熟悉在 NVIDIA Jetson TX1 上部署 OpenCV 应用程序 介绍了
  • python 类装饰器和函数装饰器区别_Python各种类型装饰器详解说明

    装饰器说明 Python中的装饰器是一种可以装饰其它对象的工具 该工具本质上是一个可调用的对象 callable 所以装饰器一般可以由函数 类来实现 装饰器本身需要接受一个被装饰的对象作为参数 该参数通常为函数 方法 类等对象 装饰器需要返
  • -day15--内置模块与开发规范

    day15 内置模块和开发规范 目标 掌握常见的内置模块的使用及了解软件开发的规范 今日概要 内置模块 json time datetime re 开发规范 主文件 配置文件 数据 附件 业务代码 1 内置模块 1 1 json json模
  • Win10+mingw64条件下编译和使用TBB(环境变量太神奇了!)

    Win10 mingw64 VSCode条件下编译和使用TBB Win10 mingw64条件下编译和使用TBB 编译TBB 环境变量的设置 TBB使用示例 总结与展望 Win10 mingw64条件下编译和使用TBB 本文记录在Win10
  • java中.xlsx或者.xls格式的Excel导入(servlet中处理的)

    1 第一步 在pom xml文件中添加maven依赖
  • 二、Node.js---模块化

    目录 模块化的基本概念 Node js中模块化 Node js 中模块的分类 加载模块 Node js 中的模块作用域 模块作用域 向外共享模块作用域中的成员 Node js 中的模块化规范 npm与包 在项目中安装包 包的语义化版本规范
  • 运放-滞回(迟滞)比较器全流程实战计算

    比较器之滞回 迟滞 比较器实战计算 下面我们进行一个电池低电压保护的电路设计 其中会介绍到滞回比较器的实际用法以及详细计算推导过程 假设我们定18 5V为电池欠压保护电压 也就是说在当前负载情况下电池电压低于18 5V时 其他功能会被限制住
  • linux中如何重新configure(或去除已configure的文件)

    linux中如何重新configure 或去除已configure的文件 linux中 在安装源码软件前 需要configure命令来进行安装配置 有时configure后需要重新configure 这时需要进行一些操作 已放置出错 以在f
  • 如何使用C ++以编程方式在Word文档中使用注释?

    Microsoft Word使您能够向Word文档添加注释 在诸如建议改进文档或共享文本思想等情况下 注释可能会有所帮助 在某些情况下 需要以编程方式管理评论 为此 本文将教您如何使用C 在Word文档中使用注释 让我们探索以下有关的内容
  • 12306验证码识别

    1 安装tesseract https digi bib uni mannheim de tesseract 安装时安装语言包 不过我安装了好多次都没成功 好像是被墙了 所以语言包使用https github com tesseract o
  • Linux驱动入门(1)hello驱动

    前言 1 学习韦东山老师的Linux 因为他讲的很精简 以至于很多人听不懂 接下来我讲介绍韦东山老师的驱动实验班的第一个Hello程序 2 注意 请先学习完视频再来看这个教程 本文仅供入门学习 如需深入 请搜索其他博客 3 gitee仓库
  • osgEarth的Rex引擎原理分析(七十七)rex引擎中绘制瓦片的调度过程原理

    目标 七十二 中的问题151 主要是分析瓦片什么时候进入场景树 什么时候从场景树中移出 1 初始化 osgEarthDrivers engine rex RexTerrainEngineNode cpp void RexTerrainEng
  • Git 常见错误 之 fatal: Authentication failed 简单解决方法

    Git 常见错误 之 fatal Authentication failed 简单解决方法 目录 Git 常见错误 之 fatal Authentication failed 简单解决方法 一 简单介绍 二 问题现象 三 解决方法 1 修改
  • ADS1115(ADC)16 位分辨率的高精度模数转换器的操作步骤

    ADS1113 ADS1114 和ADS1115 是具有16 位分辨率的高精度模数转换器 ADC 采用超小型的无引线QFN 10 封装或MSOP 10 封装 ADS1113 4 5 在设计时考虑到了精度 功耗和实现的简易性 ADS1113
  • Java的反射技术(Class类,Constructor类,Method类, Field类)

    Java编码时知道类和对象的具体信息 此时直接对类和对象进行操作即可 无需反射 如果编码时不知道类或者对象的具体信息 此时应该使用反射来实现 为什么要使用反射 反射就是把Java类中的各种成分映射成一个个的java对象 例如 一个类有 成员