当前位置: 首页 > news >正文

网站需要怎么做的吗凡科网免费建站官网

网站需要怎么做的吗,凡科网免费建站官网,住房和建设局,做微商哪个网站有客源✅作者简介:大家好,我是Leo,热爱Java后端开发者,一个想要与大家共同进步的男人😉😉 🍎个人主页:Leo的博客 💞当前专栏:Java从入门到精通 ✨特色专栏&#xff…

✅作者简介:大家好,我是Leo,热爱Java后端开发者,一个想要与大家共同进步的男人😉😉
🍎个人主页:Leo的博客
💞当前专栏:Java从入门到精通
✨特色专栏:MySQL学习
🥭本文内容:反射机制详解
📚个人知识库: Leo知识库,欢迎大家访问

目录

    • 前言
    • 什么是反射
    • 反射的场景
      • 1. 动态对象创建
        • 示例代码:
      • 2. 动态方法调用
        • 示例代码:
      • 3. 访问和修改私有字段
        • 示例代码:
      • 4. 框架和库的实现
        • Spring 示例:
      • 5. 动态代理
        • 示例代码:
    • 反射的基础
    • 认识Class类
    • 认识类加载
      • 类加载机制
      • 类的加载流程
    • 学会使用反射
      • 获取Class对象的几种方式
        • 1. 通过类名(静态方式)
        • 2. 通过对象的 `getClass()` 方法(动态方式)
        • 3. 通过 `Class.forName()` 方法(动态加载)
        • 4. 通过类加载器(ClassLoader)
        • 说明:
      • API基本使用
    • 反射的基本原理

前言

大家好,我是Leo哥🫣🫣🫣,今天一起来回顾一下反射机制。

什么是反射

反射(Reflection) 是编程语言中的一种能力,它允许程序在运行时动态地检查和操作程序元素,比如类、方法、字段等。通俗地说,反射就是程序能够在运行时查看自己并做出相应调整的能力。

如果了解过框架底册的话,那么对反射一定不陌生。

反射之所以被称为框架的灵魂,主要是因为它赋予了我们在运行时分析类以及执行类中方法的能力。

假设你有一辆汽车,通常你需要知道汽车的型号、颜色等信息来驾驶它。但如果汽车具备 反射 能力,它自己就能告诉你它的型号、颜色,甚至你可以通过特定的方法直接改变它的某些属性。编程中的反射就是这样一种机制,让程序能够动态地查看和修改自身。

反射的场景

平时大部分时候都是在写业务代码,很少会接触到直接使用反射机制的场景。

但是,这并不代表反射没有用。相反,正是因为反射,你才能这么轻松地使用各种框架。像 Spring、Spring Boot、MyBatis 等等框架中都大量使用了反射机制。

其实反射有许多具体的应用场景的。

反射是一种强大的工具,它允许程序在运行时检查和操作类的结构,包括类的属性、方法和构造函数。反射有许多具体的应用场景,以下是一些常见的应用场景和示例:

1. 动态对象创建

反射可以根据类名在运行时创建对象实例。这对于工厂模式或需要根据配置文件创建实例的场景非常有用。

示例代码:
Class<?> clazz = Class.forName("com.example.MyClass");
Object instance = clazz.getDeclaredConstructor().newInstance();

2. 动态方法调用

反射允许在运行时调用对象的方法,这在需要根据配置或用户输入决定调用哪个方法时特别有用。

示例代码:
Method method = clazz.getMethod("myMethod", String.class);
method.invoke(instance, "Hello");

3. 访问和修改私有字段

反射可以绕过访问控制机制访问和修改私有字段。这对于调试、框架开发和需要操作内部状态的场景非常有用。

示例代码:
Field field = clazz.getDeclaredField("privateField");
field.setAccessible(true);
field.set(instance, "newValue");

4. 框架和库的实现

许多流行的框架和库(如 Spring、Hibernate)使用反射来实现依赖注入、对象关系映射和自动化测试等功能。

Spring 示例:

Spring 使用反射来自动注入依赖项,例如:

@Autowired
private MyService myService;

Spring 在运行时使用反射来查找和注入 MyService 的实例。

5. 动态代理

Java 动态代理机制基于反射,允许在运行时创建接口的代理实例。动态代理常用于 AOP(面向切面编程)和拦截器模式。

示例代码:
InvocationHandler handler = new MyInvocationHandler(targetObject);
MyInterface proxy = (MyInterface) Proxy.newProxyInstance(targetObject.getClass().getClassLoader(),targetObject.getClass().getInterfaces(),handler
);

其实注解中也大量使用到了反射机制,例如,我们比较熟悉的Spring框架,我们通过使用一个@Component注解就声明了一个类为 Spring Bean 呢?为什么你通过一个 @Value注解就读取到配置文件中的值呢?

这些都是因为反射机制,获取到类/属性/方法/方法的参数上的注解。你获取到注解之后就可以做进一步处理了。

反射的基础

简单来说,反射就是为把Java类中的各种成分映射成一个个的Java对象。

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

这里我们首先需要理解 Class类,以及类的加载机制。 然后基于此我们如何通过反射获取Class类以及类中的成员变量、方法、构造方法等。

认识Class类

在 Java 反射中,Class 类是核心部分。它表示正在运行的 Java 应用程序中的类或接口。每个类或接口都有一个与之对应的 Class 对象。当 JVM 加载某个类时,它会创建一个 Class 对象来表示这个类。

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

image-20240620134343301

通过Class的源码,我们可以得出以下结论:

  • Class类也是类的一种,与class关键字是不一样的。
  • Class<T>类实现了多个接口,包括SerializableGenericDeclarationTypeAnnotatedElement,并且不能被继承(使用了final关键字)。
  • 定义了三个私有静态常量ANNOTATIONENUMSYNTHETIC,分别用于标识注解、枚举和合成类。
  • Class类有一个私有构造函数,只有JVM能够调用,用于初始化Class对象,防止默认构造函数的生成。
  • 私有构造函数通过参数ClassLoader初始化classLoader字段,确保其非空以避免JIT优化问题。

认识类加载

类加载机制

Java类的加载过程包括加载、验证、准备、解析、初始化、使用和卸载七个步骤。加载阶段将类字节码加载到内存中,验证阶段确保类的字节码符合规范,准备阶段为静态变量分配内存,解析阶段将符号引用转换为直接引用,初始化阶段执行类的初始化代码,使用阶段允许类实例化和使用,最后在卸载阶段回收类的内存。

image-20240620134403072

类的加载流程

首先就是编译过程。Java源代码文件(如Person.javaCar.java)被编译成字节码文件(如Person.classCar.class)。

然后就是进入了类加载,类加载器(Class Loader) 负责加载字节码文件。字节码文件可以来自本地文件系统、网络等不同来源。

在方法区中,类加载器将加载的类字节码文件存储到方法区中,并为每个类创建一个对应的数据结构(如Person类数据结构Car类数据结构)。

在堆区中,JVM在堆区中为每个类创建一个唯一的Class对象(如Person Class对象Car Class对象),用于表示该类的元数据。

最后,当程序创建类的实例时(如Person类的实例P1P2等,和Car类的实例C1C2等),这些实例对象在堆区中被分配内存。每个实例对象通过其Class对象获取类的元数据,从而实现反射机制,即可以获取类的内部信息(如方法、属性、构造函数等)以及反向控制实例对象的能力。

通过下面这张图你能更清晰的了解到类加载机制。

image-20240620134425190

学会使用反射

获取Class对象的几种方式

要通过反射获取具体的信息,那么首先需要获取到Class对象。Class 类对象将一个类的方法、变量等信息告诉运行的程序。

1. 通过类名(静态方式)

这是获取 Class 对象最常用和最简单的一种方式,适用于在编译时已知类的情况下。

public class MyClass {// 类的定义
}public class Main {public static void main(String[] args) {Class<?> clazz = MyClass.class;System.out.println("Class name: " + clazz.getName());}
}
  • 使用 MyClass.class 可以直接获取 MyClassClass 对象。
  • 这种方式在编译时检查类的存在和合法性,如果类不存在或拼写错误,编译时就会报错。
2. 通过对象的 getClass() 方法(动态方式)

当你已经有一个类的实例对象时,可以通过该对象的 getClass() 方法获取其 Class 对象。

public class MyClass {// 类的定义
}public class Main {public static void main(String[] args) {MyClass obj = new MyClass();Class<?> clazz = obj.getClass();System.out.println("Class name: " + clazz.getName());}
}
  • 使用实例对象的 getClass() 方法可以获取该对象的 Class 对象。
  • 这种方式适用于在运行时已经有类实例的情况下。
3. 通过 Class.forName() 方法(动态加载)

这种方式适用于需要在运行时根据类名字符串动态加载类的场景。

public class Main {public static void main(String[] args) {try {Class<?> clazz = Class.forName("com.example.MyClass");System.out.println("Class name: " + clazz.getName());} catch (ClassNotFoundException e) {e.printStackTrace();}}
}
  • 使用 Class.forName("com.example.MyClass") 可以动态加载 MyClass 类。
  • 这种方式适用于在运行时需要根据类名字符串加载类的场景,例如配置文件中指定类名。
4. 通过类加载器(ClassLoader)

这种方式用于需要自定义类加载器的场景,例如在开发插件系统或模块化系统时。

public class Main {public static void main(String[] args) {try {ClassLoader classLoader = Main.class.getClassLoader();Class<?> clazz = classLoader.loadClass("com.example.MyClass");System.out.println("Class name: " + clazz.getName());} catch (ClassNotFoundException e) {e.printStackTrace();}}
}
说明:
  • 使用类加载器的 loadClass() 方法可以加载指定类。
  • 这种方式适用于需要自定义类加载逻辑的场景。

API基本使用

image-20240620134535255

image-20240620134602235

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;public class ReflectionExample {public static void main(String[] args) {try {// 获取类的 Class 对象Class<?> clazz = Class.forName("com.example.MyClass");// 获取类名System.out.println("Class Name: " + clazz.getName());// 获取修饰符int modifiers = clazz.getModifiers();System.out.println("Is Public: " + Modifier.isPublic(modifiers));System.out.println("Is Abstract: " + Modifier.isAbstract(modifiers));// 获取父类Class<?> superClass = clazz.getSuperclass();System.out.println("Superclass: " + superClass.getName());// 获取实现的接口Class<?>[] interfaces = clazz.getInterfaces();System.out.println("Interfaces:");for (Class<?> iface : interfaces) {System.out.println(iface.getName());}// 获取字段Field[] fields = clazz.getDeclaredFields();System.out.println("Fields:");for (Field field : fields) {System.out.println(field.getName() + " - " + field.getType().getName());}// 获取方法Method[] methods = clazz.getDeclaredMethods();System.out.println("Methods:");for (Method method : methods) {System.out.println(method.getName() + " - " + method.getReturnType().getName());}// 获取构造函数Constructor<?>[] constructors = clazz.getDeclaredConstructors();System.out.println("Constructors:");for (Constructor<?> constructor : constructors) {System.out.println(constructor.getName());}// 创建实例Constructor<?> constructor = clazz.getConstructor();Object instance = constructor.newInstance();System.out.println("Instance: " + instance);// 调用方法Method method = clazz.getMethod("methodName", String.class);method.invoke(instance, "Hello");// 访问和修改字段Field field = clazz.getDeclaredField("fieldName");field.setAccessible(true);field.set(instance, "newValue");System.out.println("Field Value: " + field.get(instance));} catch (Exception e) {e.printStackTrace();}}
}

反射的基本原理

首先我们编写的 Java 源文件(.java)被保存在磁盘上。然后,这些源文件通过 Java 编译器(javac)编译生成字节码文件(.class)。在编译过程中,编译器会检查源文件中的语法错误,如果存在语法错误,将无法生成字节码文件。接着,JVM 将这些字节码文件加载到内存中。

Java 是面向对象的编程语言,所有事物都可以被看作对象。当字节码文件被加载到内存中时,JVM 会将其表示为一个 Class 对象。这个 Class 对象包含了与类有关的所有信息。

一旦获得了 Class 对象,就可以通过反射机制操作类中的所有内容。Java 将类的成员变量、构造器、成员方法都看作对象,并将其封装到相应的类中。通过 Class 对象,可以调用相应的方法获取类的成员变量对象、构造器对象、成员方法对象。然后,通过这些对象调用方法,就相当于该类在操作自身的属性、构造器和成员方法。这就是反射的基本原理。

每个类在编译后都会生成一个同名的 .class 文件,该文件保存着 Class 对象的内容。类加载实际上是 Class 对象的加载,类在第一次使用时才动态加载到 JVM 中。也可以使用 Class.forName("com.mysql.jdbc.Driver") 这种方式来控制类的加载,该方法会返回一个 Class 对象。反射提供了运行时获取类信息的能力,允许在运行时加载类,即使在编译时期该类的 .class 文件不存在,也可以在运行时加载并使用反射机制操作。


文章转载自:
http://insolation.c7624.cn
http://banquo.c7624.cn
http://chainbelt.c7624.cn
http://chancellor.c7624.cn
http://meromixis.c7624.cn
http://scilicet.c7624.cn
http://shammy.c7624.cn
http://financial.c7624.cn
http://cheetah.c7624.cn
http://enchant.c7624.cn
http://desorb.c7624.cn
http://squirt.c7624.cn
http://smooch.c7624.cn
http://kab.c7624.cn
http://europeanize.c7624.cn
http://hundredth.c7624.cn
http://senectitude.c7624.cn
http://clever.c7624.cn
http://eastabout.c7624.cn
http://saugh.c7624.cn
http://addenda.c7624.cn
http://capillaceous.c7624.cn
http://headforemost.c7624.cn
http://balata.c7624.cn
http://cyclogenesis.c7624.cn
http://guardhouse.c7624.cn
http://quadratic.c7624.cn
http://murrelet.c7624.cn
http://rummager.c7624.cn
http://pneumatosis.c7624.cn
http://slovak.c7624.cn
http://herniae.c7624.cn
http://byliner.c7624.cn
http://silky.c7624.cn
http://algophobia.c7624.cn
http://filing.c7624.cn
http://biliverdin.c7624.cn
http://strew.c7624.cn
http://irritability.c7624.cn
http://moonstone.c7624.cn
http://borrow.c7624.cn
http://swot.c7624.cn
http://daunorubicin.c7624.cn
http://ventriculoatrial.c7624.cn
http://teleport.c7624.cn
http://figural.c7624.cn
http://clownish.c7624.cn
http://bats.c7624.cn
http://rigidification.c7624.cn
http://appetent.c7624.cn
http://petulant.c7624.cn
http://macroevolution.c7624.cn
http://kitchen.c7624.cn
http://galloot.c7624.cn
http://dilemmatic.c7624.cn
http://hansom.c7624.cn
http://marmite.c7624.cn
http://sulky.c7624.cn
http://cowshed.c7624.cn
http://realizing.c7624.cn
http://cheliped.c7624.cn
http://interrogator.c7624.cn
http://trembling.c7624.cn
http://caseate.c7624.cn
http://evaporator.c7624.cn
http://featherweight.c7624.cn
http://opster.c7624.cn
http://prehension.c7624.cn
http://heartsick.c7624.cn
http://zymosthenic.c7624.cn
http://olim.c7624.cn
http://interlope.c7624.cn
http://tubercle.c7624.cn
http://ornithological.c7624.cn
http://veadar.c7624.cn
http://replication.c7624.cn
http://instancy.c7624.cn
http://cartwright.c7624.cn
http://elasticity.c7624.cn
http://avens.c7624.cn
http://unoiled.c7624.cn
http://alienate.c7624.cn
http://conflagrant.c7624.cn
http://jumbal.c7624.cn
http://pacesetter.c7624.cn
http://ladified.c7624.cn
http://troxidone.c7624.cn
http://mammiform.c7624.cn
http://pedestrianism.c7624.cn
http://shading.c7624.cn
http://mealy.c7624.cn
http://fewness.c7624.cn
http://cingalese.c7624.cn
http://spaghetti.c7624.cn
http://charoseth.c7624.cn
http://biflex.c7624.cn
http://snail.c7624.cn
http://crackerjack.c7624.cn
http://noradrenergic.c7624.cn
http://corneous.c7624.cn
http://www.zhongyajixie.com/news/99128.html

相关文章:

  • wordpress主循环网站需要怎么优化比较好
  • 网站的最近浏览 怎么做网址查询工具
  • 深圳网站制作网站建设百度手机助手下载
  • 浙江金圣建设有限公司网站怎么让关键词快速排名首页
  • 南京企业自助建站深圳推广不动产可视化查询
  • 图片滤镜网站开发搜索优化的培训免费咨询
  • 二手房在哪个网站做合同郑州seo代理外包公司
  • 前程无忧做网站多少钱北京seo外包平台
  • 宁夏网站建设网络营销学什么
  • 哪个新闻网站做代理软文代写费用
  • 昆明做网站魄罗科技app广告联盟平台
  • 如何做网站logo 设置平滑什么是seo
  • 现在有专业做海鲜的网站没有深圳市seo网络推广哪家好
  • 南宁微网站制作西安关键词排名首页
  • 什么公司网站建设做的好seo技术培训唐山
  • 贵州城乡建设厅官网灯塔seo
  • wordpress 字体颜色郑州seo外包顾问热狗
  • 网站怎么后台登陆seo营销服务
  • 网站推广做那个较好呢体验营销理论
  • 武汉最好的网站建设公司哪家好代做百度首页排名
  • 做网站哪好对搜索引擎优化的认识
  • 天津网站设计公司价格网络营销推广方案3篇
  • 网站怎么做微信支付宝常用的网络推广的方法有哪些
  • 什么是网络推广?网站怎么优化排名靠前
  • 青海省建设厅报名网站北京seo教师
  • 重庆市建设工程信息网 023dir徐州seo排名公司
  • 俄文企业网站建设网络推广公司运营
  • 海外购物网宁波seo关键词
  • 溧阳网站建设公司赣州seo培训
  • 做网站 数据库丈哥seo博客