java反射基础知识总结

Java反射之基础知识 欢迎点击「算法与编程之美」↑关注我们!本文首发于微信公众号:"算法与编程之美",欢迎关注,及时了解更多此系列文章。1 问题描述  最近学习到java反射机制的内容,对这一... 阅读详情

反射定义

JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性。
欲用反射,必先得字节码(.class文件对象)。

先来看看java反射的三个阶段:

源文件阶段字节码阶段创建对象阶段String.java文件javac命令编译Class c = Class.forName("java.lang.String")java命令运行Class c = String.classString s = new String()Class c = s.getClass()源文件阶段字节码阶段创建对象阶段

每一个阶段我们都有对应的手段得到字节码文件对象,得到对应的字节码文件对象只是我们反射的第一步,我们真正想做的是改变成员变量的属性值或者是调用类中的方法。
要想改变属性或者方法必须得有对象可行,下面先介绍如何通过反射创建对象:

反射创建对象

Class c = String.class;
String s = (String) c.newInstance();

一个字节码文件对象调用该方法可以创建其实例对象,注意此种创建对象方式只能局限于非私有空参构造方法(没有空参构造或者空参构造是私有的不能通过此种方法创建对象)。

Constructor<T>      getConstructor(Class<?>... parameterTypes)//根据指定构造参数类型得到对应的Constructor对象
Constructor<?>[]    getConstructors()//得到包含该类所有public构造方法Constructor对象的数组

上面的一组方法可以得到public权限修饰的构造方法

Constructor<T>      getDeclaredConstructor(Class<?>... parameterTypes)
Constructor<?>[]    getDeclaredConstructors() 

在Class类中有一类方法是以getDeclared…开头的,这一类方法可以得到类中私有的构造、属性和方法。
为了便于举例说明,这里我们创建一个自定义的测试类:

package com.qj.reflect;
public class ReflectBean {
	private ReflectBean() {
		super();//私有构造
	}

	public void print(String s) {
		System.out.println(s);
	}
}

该类私有了构造方法,下面通过反射创建对象并调用该类中的方法:

public static void testConstructor() throws Exception {
	Class c = Class.forName("com.qj.reflect.ReflectBean");
	Constructor dc = c.getDeclaredConstructor();//得到私有构造
	dc.setAccessible(true);// 解除私有权限
	ReflectBean rb = (ReflectBean) dc.newInstance();//创建对象
	rb.print("反射创建对象调用方法");
}

反射修改属性值

与获取字节码对象的构造方法类似,获取成员属性Class类中也有对应的API:

Field      getField(String name)//根据属性名称获取Field对象,仅限public
Field[]    getFields()//获取该类所有的public属性
Field      getDeclaredField(String name)//根据属性名称获取Field对象,private属性也可获取
Field[]    getDeclaredFields()//获取该类所有的属性

为了便于演示我们在ReflectBean类中添加一个属性flag

private boolean flag = true;

反射修改属性值:

public static void testField() throws Exception {
	Class c = Class.forName("com.qj.reflect.ReflectBean");
	Constructor dc = c.getDeclaredConstructor();// 得到私有构造
	dc.setAccessible(true);// 解除私有权限
	ReflectBean rb = (ReflectBean) dc.newInstance();// 创建对象
	Field flag = c.getDeclaredField("flag");//通过属性flag得到对应的Field对象
	flag.setAccessible(true);// 解除私有权限
	flag.setBoolean(rb, false);//修改属性值
}

Field类中修改属性值API:

set(Object obj, Object value)
setBoolean(Object obj, boolean z)
setByte(Object obj, byte b)
setChar(Object obj, char c)
setDouble(Object obj, double d)
setFloat(Object obj, float f)
setInt(Object obj, int i)
setLong(Object obj, long l)
setShort(Object obj, short s)

反射调用方法

在开发中经常遇到有某个类的对象但是方法是私有的,眼巴巴地看着不能调用,反射的强大之处就是能够让你为所欲为!

Method      getMethod(String name, Class<?>... parameterTypes)
Method[]    getMethods()
Method      getDeclaredMethod(String name, Class<?>... parameterTypes) 
Method[]    getDeclaredMethods() 

结合之前对于构造方法和属性的获取,Class类中对方法对象的获取就很容易理解了。
为了演示反射调用方法,我们在ReflectBean中添加一个私有的方法

private void secret() {
	System.out.println("私有方法被调用了!");
}

利用反射调用私有方法:

public static void testMethod() throws Exception{
	Class c = Class.forName("com.qj.reflect.ReflectBean");
	Constructor dc = c.getDeclaredConstructor();// 得到私有构造
	dc.setAccessible(true);// 解除私有权限
	ReflectBean rb = (ReflectBean) dc.newInstance();// 创建对象
	Method dm = c.getDeclaredMethod("secret");//根据方法名称获取Method对象
	dm.setAccessible(true);// 解除私有权限
	dm.invoke(rb);//调用方法
}

我们向ReflectBean测试类中添加一个有参的私有方法:

private void secret(String s) {
	System.out.println("有参私有方法被调用了!  s : " + s);
}

反射调用有参私有方法:

//Class c , ReflectBean rb 生成步骤略
Method dm = c.getDeclaredMethod("secret", String.class);// 根据方法名称及方法参数类型获取Method对象
dm.setAccessible(true);// 解除私有权限
dm.invoke(rb, "方法参数内容");// 调用方法

众所周知,我们利用反射无非是为了获取、改变对象的属性或者调用对象的方法,下面总结一个反射的工具类,让我们使用反射易如反掌!

反射工具类

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class ReflectUtil {
    private ReflectUtil() {
        super();
    }

    /**
     * 根据全类名得到一个该类的对象(仅限非私有空参构造)
     *
     * @param className 全类名(形如com.qj.reflect.ReflectBean,内部类需要$拼接)
     * @return 该类的实例
     * @throws InstantiationException
     * @throws IllegalAccessException
     * @throws ClassNotFoundException
     */
    public static Object newInstance(String className)
            throws InstantiationException, IllegalAccessException,
            ClassNotFoundException {
        Class c = Class.forName(className);
        return c.newInstance();
    }

    /**
     * 根据全类名以及构造方法参数得到一个该类的对象
     *
     * @param className 全类名(形如com.qj.reflect.ReflectBean,内部类需要$拼接)
     * @param args      构造方法参数(可变参数)
     * @return 该类的实例
     * @throws ClassNotFoundException
     * @throws NoSuchMethodException
     * @throws SecurityException
     * @throws InstantiationException
     * @throws IllegalAccessException
     * @throws IllegalArgumentException
     * @throws InvocationTargetException
     */
    public static Object createInstance(String className, Object... args)
            throws ClassNotFoundException, NoSuchMethodException,
            SecurityException, InstantiationException, IllegalAccessException,
            IllegalArgumentException, InvocationTargetException {
        Class c = Class.forName(className);
        Constructor dc;
        int length = args.length;
        if (args != null && length > 0) {//有参构造
            Class[] type = new Class[length];
            for (int i = 0; i < length; i++) {
                type[i] = args[i].getClass();
            }
            dc = c.getDeclaredConstructor(type);
            dc.setAccessible(true);
            return dc.newInstance(args);
        }
        dc = c.getDeclaredConstructor();//无参构造
        dc.setAccessible(true);
        return dc.newInstance();
    }

    /**
     * 根据传过来的对象以及对象的属性名称更改属性值
     *
     * @param obj       该类的实例
     * @param fieldName 该类的属性名称
     * @param value     要更改的属性值
     * @throws NoSuchFieldException
     * @throws SecurityException
     * @throws IllegalArgumentException
     * @throws IllegalAccessException
     */
    public static void modfyField(Object obj, String fieldName, Object value)
            throws NoSuchFieldException, SecurityException,
            IllegalArgumentException, IllegalAccessException {
        Class<?> c = obj.getClass();
        Field field = c.getDeclaredField(fieldName);
        field.setAccessible(true);
        field.set(obj, value);
    }

    /**
     * 获取类的静态属性(仅限静态属性,非静态属性报错)
     *
     * @param className 全类名(形如com.qj.reflect.ReflectBean,内部类需要$拼接)
     * @param fieldName 类的静态属性名称
     * @return 该类的静态属性 {@code fieldName} 的值
     * @throws ClassNotFoundException
     * @throws NoSuchFieldException
     * @throws IllegalAccessException
     */
    public static Object getStaticField(String className, String fieldName)
            throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException {
        Class<?> clazz = Class.forName(className);
        Field field = clazz.getDeclaredField(fieldName);
        field.setAccessible(true);
        return field.get(null);
    }

    /**
     * 获取类的属性(静态属性、非静态属性均可)
     *
     * @param className 全类名(形如com.qj.reflect.ReflectBean,内部类需要$拼接)
     * @param obj       该类的实例对象
     * @param fieldName 类的属性名称
     * @return 该类的属性 {@code fieldName} 的值
     * @throws ClassNotFoundException
     * @throws NoSuchFieldException
     * @throws IllegalAccessException
     */
    public static Object getField(String className, Object obj, String fieldName)
            throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException {
        Class<?> clazz = Class.forName(className);
        Field field = clazz.getDeclaredField(fieldName);
        field.setAccessible(true);
        return field.get(obj);
    }

    /**
     * 根据传过来的对象以及对象的方法名称调用该方法
     *
     * @param obj        该类的实例
     * @param methodName 要调用的方法
     * @param args       方法的参数(可变参数)
     * @throws NoSuchMethodException
     * @throws SecurityException
     * @throws IllegalAccessException
     * @throws IllegalArgumentException
     * @throws InvocationTargetException
     */
    public static void invokeMethod(Object obj, String methodName,
                                    Object... args) throws NoSuchMethodException, SecurityException,
            IllegalAccessException, IllegalArgumentException,
            InvocationTargetException {
        Class c = obj.getClass();
        Method method;
        if (args != null && args.length > 0) {// 有参方法
            Class[] type = new Class[args.length];
            for (int i = 0; i < type.length; i++) {
                type[i] = args[i].getClass();
            }
            method = c.getDeclaredMethod(methodName, type);
        } else {// 空参方法
            method = c.getDeclaredMethod(methodName);
        }
        method.setAccessible(true);
        method.invoke(obj, args);
    }
}

有了这个工具类我们用反射就很easy了:

ReflectBean obj = (ReflectBean) ReflectUtil
.createInstance("com.qj.reflect.ReflectBean");//创建对象
ReflectUtil.modfyField(obj, "flag", false);// 修改flag属性值
ReflectUtil.invokeMethod(obj, "secret");// 调用secret空参构造
ReflectUtil.invokeMethod(obj, "secret", "太帅了");// 调用secret有参构造

通过使用反射工具类大大减少了代码量,一句代码解决一个问题,清晰明朗。

Java基础知识之反射机制简介 Java基础知识之反射机制简介,在程序运行中动态地获取类的相关属性,同时调用对象的方法和获取属性,这种机制被称之为Java反射机制,Java反射是Java实现动态语言的关键,也就是通过反射实现类动态加载 阅读详情

相关推荐

ITK-snap进行分割区域标注、三维显示及改变显示颜色

在进行医学图像器官分割时,无论我们是用传统方法还是深度学习,最后肯定要用到手动分割的区域作为金标准来验证我们方法的精度。但是手动标注器官的轮廓是十分耗时的,这里我介绍一个比较简单的标注方法,以肺分割作为例子。 我们使用ITK-snap作为分割标注工具。 当切片间距离比较小时,比如1mm,一个患者的完整HRCT序列通常在200张以上,如果让医生一一进行分割区域标注是非常耗时乏味的。因此,我们可以使用最简单的阈值法比如OSTU,加上基本的形态学操作对肺进行粗分割得到粗略的分割掩码,在此基础上再手动的对分割结果进

u010409517的博客 2万+

不要重复造轮子-hutool工具包直接起飞

不要重复造轮子-hutool工具包直接起飞

搬运工007 809

ADS学习笔记 2. 低噪声放大器设计

ADS学习笔记 2. 低噪声放大器设计。设计了一个中心频率433MHz,增益18.206dB,NF=0.134dB,S11带宽较好的低噪声放大器

u014087103的博客 9506

JAVA学习记录 - Reflect 反射

(ps: 本文章适用于超级萌新,所以会说一些基础的东西,不喜勿喷) 目录 为什么叫反射? Java反射基础常用代码的有以下三个方法: 让我们举一个示例: 输出: 反射有什么用? 通过反射优化代码的示例: 运行结果: 反射的所有常用方法 注意 练习 答案 为什么叫反射? reflect 可以把某一对象中的变量、方法等等内容映射成一个个的变量对象、方法对象等。打个不恰当的比方,就好比一个 Object (对象)在照镜子,因为光线反射致使镜中呈现了一个和这个 Ob...

qq_41567818的博客 1019

Claude Code与Codex深度对比:终端AI编程助手选型指南

大语言模型驱动的AI编程助手已成为开发者提效的重要工具,它们基于自然语言交互,自动完成代码生成、重构和调试。这类工具依赖上下文理解与工程实践,不同产品在交互模式、模型接入和任务执行上差异显著。从终端CLI编程场景出发,梳理AI编程助手的设计原理与技术价值,重点对比Anthropic Claude Code与OpenAI Codex在安装配置、上下文管理、第三方模型接入(如DeepSeek)以及高频报错处理上的实际表现。无论你是新手还是资深工程师,理解这些差异有助于根据自身工作流选择合适工具,或在两者间灵活切

weixin_33755649的博客 3098

OpenVox 8FXO板卡驱动安装记录

OpenVox A800P和A1200P的板卡驱动安装及问题解决方法

clliu的专栏 2463

ReflectionTestUtils.invokeMethod方法的使用

spring框架的ReflectionTestUtils.invokeMethod方法了解

四问四不知的博客 5659

51单片机也能玩转信号发生器?手把手教你用DAC0832和LM358输出四种标准波形

本文详细介绍了如何使用51单片机和DAC0832芯片搭配LM358运放,自制低成本信号发生器,实现正弦波、矩形波、三角波和锯齿波四种标准波形的输出。从硬件选型、电路设计到编程实现,手把手教你完成这一实用电子项目,总成本不到50元,适合电子爱好者和学生实践。

weixin_30530939的博客 551

Hutool中那些常用的工具类和方法

SpringBoot实战电商项目mall(20k+star)地址:github.com/macrozheng/… 摘要 Hutool是一个Java工具包,它帮助我们简化每一行代码,避免重复造轮子。如果你有需要用到某些工具方法的时候,不妨在Hutool里面找找,可能就有。本文将对Hutool中的常用工具类和方法进行介绍。 (想自学习编程的小伙伴请搜索圈T社区,更多行业相关资讯更有行业相关免费视频...

wanghao112956的博客 1万+

Linux安装部署PostgreSQL详细步骤

Linux安装部署PostgreSQL详细步骤

2301_77356579的博客 9318

华为OD机试 - 荒岛求生 - 栈Stack(Python/JS/C/C++ 新系统 100分)

每一题都有详细的答题思路、详细的代码注释、3个测试用例、为什么这道题采用XX算法、XX算法的适用场景,发现新题目,随时更新,全天优快云在线答疑。

学Java,找哪吒 2837

【Java】之反射总结

学习之路,长路漫漫,写学习笔记的过程就是把知识讲给自己听的过程。这个过程中,我们去记录思考的过程,便于日后复习,梳理自己的思路。学习之乐,独乐乐,不如众乐乐,把知识讲给更多的人听,何乐而不为呢?一、反射概述程序通过类创建对象,反射将这一过程进行反转,通过实例化对象来获取所属类的信息。1.作用,构造任意一个类的对象、获取任意一个对象所属的类的信息、调用任意一个类的成员变量和方法、获取任意一个对象的属性和方法。2.优点可以在程序运行期间动态的创建和编译对象,不需要再次重新编译,就可以更新。

m0_67388084的博客 1175

【ESP32CAM+Android+OpenCV】自定义目标数据集、训练自己的OpenCV模型部署到手机APP并对ESP32CAM无线图传显示并实时检测识别目标_资料编号30

本项目实现自定义目标数据集(想检测什么就检测什么,按照本文教程自己来更换目标)、训练自己的OpenCV模型实时检测识别(pycharm工程)。手机APP(Android studio工程)部署OpenCV模型实现对ESP32CAM(arduino工程)无线WIFI图传过来的图像实时检测识别。 本文以火焰检测识别为例进行演示,通过该过程,结合本文可自定义尝试更换为其它目标的检测,例如更换为车辆、车牌、手势、人脸面部活动、人脸表情、火焰烟雾、行人、口罩、行为、水果、植物、农作物、建筑、损伤等等部署进行检测。

嵌入式阿齐Archie 3477

Java反射基础知识

反射基础知识: Java.lang.Class是所有类对象的定义类,同时是所有反射的入口. Java的安全框架:Java.Security Java.security.Permission 反射会打破OOP对象/类的封装.Java中所有类型不一定是对象,然而每种类型都是类对象(java.lang.class) java类型: 对象类型(java.lang.Object子类) -> java...

weixin_44788441的博客 189

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

Java 反射和注解 基础知识总结

若要学习别人写好的开源的框架(这些框架为了保持通用,在底层大量使用了反射和注解相关的知识和内容)所以,对反射注解的学习非常重要! 反射非常强大,甚至可以操作类的私有成员 文章目录反射ClassField利用反射修改String的内容MethodConstructor利用反射替代我们自己创建对象注解1. **注解**的写法:2. 注解放置在哪儿3. 注解的作用4. Java中有一些人家写好的注解供我...

Zhangguohao666的博客 1127

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

JAVA反射基础知识整理

个人学习整理.

NightWoofGo的博客 357

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

java反射参考文献_Java反射之基础知识

1 问题描述最近学习到java反射机制的内容,对这一部分的相关的知识做了一下学习,这篇文章主要主要通过什么是类型信息?什么是RTTI?什么是java反射?以及反射机制的作用是什么?这几个问题来讲述反射机制。2 问题分析这篇文章最主要的是讲解Java反射机制的基础知识,但是想要理解这个知识点,需要事先明白一些预备知识,主要就是反射机制的作用及意义,还用RTTI是什么?那么就开始进入正文吧!3 解决方...

weixin_39535752的博客 149

基础知识_java反射机制

【代码】基础知识-java反射机制。

senhai的博客 359

java反射基础知识

JAVA反射机制定义:JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。 1、Class对象  1.1通过全限定名加载一个类,格式如下:    Class clazz = Class.forName("com.test.reflect.

293

java反射测试方法_java反射基础知识(四)反射应用实践

反射基础p.s: 本文需要读者对反射机制的API有一定程度的了解,如果之前没有接触过的话,建议先看一下官方文档的Quick Start。在应用反射机制之前,首先我们先来看一下如何获取一个对象对应的反射类Class,在Java中我们有三种方法可以获取一个对象的反射类。通过getClass方法在Java中,每一个Object都有一个getClass()方法,通过getClass方法我们可以获取到这个对...

weixin_36121198的博客 139

Java基础知识系列之反射

转自:http://www.cnblogs.com/rollenholt/archive/2011/09/02/2163758.html 本篇文章依旧采用小例子来说明,因为我始终觉的,案例驱动是最好的,要不然只看理论的话,看了也不懂,不过建议大家在看完文章之后,在回过头去看看理论,会有更好的理解。 下面开始正文。 【案例1】通过一个对象获得完整的包名和类名 ...

a18826265589的博客 67

java 反射基础知识

java 反射 基础知识反射:reflection反射关键类java 反射部分应用 反射:reflection 在运行中分析类。 在运行中查看和操作对象。 基于反射自己创建对象。 调用不可以访问的方法。 set或者get无法访问的成员变量。 反射构建出无法直接访问的类。 实现通用的数组操作代码。 类似函数指针的功能。 使用反射创建对象。 newInstance, 调用构造函数。 方法一: public class A{ public void hello(){ System.

calabash_man的博客 139

Java基础知识—反射

反射 对类的剖析 成员变量,方法,构造方法 1.获取class的字节码对象,其类型是 Class 1.getClass 2.类名直接调用 类名.class直接获取; 3.Class clazz = Class.forName("包名.类名");//括号里写全路径名 2.获取成员变量 Field[] fields = clazz.getFields();//只能访问publ...

Steven_YE 178
上一篇: Android中的“再按一次退出程序”代码实现
下一篇: google vr 入门之VrPanoramaView制作全景图列表
github_2011
博客等级 码龄10年 116粉丝 56原创
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值