Java基础篇——反射&枚举

这篇具有很好参考价值的文章主要介绍了Java基础篇——反射&枚举。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

反射&枚举

课程目标

1. 【理解】类加载器
2. 【理解】什么是反射
3. 【掌握】获取Class对象的三种方式
4. 【掌握】反射获取构造方法并创建对象
5. 【掌握】反射获取成员变量并使用
6. 【掌握】反射获取成员方法并使用
7. 【掌握】反射综合案例
8. 【理解】枚举

B友:https://www.bilibili.com/video/BV1QG4y1J76q/

VIP服务课程:https://edu.51cto.com/course/32767.html

类加载器

类加载

当程序要使用某个类时,如果该类还未被加载到内存中,则系统会通过类的【加载】,【连接】,【初始化】 这三个步骤来对类进行初始化。

如果不出现意外情况,JVM将会连续完成这三个步骤,所以有时也把这三个步骤统称为类加载或者类初始化。

一个类的生命周期包括了 “加载”、“验证”、“准备”、“解析”、“初始化”、“使用”、“卸载” 这七个阶段, 我们只研究前五个阶段,这五个阶段又可以分为 “加载”、“连接、验证,解析” 、 “初始化”。

当程序主动使用某个类时,如果该类还未被加载到内存中,则系统会通过如下三个步骤来对该类进行初始化。

类的加载

类的加载就是指将class文件读入内存,并为之创建一个Class对象。任何类被使用时系统都会建立一个Class对象,用于加载二进制数据,类的加载主要做三件事情:

  • 找到类文件(通过类的全限定名来获取定义此类的二进制字节流)

    首先会根据各种途径(比如网络下载、数据库提取、从jar,zip中读取等)获取类的二进制数据

  • 放入方法区(将这个字节流所代表的静态存储结构转化为方法区的运行时数据结构)

    把获取到的二进制数据读入内存,存储在运行时数据区的方法区,

    这些二进制数据所代表的存储结构会被转化为方法区中运行时的数据结构

  • 开个入口(生成一个代表此类的java.lang.Class对象,作为访问方法区这些数据结构的入口)

    在方法区中创建相应的Class对象(这里的Class对象与平时所说的对象是不一样的,
    当使用new创建实例对象时,就会通过Class对象在堆中创建实例对象)用来封装保存在方法区内的数据结构

类的连接

  • 【验证阶段】:用于检验被加载的类是否有正确的内部结构,并和其他类协调一致

    文件格式验证:验证字节流是否符合class文件的规范,确保输入的字节流能正确解析并存储到方法区

    元数据验证:对字节码描述的信息进行语义分析,保证其描述的信息符合规范要求。
    字节码验证:这个阶段是比较复杂的,通过数据流和控制流分析,对类的方法体进行校验,确保程序的合法性。

    符号引用验证:这里的符号引用不单单指类的,也包括方法。
    ​ 发生在符号引用转为直接引用的时候,也就是解析阶段,
    ​ 对常量池中各种符号引用的信息进行匹配性校验,确保解析动作正确执行

  • 【准备阶段】:负责为类的类变量分配内存,并设置默认初始化值

    需要注意的是:

    * 静态变量只会给默认值。
        * 例:public static int value = 123; // 此时赋给value的值是0,不是123。
    
    * 静态常量(static final修饰的)则会直接赋值。
        * 例:public static final int value = 123; // 此时赋给value的值是123。
    
  • 【解析阶段】:将类的二进制数据中的符号引用替换为直接引用

类的初始化

类的初始化的主要工作是为静态变量赋程序设定的初值。

类的初始化步骤

  • 假如类还未被加载和连接,则程序先加载并连接该类
  • 假如该类的直接父类还未被初始化,则先初始化其直接父类
  • 假如类中有初始化语句,则系统依次执行这些初始化语句
  • 注意:在执行第2个步骤的时候,系统对直接父类的初始化步骤也遵循初始化步骤1-3

类的初始化时机

  • 创建类的实例
  • 调用类的类方法
  • 访问类或者接口的类变量,或者为该类变量赋值
  • 使用反射方式来强制创建某个类或接口对应的java.lang.Class对象
  • 初始化某个类的子类
  • 直接使用java.exe命令来运行某个主类

类加载器

类加载器的作用

负责将.class文件加载到内存中,并为之生成对应的 java.lang.Class 对象。虽然我们不用过分关心类加载机制,但是了解这个机制我们就能更好的理解程序的运行!

简单来说:类加载器的作用,就是把class文件装进虚拟机

类加载机制

  • 全盘负责

    就是当一个类加载器负责加载某个Class时,该Class所依赖的和引用的其他Class也将由该类加载器负责载入,除非显示使用另外一个类加载器来载入

  • 父类委托

    就是当一个类加载器负责加载某个Class时,先让父类加载器试图加载该Class,只有在父类加载器无法加载该类时才尝试从自己的类路径中加载该类

  • 缓存机制

    保证所有加载过的Class都会被缓存,当程序需要使用某个Class对象时,类加载器先从缓存区中搜索该Class,只有当缓存区中不存在该Class对象时,系统才会读取该类对应的二进制数据,并将其转换成Class对象,存储到缓存区

双亲委派机制

  • 当前ClassLoader首先从自己已经加载的类中查询是否此类已经加载,如果已经加载则直接返回原来已经加载的类。每个类加载器都有自己的加载缓存,当一个类被加载了以后就会放入缓存,等下次加载的时候就可以直接返回了。
  • 当前ClassLoader的缓存中没有找到被加载的类的时候,委托父类加载器去加载,父类加载器采用同样的策略,首先查看自己的缓存,然后委托父类的父类去加载, 一直到bootstrp ClassLoader.
  • 当所有的父类加载器都没有加载的时候,再由当前的类加载器加载,并将其放入它自己的缓存中,以便下次有加载请求的时候直接返回。

这样做的好处是什么?

1.避免重复加载。当父亲已经加载了该类的时候,就没有必要子ClassLoader再加载一次。
2.为了安全。避免核心类,比如String被替换。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dntytLVb-1692620952897)(asseits/1de2c4d28014486fa71fdcd0938cd31a.png)]

Java中的内置类加载器

当JVM启动的时候,Java缺省开始使用如下三种类加载器

  • Bootstrap ClassLoader

    引导类加载器(根类加载器), 用来加载 Java 的核心库,是用原生代码来实现的,
    比如:System.String等,jre的lib下rt.jar文件中

  • Platform ClassLoader

    平台类加载器可以看到所有平台类 ,平台类包括由平台类加载器或其祖先定义的Java SE平台API,其实现类和JDK特定的运行时类

  • System ClassLoader

    它也被称为应用程序类加载器(系统类加载器)(Application ClassLoader) ,与平台类加载器不同。 系统类加载器通常用于定义应用程序类路径,模块路径和JDK特定工具上的类

    负责在jvm启动时加载来自java命令的class文件,以及classpath环境变量所指定的jar和类路径

  • UserClass Loader

    自定义类加载器

如果核心包中没有项目所需要的jar,还有一个扩展加载器:将扩展的jar进行加载

类加载器的继承关系:System的父加载器为Platform,而Platform的父加载器为Bootstrap

反射

反射概述

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

反射理解:
可以通过这个对象拿到字节码文件,通过子节码文件还原到类的本身(也就是说你拿到类的Class对象去使用这个类的成员方法,成员变量,构造方法)文章来源地址https://www.toymoban.com/news/detail-664111.html

获取Class类对象的三种方式

  • 类名.class属性
  • 对象名.getClass()方法
  • Class.forName(全限定类名)方法
public class Person {
   
	//私有成员变量	
	private String name;    
    //默认成员变量
	int age;    
    //公有成员变量
	public String address;

    //公有无参构造方法
	public Person() {
   
	}    
	//私有的有参构造方法 1个参数
	private Person(String name) {
   
		this.name = name;
	}    
	//默认的有参构造方法 2个参数
	Person(String name, int age) {
   
		this.name = name;
		this.age = age;
	}    
	//公有的有参构造方法 3个参数
	public Person(String name, int age, String address) {
   
		this.name = name;
		this.age = age;
		this.address = address;
	}
    
	//公有的无参无返回值方法
	public void show() {
   
		System.out.println("show");
	}    
	//公有的有参无返回值方法
	public void method(String s) {
   
		System.out.println("method " + s);
	}    
	//公有的有参有返回值方法
	public String getString(String s, int i) {
   
		return s + "---" + i;
	}    
	//私有的无参无返回值方法
	private void function(

到了这里,关于Java基础篇——反射&枚举的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • java基础-集合+泛型+枚举

    说明: 集合框架是一个类库的集合,里面还有很多接口。 里面虚框都是接口 。 全部在java.util HashSet是基于HashMap实现的。 TreeSet是一个有序Set。 ArrayList能快速随机访问,可变大小。 LinkedList随机访问相对慢,但是可以当作stack或者queue来用。 下面是List接口常用的方法: 使用的

    2024年02月20日
    浏览(26)
  • 「Java基础入门」Java中switch怎么使用枚举

    在Java开发中,switch语句是一种常用的流控制语句,用于根据不同的条件执行不同的代码块。而当使用枚举类型作为条件时,我们常常会遇到“Constant expression required”的报错问题,这给程序开发造成了不小的困扰。 switch 语句中的变量类型可以是: byte、short、int 或者 char。从

    2024年02月16日
    浏览(20)
  • 【Java 基础篇】Java反射:深入了解Class对象

    Java是一门强类型语言,它要求在编译时知道所有的类和对象类型。然而,有时候我们需要在运行时动态地获取和操作类的信息,这就是Java反射的用武之地。本文将深入探讨Java反射,特别是与Class对象相关的内容。 反射是一种机制,允许我们在运行时检查、获取和操作类的信

    2024年02月06日
    浏览(34)
  • 【Java基础】深入理解反射、反射的应用(工厂模式、代理模式)

    Java 反射机制是指在 运行时动态地获取和操作类的信息、调用对象的方法和访问对象的属性的能力 。通过反射,可以在程序运行时分析和修改类的结构、行为和状态。 Java 反射机制提供了以下功能: 获取类的信息:可以获取类的名称、修饰符、父类、实现的接口等。 创建对

    2024年02月09日
    浏览(40)
  • Java安全基础之Java反射机制和ClassLoader类加载机制

    目录 Java 反射机制 反射 java.lang.Runtime ClassLoader 类加载机制 URLClassLoader loadClass() 与 Class.forName() 的区别? Java 反射(Reflection)是 Java 非常重要的动态特性。在运行状态中,通过 Java 的反射机制,我们能够判断一个对象所属的类。了解任意一个类的所有属性和方法。能够调用任

    2024年04月22日
    浏览(29)
  • Java基础_反射机制(尚硅谷-学习笔记)

    反射的概述(熟悉) ● Java给我们提供了一套API,使用这套API我们可以在运行时动态的获取指定对象所属的类,创建运行时类的对象,调用指定的结构(属性、方法)等。 ● API: ○ java.lang.Class:代表一个类 ○ java.lang.reflect.Method:代表类的方法 ○ java.lang.reflect.Field:代表类

    2024年02月11日
    浏览(23)
  • JAVA使用反射机制和注解实现对信息的处理-----JAVA入门基础教程

    import java.lang.annotation.Annotation; import java.lang.reflect.Field; public class AnnotationTest { public static void main(String[] args) throws Exception { Class c = Class.forName(\\\"Customer\\\"); c = Customer.class; Table table = (Table)c.getDeclaredAnnotation(Table.class); System.out.println(table.value()); Annotation[] annotations = c.getDeclaredAnnotatio

    2024年02月15日
    浏览(34)
  • Java 基础进阶篇(十七):反射概述及获取对象的方式

    反射是指对于任何一个Class类,在 “运行的时候”,不用创建对象,就可以直接得到这个类全部成分。 在运行时,可以直接得到这个类的构造器对象:Constructor 在运行时,可以直接得到这个类的成员变量对象:Field 在运行时,可以直接得到这个类的成员方法对象:Method 这种

    2024年02月07日
    浏览(27)
  • Java 基础进阶篇(三)—— 权限修饰符、final 关键字与枚举

    权限修饰符 用于约束成员变量、构造器、方法等的访问范围。 权限修饰符: 有四种作用范围由小到大 (private - 缺省 -protected - public) 注: 不同包下的子类指的是,不同包下的子类对象能访问,当前类创建父类对象访问不了。 定义成员变量、构造器、方法等一般需满足如下要

    2024年02月02日
    浏览(40)
  • 反射、枚举

    反射的定义:Java的反射机制是在运行状态中,都能对任意的类拿到这个类的所有属性,从而对其进行相应的修改; 用途:在日常第三方应用开发中,可以通过反射机制来获取某个类的私有成员变量或是方法;主要是用来开发各种通用框架; 优缺点:         优      

    2024年02月02日
    浏览(17)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包