Java反射浅析一二

【Java】Java 反射机制浅析 1.概述 转载:https://www.cnblogs.com/gulvzhe/archive/2012/01/27/2330001.html Java反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为Java语言的反射机制。反射的概念是由Smith在1982年首次提出的,主要是指程序可以访问、检测和修改它本身状态或行为的一种能力。这一概念的提出很快引发了计算机科学领域关于应用反射. 阅读详情

Java反射

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

1.反射的基础原理

1.1 Class类

Class类也是类的一种,注意其与class关键字是完全不同的。 Class类是java虚拟机加载类字节码后产生的类的类型信息,这个Class对象保存在同名.class的字节码文件中,在内存中有且只有一个与之对应的Class对象来描述其类型信息。无论创建多少个实例对象,其依据的都是用一个Class对象。 Class对象只能有JVM创建和加载 Class类的对象作用是运行时提供或获得某个对象的类型信息,这点对于反射技术很重要

public final class Class<T> implements java.io.Serializable,
                              GenericDeclaration,
                              Type,
                              AnnotatedElement {
  	//。。
    private static native void registerNatives();
    static {
        registerNatives();
    }

    private Class(ClassLoader loader) {
        classLoader = loader;
    }

  @CallerSensitive
    public static Class<?> forName(String className)
                throws ClassNotFoundException {
        Class<?> caller = Reflection.getCallerClass();
        return forName0(className, true, ClassLoader.getClassLoader(caller), caller);
    }

Class类的实例表示java应用运行时的类(class ans enum)或接口(interface and annotation)(每个java类运行时都在JVM里表现为一个class对象,可通过类名.class、类型.getClass()、Class.forName(“类名”)等方法获取class对象)

    public static void main(String[] args) throws ClassNotFoundException {
        Class<Main> mainClass = Main.class;
        Main m = new Main();
        Class aClass = m.getClass();
        Class<?> aClass1 = Class.forName("com.reflection.clazz.Main");
        System.out.println(mainClass == aClass);
        System.out.println(aClass == aClass1);
        // System.out.println(m.getClass().getClass());
    }

运行结果

true
true

如果使用接口

    public static void main(String[] args) throws ClassNotFoundException {
        Class F1Class = F1.class;
        F1 c = new C1();
        Class C1Class = c.getClass();
        Class<?> F1Class1 = Class.forName("com.reflection.clazz.F1");
        Class<?> C1lass11 = Class.forName("com.reflection.clazz.C1");
        System.out.println(F1Class == F1Class1);
        System.out.println(C1Class == C1lass11);
        System.out.println(F1Class == C1Class);
    }

运行结果:

true
true
false

2.2 类加载机制

类全生命周期如下图
在这里插入图片描述
类加载流程如下图
从下图看的很清楚,每个字节码文件加载后对应一个Class对象,这个对象存储了类的基本结构,这个读写可以和堆内的普通对象一起完成复杂的操作。
在这里插入图片描述

2. 反射初识

2.1 Class类能搞清楚类的各种信息

先定义一个User类

public class User extends AbstractUser implements Person, Serializable {

    private int id;
    private String name;

    public User() {
    }

    public User(int id, String name) {
        this.id = id;
        this.name = name;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", name='" + name + '\'' +
                '}';
    }
}

这个User类继承了接口和抽象类

public interface Person {

}
public class AbstractUser {
    public int age;
}

经过Class的反射,可以看到:

public class Main3 {
    public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException {
        // 获取类名称
        System.out.println(User.class.getName());
        System.out.println(User.class.getSimpleName());
        System.out.println(User.class.getCanonicalName());
        //获取接口信息
        System.out.println(" is interface :" + User.class.isInterface());
        for (Class infs : User.class.getInterfaces()) {
            System.out.println(" impl interfaces :" + infs);
        }
        //父类
        System.out.println("Super class : " + User.class.getSuperclass());
        //获取属性
        for (Field field : User.class.getFields()) {
            System.out.println(" all field :" + field.getName());
        }
        //获取公开属性
        for (Field field : User.class.getDeclaredFields()) {
            System.out.println(" all DeclaredField :" + field.getName());
        }
        //获取公开方法
        for (Method declaredMethod : User.class.getDeclaredMethods()) {
            System.out.println(" all DeclaredMethods :" + declaredMethod.getName());
        }
        //获取公开方法
        for (Constructor constructor : User.class.getDeclaredConstructors()) {
            System.out.println(constructor.getName() + " 方法需要的参数如下:");
            for (Parameter parameter : constructor.getParameters()) {
                System.out.println(constructor.getName() + "\t" + parameter.getType() + ":" + parameter.getName());
            }
        }
    }
}

运行结果:

com.reflection.clazz.pojo.User
User
com.reflection.clazz.pojo.User
 is interface :false
 impl interfaces :interface com.reflection.clazz.pojo.Person
 impl interfaces :interface java.io.Serializable
Super class : class com.reflection.clazz.pojo.AbstractUser
 all field :age
 all DeclaredField :id
 all DeclaredField :name
 all DeclaredMethods :toString
 all DeclaredMethods :getName
 all DeclaredMethods :getId
 all DeclaredMethods :setName
 all DeclaredMethods :setId
com.reflection.clazz.pojo.User 方法需要的参数如下:
com.reflection.clazz.pojo.User 方法需要的参数如下:
com.reflection.clazz.pojo.User	int:arg0
com.reflection.clazz.pojo.User	class java.lang.String:arg1

2.2 用反射构建对象

可以通过参数类型找出指定的构造方法,生成所要的对象。私有方法也可以更改其权限来创建对象。

public class Main4 {
    public static void main(String[] args) throws IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
        //使用默认构造方法
        Apple apple = Apple.class.newInstance();
        System.out.println(apple);
        //使用Apple(String color, String area)来构造
        Constructor<Apple> constructor = Apple.class.getConstructor(String.class, String.class);
        Apple apple1 = constructor.newInstance("红色", "阿克苏");
        System.out.println(apple1);
        //调用私有构造方法  private Apple(String area)
        Constructor<Apple> constructor1 = Apple.class.getDeclaredConstructor(String.class);
        constructor1.setAccessible(true);
        Apple apple2 = constructor1.newInstance("山东");
        System.out.println(apple2);
    }
}

运行结果:

Apple{color='null', area='null', weight=0.0, price=0.0}
Apple{color='红色', area='阿克苏', weight=0.0, price=0.0}
Apple{color='null', area='山东', weight=0.0, price=0.0}

2.3 用反射来修改字段

可以看到私有字段的属性值也可以被反射方式修改;不过final字段的修改并不成功。

class Box{
    private final String color ="蓝色";
    private int len;
    private int width;
    private int height;
    private double weight;

    @Override
    public String toString() {
        return "Box{" +
                "color='" + color + '\'' +
                ", len=" + len +
                ", width=" + width +
                ", height=" + height +
                ", weight=" + weight +
                '}';
    }
}

public class Main5 {
    public static void main(String[] args) throws IllegalAccessException, InstantiationException, NoSuchFieldException {
        Box box = Box.class.newInstance();
        Field field = Box.class.getDeclaredField("width");
        Field field2 = Box.class.getDeclaredField("color");
        field.setAccessible(true);
        field2.setAccessible(true);
        field.set(box,20);
        field2.set(box,"灰色");
        System.out.println(box);
    }
}

运行结果

Box{color='蓝色', len=0, width=20, height=0, weight=0.0}

2.4. 使用反射来调用方法

通过反射能够获取类所继承实现、以及私有的各类方法,并且能够进行调用

interface Fly{
   void fly();
}

class Animal {
    public void live() {
        System.out.println(" living ");
    }
}

class Bird  extends Animal implements Fly{
    @Override
    public void fly() {
        System.out.println("flying");
    }

    public static void eat(String food){
        System.out.println("eating some "+food);
    }

    private int layeggs(int num) {
        System.out.println(" lay "+ num+ " eggs , hope born baby birds");
        return new Random().nextInt(num);
    }
}

public class Main6 {
    public static void main(String[] args) throws IllegalAccessException, InstantiationException, NoSuchFieldException, NoSuchMethodException, InvocationTargetException {
        Bird bird = Bird.class.newInstance();
        Method[] methods = Bird.class.getDeclaredMethods();
        for(Method method:methods){
            System.out.println("Bird类有这个方法:"+method.getName()+",其参数个数:"+method.getParameterCount());
        }
        //调用一个私有方法试试
        Method method = Bird.class.getDeclaredMethod("layeggs", int.class);
        method.setAccessible(true);
        Integer ret = (Integer) method.invoke(bird, 42);
        System.out.println(ret);

        //调用一个静态方法
        Method staticmethod = Bird.class.getDeclaredMethod("eat",String.class);
        staticmethod.invoke(null,"谷子");
    }
}

运行结果:

Bird类有这个方法:layeggs,其参数个数:1
Bird类有这个方法:eat,其参数个数:1
Bird类有这个方法:fly,其参数个数:0
 lay 42 eggs , hope born baby birds
35
eating some 谷子

3. 反射执行的内部流程

反射类及反射方法的获取,都是通过从列表中搜寻查找匹配的方法,所以查找性能会随类的大小方法多少而变化; 每个类都会有一个与之对应的Class实例,从而每个类都可以获取method反射方法,并作用到其他实例身上; 反射也是考虑了线程安全的,放心使用; 反射使用软引用relectionData缓存class信息,避免每次重新从jvm获取带来的开销; 反射调用多次生成新代理Accessor, 而通过字节码生存的则考虑了卸载功能,所以会使用独立的类加载器; 当找到需要的方法,都会copy一份出来,而不是使用原来的实例,从而保证数据隔离; 调度反射方法,最终是由jvm执行invoke0()执行

总结

“反射”机制,它允许我们在运行时发现和使用类的信息。掌握反射是进阶程序员的必经之路。

java基础 系列在github上有一个开源项目,主要是本系列博客的demo代码。https://github.com/forestnlp/javabasic
如果您对软件开发、机器学习、深度学习有兴趣请关注本博客,将持续推出Java、软件架构、深度学习相关专栏。
您的支持是对我最大的鼓励。

Ubuntu24.04/20.04设置网络共享文件夹 Ubuntu20.04利用向日葵远程控制时,不能传输文件。使用linux版本QQ来传输是可以的,不过linuxqq功能真的很弱。因此,打算在Ubuntu系统中建立一个共享文件夹,可在局域网中访问。 1、新建共享文件夹 获取root权限,或者登陆root账户。可在/home文件夹(或其它文件夹)下新建一个文件夹,如share。 右击文件夹,选择“本地网络共享”菜单。按下图设置。 点击确定。如果系统已经安装了samba服务器,就可以进入第3步。如果没有,会提示安装,按提示安装,可能会出错,可进. 阅读详情

相关推荐

【个人记录】CentOS7升级glibc至2.28

由于CentOS7系统已经停止支持, 虽然大部分业务已经迁移至OpenEuler,但仍然有部分业务系统跑在CentOS7上。在尝试部署新业务环境时经常会提示如下错误(以code-server运行需要的node 20为例)node -v为了保障业务可正常运行,通常采用Docker继承好的node环境进行部署,但部分场景还是需要宿主机使用新版glibc版本。本文记录本人一次成功升级glibc(2.17=>2.28)的步骤。

喵呜 3883

Class.forName底层原理

Class Class.forName public static Class<?> forName(String name, boolean initialize, ClassLoader loader) throws ClassNotFoundException { Class<?> caller = null; SecurityManager sm =

kongkong的专栏 1395

麒麟银河操作系统V10部署ffmpeg(也能用于Linux系统)

部署ffmpeg用来处理视频的各种操作,如编码解码,格式转换,剪辑,处理实时视频流,音频流,加滤镜等

zhouwenxing666的博客 9041

Reflection的getCallerClass的使用

Reflection的getCallerClass的使用 博客分类:  java基础   Reflection的getCallerClass的使用:可以得到调用者的类.这个方法是很好用的.  0 和小于0  -   返回 Reflection类  1  -   返回自己的类  2  -    返回调用者的类  3. 4. ....层层上传。  Java代码    package com....

evilcry2012的专栏 6594

影刀RPA进阶:Excel多条件筛选与数据提取实战

本文详细介绍了如何利用影刀RPA实现Excel多条件筛选与数据提取的自动化。通过拆解文本、数值、日期及颜色筛选等核心指令,并结合实战案例,指导用户构建稳健的销售数据提取机器人,从而高效处理复杂数据报表,提升工作效率。

onion的博客 530

保姆级教程:用OpenCV搞定鱼眼双目相机的标定与测距(附完整C++代码)

本文详细介绍了使用OpenCV进行鱼眼双目相机标定与测距的全流程,包括环境搭建、数据采集、单目标定、双目标定、立体校正和视差计算等核心步骤。通过完整的C++代码示例和参数调优指南,帮助开发者快速实现高精度的双目测距系统,适用于机器人导航、VR全景拍摄等领域。

weixin_42573113的博客 388

java clazz_java相关。请问Class的clazz在各个语句里是什么用?我总不理解这一点,麻烦详解一下。谢谢...

publicclassDataUtil{//将rs中的值封装成一个集合publicstaticCollectiongetDatas(Collectionresult,ResultSetrs,Classclazz){try{while(rs.next()){//创建类的实例Objectvo=clazz.ne...public class DataUtil {//将rs中的值封装成一个集合public...

weixin_42298646的博客 650

用Cadence IC618仿真双平衡吉尔伯特混频器:从原理图到后仿的完整避坑指南

本文详细介绍了在Cadence IC618环境中设计双平衡吉尔伯特混频器的全流程,包括原理图设计、仿真优化和版图实现。通过实战案例分享,重点解析了设计中的关键技巧和常见问题解决方案,帮助工程师高效完成高性能混频器设计,特别适合射频前端开发人员参考。

weixin_42656416的博客 162

Reflection.getCallerClass()

DriverManager.getConnection;Reflection.getCallerClass()方法

Ljj_fishhG的博客 684

innovus:addRepeaterByRule用法

我正在「拾陆楼」和朋友们讨论有趣的话题,你⼀起来吧?addRepeaterByRule不管transition/timing violation,只根据约束的length/cap/fanout等等去给net 插buffer。

m0_61544122的博客 1091

华为OD机试 - 第k个排列 - 全排列递归(Python/JS/C/C++ 2025 C卷 100分)

给定参数n,从1到n会有n个整数:1,2,3,…,n,这n个数字共有n!按大小顺序升序列出所有排列的情况,并一一标记当n=3时,所有排列如下“123”,“132,“213”,“231”,“312”,“321”输入两行,第一行为n,第二行为k,给定n的范围是[1,9],给定k的范围是[1,n!排列为“12”和“21”,第2个是“21”。给定n和k,返回第k个排列。输出排在第k位置的数字。只有一个排列,直接返回。

学Java,找哪吒 984

使用GSON解析

一、简介 GSON是Google提供的用来在Java对象和JSON数据之间进行映射的Java类库。 可以将一个Json字符串转换成一个Java对象,戒者将一个Java对象转换成Json字符串。 GSON最大的特点:(1)代码量少、简洁(2)数据传递和解析方便。 GSON的项目主页地址是:https://github.com/google/gson 注意:添加GSON库的依赖: implementation 'com.google.code.gson:gson:2.8.6' ...

indeedes的博客 3238

你分得清ChatGPT、Gemini、Grok、豆包、千问、DeepSeek、OpenClaw、CloudCode、vibeCodeing、sKill、MCP,飞书、微信这些到底是什么吗?

AI技术生态呈现层级化发展,从基础模型到应用平台形成完整技术栈。核心分为五层:模型层(GPT、Gemini等基础模型)→AI助手层(ChatGPT等应用产品)→工具层(ClaudeCode等开发工具)→协议层(MCP等接口标准)→应用层(微信、飞书等平台)。未来趋势将形成"模型公司-开发框架-应用生态"三层结构,AI正逐步演变为新型操作系统,通过标准化协议连接各类外部系统,实现能力调用与生态整合。技术发展呈现出从底层基础设施到上层应用场景的垂直整合特征。

hy行者勇哥的博客 397

Java 反射浅析

Java 反射浅析 目录 Java 反射浅析 反射的意义 反射的基本运用 获取class对象 创建获取到的Class类对象的实例 获取类的方法 获取类的成员变量 调用类的方法 Simple Demo 反射原理浅析 1. 反射的意义 Java反射机制是指在运行状态,对于任意一个类,都能够知道这个类的所有属性和方法,对于任意一个对象,都能够调用它的任意方法和属性,这种动态获取信息以及动态调用...

weixin_42108260的博客 187

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

浅析Java反射

Java的反射(reflection)机制:是指在程序的运行状态中,可以构造任意一个类的对象,可以了解任意一个对象所属的类,可以了解任意一个类的成员变量和方法,可以调用任意一个对象的属性和方法。这种动态获取程序信息以及动态调用对象的功能称为Java语言的反射机制。反射被视为动态语言的关键。

2401_83384536的博客 827

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

JAVA中的反射机制理解与浅析

java反射机制 反射的理解 示例代码

永远不要停下学习的脚步。 4106

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

Java反射浅析

Java反射浅析及其简单的使用方法、以及一些常用的反射相关的函数

ZkSky的博客 652

Java泛型浅析一二

泛型是一种参数化类型的机制。它可以使得代码适用于各种类型,从而编写更加通用的代码,例如集合框架。 泛型是一种编译时类型确认机制。它提供了编译期的类型安全,确保在泛型类型(通常为泛型集合)上只能使用正确类型的对象,避免了在运行时异常。

EndlessProcess的专栏 724

java反射浅析

java反射浅析 反射机制: 正常模式:引入一个类的完整路径,然后通过new来实例化对象 反射模式:通过某个类的Class实例c来获取该类的信息(或创建该类实例对象) 反射实现(操作)流程: 反射应用: 利用反射操作对象属性 //Person实体类 public class Person { private int num=100; private String name="李兴华"; private String sex="女"; private int age=

crt_998的博客 177

浅析java反射(字节码文件)

什么是反射? 先谈谈java程序的运行步骤吧! 先编译后运行对吗? 其实你想一想, 你写的java代码机器真的能认识吗? 早在以前就听过了吧机器是只认识0和1的 所以编译这一阶段也就是将java文件编译成字节码文件也就是.class文件 也就是01码 那什么又是反射呢? 我现在觉得反射就是拿到它的字节码文件,对字节码文件做操作 字节码文件 我先举个例子什么叫做字节码文件 ...

TheSevenSky 3013

浅析Java反射机制

本文是Java反射的学习,认识什么是反射,反射相关的类,以及反射的原理和过程。之后的学习内容将持续更新!!!

qq15035899256的博客 287

Java反射机制浅析

部分内容来源于JDK API 1.6.0中文版 初学Java反射机制,写个博客,想想还是很紧张的,欢迎各位讨论学习。

epiccic3的博客 1029

浅析java反射

回顾:什么是反射? 反射 (Reflection) 是 Java 的特征之一,它允许运行中的 Java 程序获取自身的信息,并且可以操作类或对象的内部属性。 简而言之,通过反射,我们可以在运行时获得程序或程序集中每一个类型的成员和成员的信息。程序中一般的对象的类型都是在编译期就确定下来的,而 Java 反射机制可以动态地创建对象并调用其属性,这样的对象的类型在编译期是未知的。所以我们可以通过反射机...

qq_34501351的博客 183

Java 反射机制浅析

Java 反射机制浅析       Java反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为Java语言的反射机制。反射的概念是由Smith在1982年首次提出的,主要是指程序可以访问、检测和修改它本身状态或行为的一种能力。这一概念的提出很快引发了计算机

IT张先生 454
上一篇: Java异常浅析一二
下一篇: Java SPI 浅析一二
悟空学编程
博客等级 码龄12年 32粉丝 123原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

悟空学编程

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值