JVM-类的加载机制

概率论 知识图谱 + 实战案例解析 本文通过构建概率论知识图谱,系统梳理了从随机试验、概率、条件概率到随机变量与分布的核心概念及其内在联系。结合朴素贝叶斯分类器和蒙特卡洛模拟等实战案例,深入解析了条件概率、独立性及大数定律等理论如何应用于机器学习与实际问题求解,旨在帮助读者建立结构化思维,将理论有效转化为解决实际问题的能力。 阅读详情

概述

虚拟机把描述类的数据从Class文件加载到内存,并对数据进行校验、转换解析和初始
化,最终形成可以被虚拟机直接使用的Java类型,这就是虚拟机的类加载机制。

类加载时机:

类从被加载到虚拟机内存中开始,到卸载出内存为止,它的整个生命周期包括:加载
(Loading)、验证(Verification)、准备(Preparation)、解析(Resolution)、初始化
(Initialization)、使用(Using)和卸载(Unloading)7个阶段。其中验证、准备、解析3个
部分统称为连接(Linking).
在这里插入图片描述

在加载阶段:JVM规范中没有进行约束, 这点可以交给虚拟机的具体实现来自由把握.
在初始化阶段:
JVM严格规范了有且只有以下5种情况必须立即进行初始化(初始化前,必须经过加载,验证解析,准备阶段)
1.使用new实例化对象时,读取(getstatic)和设置(putstatic)类的静态变量,静态非字面值常量时,调用静态方法(invokestatic)时
2.对内进行反射调用时, 如果类没有进行过初始化,则需要先触发其初始化
3.当初始化一个类时,如果父类没有进行初始化,首先要初始化父类.
4.启动程序所使用的main方法所在类
5.当使用1.7的动态语言支持时
以上5种称为主动引用,除此之外的引用被称为被动引用

被动引用常见情况:

  • 调用父类的静态字段,只会初始化父类,不会触发子类的初始化
  • 定义对象数组和集合,不会触发该类的初始化
  • 类A引用类B的static final 常量不会导致类B初始化(注意静态常量必须是字面值常量,否则还是会触发B的初始化)
  • 通过类名获取对象,不会触发类的初始化(System.out.println(Person.class));
  • 通过Class.forName加载指定类时,如果指定参数initialize为false,也不会初始化该类
  • 通过ClassLoader默认的loadClass方法,也不会触发初始化.

类加载过程:

加载流程: 加载->连接(验证->准备->解析)->初始化->使用->卸载

加载

在加载阶段 , JVM需要完成3件事情

  1. 查找并加载类的二进制数据(Class文件)
  2. 静态存储结构转化为方法区运行时数据结构:类的类信息
  3. Java堆生产:Class文件对应的类实例(相当于一个句柄),去访问方法区

加载.class文件的方式:

  • 从本地系统中直接加载
  • 通过网络下载class文件
  • 将java源文件动态编译为.class文件
  • …

验证

确保加载的类信息是正确的

  • 文件格式验证
    • 验证Class文件的标示:魔数(默认为:CAFE BABE)
    • 验证Class文件的版本号
    • 验证常量池(常量类型,常量类型数据结构是否正确,UTF8是否符合标准)
    • Class文件的每个部分(字段表,方法表)是否正确
  • 元数据验证(父类验证,继承验证,接口验证,final验证)
    • 这个类是否有父类,是否实现了父类的抽象方法,是否重写了父类的final方法,是否继承了被final修饰的类等等
  • 字节码验证(指令验证)
  • 符号引用验证(通过符号引用是否能找到类,方法,字段)
    • 通过符合引用能找到对应的类和方法
      ,符号引用中类、属性、方法的访问性是否能被当前类访问等等。

准备

类变量:一般称为静态变量
实例变量:当对象被实例化时,实例变量就被跟着被确定

为类的静态变量(static)分配内存空间并赋予初始值(默认值) ,这些变量所使用的内存都将在方法区中进行分配.

例:static int value = 2;初始化值为0.

这时候尚未开始执行任何Java方法,而把value赋值为2的putstatic指令是程序被编译后,存放于类构造器< clinit>()方法之中,所以把value赋值为2的动作将在初始化阶段才会执行。

而 static final int value = 2;

对应到常量池ConstantValue,在准备阶段必须赋值为2.

数据类型对应的零值
基本数据的零值

解析

将符号引用转化为直接引用
直接引用: 指向目标的指针或者偏移量
主要涉及:类,接口,字段,方法等.
匹配:简单名字+描述符 同时满足

类或接口的解析

public class A{
	C data; //C有可能是个类,或接口
}
  1. 如果C不是一个数组类型 , 那么会将代表N的权限定名传递给A去加载这个类C . 若在加载C的过程中出现了异常,则解析失败.
  2. 如果C是一个数组类型 ,并且数组元素类型为对象 (Integer[] data), 则按照 1中的方式先加载数组元素类型 ,接着由虚拟机生成一个代表此数组维度和元素的数组对象.
  3. 如果上面的步骤没有出现任何异常,那么C在虚拟机中实际上已经成为一个有效的类或接口了,但在解析完成之前还要进行符号引用验证,确认A是否具备对C的访问权限。

如果发现不具备访问权限,将抛出java.lang.IllegalAccessError异常。

字段的解析:

class A extends B implements C,D{
     private int a;  
}
  1. 先在本类去找有没有简单名称和字段描述符匹配的字段,有则返回字段的引用 , 查找结束.
  2. 如果类实现了接口,递归搜索各个接口和它的父接口,如果接口中包含了简单名称和字段描述符都与目标相匹配的字段,则返回这个字段的直接引用,查找结束.
  3. 如果不是继承Object类, 再去搜索父类 , 有则返回.
  4. 否则 , 查找失败

查找可能会有异常

如果找到,没有权限:java.lang.IllegalAccessError 如果失败:java.lang.NoSuchFieldError

类方法的解析:

class A extends B implements C,D{
     public void inc();
}

类方法和接口方法符号引用的常量类型定义是分开的,如果在类方法表中发现class_index中索引的C是个接口,那就直接抛出java.lang.IncompatibleClassChangeError异常。

  1. 在本类里面去找有没有匹配的方法
  2. 父类去找
  3. 接口列表去找方法(如果找到则代表本类是抽象类)

如果找到,没有权限:java.lang.IllegalAccessError 如果失败:java.lang.NoSuchMethodError

接口方法的解析:
与类方法解析不同,如果在接口方法表中发现class_index中的索引C是个类而不是接口,那就直接抛出java.lang.IncompatibleClassChangeError异常。

  1. 在本类找有没有匹配的方法
  2. 父类接口去递归查找

如果失败:java.lang.NoSuchMethodError
由于接口中的所有方法默认都是public的,所以不存在访问权限的问题,因此接口方法的符号解析应当不会抛出java.lang.IllegalAccessError异常。

初始化

java虚拟机对类进行初始化,对静态变量赋予正确值, 真正开始执行类中定义的Java程序代码.
< init>:类的实例构造器
< clinit>:由编译器自动收集类中的所有类变量的赋值动作和静态语句块(static{}块)中的语句合并.(如果没有静态变量,静态块,则没有clinit)

在类中:

< clinit>()方法与类的构造函数(或者说实例构造器< init>()方法)不同,它不需要显式地调用父类构造器,虚拟机会保证在子类的<
clinit>()方法执行之前,父类的< clinit>()方法已经执行完毕。因此在虚拟机中第一个被执行的<
clinit>()方法的类肯定是java.lang.Object。 由于父类的<
clinit>()方法先执行,也就意味着父类中定义的静态语句块要优先于子类的变量赋值操作,

在接口中:

接口中不能有静态块 ,但仍然有变量初始化的赋值操作,因此接口与类一样都会生成< clinit>()方法。
但接口与类不同的是,执行接口的< clinit>()方法不需要先执行父接口的< clinit>()方法。只有当父接口中定义的变量使用时,父接口才会初始化。另外,接口的实现类在初始化时也一样不会执行接口的< clinit>()方法。

虚拟机会保证一个类的< clinit>()方法在多线程环境中被正确地加锁、同步,如果多个线程同时去初始化一个类,那么只会有一个线程去执行这个类的< clinit>()方法,其他线程都需要阻塞等待,直到活动线程执行< clinit>()方法完毕 .

Class A{
    static int i = 2;
    static{
          sout;
     }
    int n;
}

类的加载方式(整个过程)

隐式加载

  • 创建类对象
  • 使用类的静态域
  • 创建子类对象
  • 使用子类的静态域

在JVM启动时,BootStrapLoader会加载一些JVM自身运行所需的class
在JVM启动时,ExtClassLoader会加载指定目录下一些特殊的class
在JVM启动时,AppClassLoader会加载classpath路径下的class,以及main函数所在的类的class文件

显式加载

ClassLoader.loadClass(className),只会加载和链接,不会进行初始化
Class.forName(String name,boolean initialize,ClassLoader loader),使用loader进行加载和链接,根据initialize参数决定是否初始化

类加载器:

对于任意一个类,都需要由加载它的类加载器和这个类本身一同确立其在Java虚拟机中的唯一性 , 每一个类加载器,都拥有一个独立的类名称空间。在比较两个类是否“相等”时 ,只有在这两个类是由同一个类加载器加载的前提下才有意义,否则,即使这两个类来源于同一个Class文件,被同一个虚拟机加载,只要加载它们的类加载器不同,那这两个类就必定不相等。

//sun.misc.Launcher
//..........
/..........
var1 = Launcher.ExtClassLoader.getExtClassLoader();
this.loader = Launcher.AppClassLoader.getAppClassLoader(var1);
//..........

问题: ExtClassLoader和AppClassLoader有什么关系?

ExtClassLoader是AppClassLoader的Parent

//代表同时只有一个load来加载class,保证class的唯一性
findBootStrapClass(String name):  //方法
synchronized(getClassLoadingLock(name)) {
    Class<?> c = findLoadedClass(class);
    if(c == null) {
          ......
          if(parent != null) {
                 //递归调用
           } else {
                  findBootStrapClass(name);  //native方法 JNI调用
            }
     }
}
  • BootStrapClassLoader(C语言编写): JAVA_HOME
    /lib/rt.jar
  • ExtClassLoader: JAVA_HOME/lib/ext/javax.* 或"java.ext.dirs"指向的目录
  • AppClassLoader:自定义的类,负责将系统类路径(CLASSPATH)中指定的类库加载到内存中
  • 用户自定义类加载器: 流,网络,数据库

双亲委派机制(安全)

在这里插入图片描述
如果一个类加载器收到了类加载的请求,他首先不会自己去尝试加载这个类,而是把请求委托给父类加载器去完成,依次向上.因此,所有的类加载请求最终都会被传递到顶层的启动类加载器中.
只有当父加载器在他的搜索范围中没有找到所需的类时,既无法完成加载,自加载器才会尝试自己去加载该类.
父类能加载的,不给子类加载

这种机制有如下好处:

  • 可以保证java核心类库的安全,即保证由引导类加载器加载的类不能被用户随便替换,不能自己定义一个java.lang.String 的类来替换java核心类库的java.lang.String类,否则会抛出ClassCastException。
  • 避免类的重复加载.

加载顺序: 自顶向下 AppClassLoader -> Extension ClassLoader -> BootStrap ClassLoader
检查顺序: 自底向上

倾斜摄影与地面激光点云融合高精度建模研究 本文研究了倾斜摄影与地面激光点云融合精细化建模技术,并通过相应的源代码实现了建模过程。该方法将倾斜摄影和激光扫描相结合,能够获得高精度的三维建模结果,为相关领域的研究和应用提供了有力支持。近年来,倾斜摄影和激光扫描技术的快速发展为高精度三维建模提供了新的机遇和挑战。本文针对倾斜摄影与地面激光点云融合建模这一前沿领域展开研究,旨在通过相应的源代码实现精细化的建模过程。同时,使用激光扫描仪进行地面激光扫描,获取地面的点云数据。经过数据融合和精细化建模处理后,我们获得了高精度的三维建模结果。 阅读详情

相关推荐

STM32电机库(ST-MC-Workbench)实战指南——三电阻电流采样电路参数配置详解

本文详细解析了STM32电机库(ST-MC-Workbench)中三电阻电流采样电路的参数配置方法,涵盖电阻选型、放大增益计算、滤波时间优化等关键步骤。通过实战案例和调试技巧,帮助工程师快速掌握电流采样技术,提升电机控制系统的精度与稳定性。特别针对ST-MC-Workbench界面参数设置提供了详细指导。

weixin_29186249的博客 509

Class.forName() 与 ClassLoader.loadClass() 的区别

Class.forName() 的方式加载类时,默认会执行类的初始化。ClassLoader.loadClass() 的方式加载类时,类不会被初始化,只有显式调用加载的类时才会进行初始化。采用 ClassLoader 进行懒加载,不会调用类的 static 代码块,实现延迟加载。

JellyfishMIX 的博客 795

Jupyter地铁数据分析预测地铁后7天小时客流量

地铁数据分析 基于八月地铁刷卡数据,以前23天的数据作为训练数据,预测后7天各个地铁站点在6点—23点每个小时的客流量。 import pandas as pd import time import numpy as np import matplotlib.pyplot as plt ...

qq_45868915的博客 1754

jvm中变量的存放位置

(如果局部变量是一个reference引用类型,它引用的对象在Java堆中可被各个线程共享,但是reference引用本身在Java栈的局部变量表中,是线程私有的)。Java内存模型的主要目标是定义程序中各个变量的访问规则,即在JVM中将变量存储到内存和从内存中取出变量这样的底层细节。而类的方法却是该类的所有对象共享的,只有一套,对象使用方法的时候方法才被压入栈,方法不使用则不占用内存。类的成员变量在不同对象中各不相同,都有自己的存储空间(成员变量在堆中的对象中)。对象在堆里,对象中的内容就是各种字段。..

m0_67401055的博客 1419

【Get深一度】小波分析概念1——紧支撑集是什么意思,通俗解释

最近学到小波,在仿真中也用到了紧支撑函数;紧支撑性越好,说明能量越集中;用最通俗的话来讲,紧支撑是这样的: 对于函数f(x),如果自变量x在 0附近的取值范围内,f(x)能取到 C; 而在此之外,f(x)取值为 0; 那么这个函数f(x)就是紧支

Trey_优快云 的优快云博客 8349

Ubuntu双系统引导修复实战:boot-repair工具详解

本文详细介绍了使用boot-repair工具修复Ubuntu双系统引导丢失问题的实战方法。当GRUB引导菜单因安装新系统或更新而损坏时,通过制作Ubuntu启动盘进入Live环境,安装并运行boot-repair,可一键完成系统修复引导,自动化执行GRUB重装与配置,解决无法进入Windows或Ubuntu的常见故障。

weixin_29224589的博客 359

JVM-类加载详解

一、JVM类加载过程 JVM类加载过程如下图: JVM类加载过程分为:加载 、链接 、初始化 、使用 、卸载 这五个阶段,其中链接阶段又包括: 验证 、 准备 、 解析 。 加载 :通过类的完全限定名,查找此类的二进制字节码文件,通过该字节码文件创建Class对象。 链接 :包含 验证 、 准备 、 解析 三个阶段: 验证 :确保Class文件复合虚拟机规定的Class文件格式,包含文件格式验证、元数据验证、字节码验证、引用符号验证。 准备 :为类的静态变量分配内存并设置初始化值,注:这里不包含fi

qq_34222160的博客 9038

材料力学小白必看:纯弯曲正应力计算全解析(附实例演示)

本文详细解析了材料力学中纯弯曲正应力的计算原理与工程应用,通过实例演示帮助初学者掌握关键公式和计算流程。内容涵盖纯弯曲的基本假设、正应力分布规律、截面特性计算,以及现代工具如Excel、ANSYS和Python在应力分析中的应用,特别适合材料力学小白系统学习。

sea99的博客 1233

类的成员变量存在JVM的哪块区域

public class A{ public static void main(String[] args){ B b = new B(); } } public class B{ int i; C c; B(){ i = 1; c = new C(); } } public class C{ } 记住一个原则即可:方法体中的引用变量和基本类型的变量都在栈中,其他的都在堆中。 所以B对象里面的所有东

weixin_46314604的博客 1730

AI重塑运营商CRM:从传统办理到智能推荐的实战经验

本文探讨了AI技术如何重塑运营商CRM系统,从传统办理模式升级为智能推荐平台。文章首先分析了传统CRM系统在产品推荐效率、客户信息录入、业务流程和个性化服务等方面的痛点,提出AI赋能的解决方案。技术架构采用分层设计,包含智能推荐引擎、知识图谱系统和大模型集成三大核心模块。实战案例详细介绍了基于深度学习的智能推荐系统实现,包括用户行为特征提取、产品特征建模、推荐模型训练和实时推荐服务等关键组件代码实现,展示了AI如何提升运营商CRM系统的智能化水平和服务效率。

技术传感器的博客 1049

YOLOv13添加轻量化的EMA模块Faster_EMA,轻量又涨点!map50提升4.56个点,召回率提升9.66!

本文介绍了YOLOv13模型的优化移植方法,通过添加Faster_EMA模块和超参数调整,使模型性能显著提升。主要修改包括:1) 创建新的模型配置文件yolov13-Faster_EMA.yaml;2) 在tasks.py中添加新模块;3) 修改__init__.py和block.py文件,新增Partial_conv3和DropPath类。优化后模型mAP50提升4.56%,召回率提升9.66%,验证了改进方案的有效性。代码实现了局部卷积和随机深度等先进技术,为YOLO系列模型性能优化提供了新思路。

FJN110的博客 2606

【JVM】——类的加载机制

一、什么是类的加载 (1)类的加载指的是将类的.class文件中的二进制数据读入到内存中,将其放在运行时数据区的方法区内,然后在堆区创建一个java.lang.Class对象,用来封装类在方法区内的数据结构。类的加载的最终产品是位于堆区中的Class对象,Class对象封装了类在方法区内的数据结构,并且向Java程序员提供了访问方法区内的数据结构的接口。 (2)类加载器并不需要等到某个类被...

我爱吃土豆 8510

基于Python实现身份证信息识别

身份证是一种重要的证件,包含了个人的基本信息,如姓名、性别、出生日期、住址等。在实际应用中,有时需要对身份证进行自动化的识别,以提高工作效率和准确性。本文将介绍如何使用Python实现身份证信息的识别,通过图像预处理、OCR技术和解析算法,实现对身份证号码和其他信息的提取和解析。

商务合作 / 项目定制 / 学习交流。个人vx:lovely_wml 1万+

JVM类的加载机制

在学习之前,我们现象几个问题: 1.JVM的类加载机制是什么? 2.它是如何实现的其功能的? 3.在什么情况下在使用类加载器? 带着这几个问题,我们一步一步深入学习一下。 一、什么是类加载机制? 虚拟机把描述类的数据,从class文件(即一组以8位字节为基础单位的二进制流)加载到内存中,并对数据进行各种处理,最终生成能够直接被虚拟机识别的Java类型; 它分为以下几个...

许我笔墨三千绘你绝世倾城 303

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

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

锂电池充电器电路设计 里面有电路

锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。

【JVM】类的加载机制

JVM类加载机制是Java程序运行的核心过程,主要包括加载、验证、准备、解析和初始化五个阶段。加载阶段通过类加载器获取二进制字节流并转换为运行时数据结构;验证确保字节码符合规范;准备为静态变量分配内存并设置初始值;解析将符号引用转为直接引用;初始化执行类构造器方法完成程序逻辑初始化。类加载器采用双亲委派模型,确保类唯一性和程序稳定性,但也存在三次典型"破坏"以解决兼容性、SPI调用和热部署等需求。整个过程严格规范类加载顺序,同时保留灵活性以适应不同应用场景。

2501_91676654的博客 911

温度PID控制PLC程序

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

【JVM基础】 JVM 如何加载一个类以及类加载机制

如果你要 “new ReplicaManager()” 初始化这个类的实例,那么就会加载这个类,然后初始化这个类,但是初始化这个类之前,发现 AbstractDataManager 还没有加载和初始化,就需要先加载这个父类,并且初始化这个父类。然后从 main 方法的入口代码开始。假设你的应用程序需要去加载一个类,他首先会委派给自己的父类加载器去加载,经过层层床底,最终传递到顶层的类加载器去加载。但是如果父类加载器在自己负责范围加载的范围内没有找到这个类,就会将加载的权利给自己的子类加载器去进行加载。

【程序员不弃】的博客 1964

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

jvm类加载机制_JVM类的加载机制

1.概述虚拟机加载Class文件(二进制字节流)到内存,并对数据进行校验、转换解析和初始化,最终形成可被虚拟机直接使用的Java类型,这一系列过程就是类的加载机制。2.类的加载时机类从被虚拟机加载到内存开始,直到卸载出内存为止,整个生命周期包括:加载——验证——准备——解析——初始化——使用——卸载这7个阶段。其中验证、准备、解析3个部分统称为连接。生命周期图如下:  其中加载、验证、...

weixin_39764494的博客 79

JVM——类的加载机制

JVM将class字节码加载到内存中,将数据

雪人奥特曼的博客 257

类重复引用_JVM类加载机制

JVM类加载机制1、整体流程:2、加载扩展类加载器以及应用类加载器JVM自动调用getLauncher()方法获取launcher实例,而Launcher实例是在引导类加载器加载Launcher类的“初始化”阶段进行实例化的(launcher属性被static修饰)。下面看一下Launcher类的构造方法,可以看到Launcher类是如何加载扩展类加载器以及应用类加载器的:首先创建扩展类...

weixin_34562922的博客 724

JVM类加载机制-类是如何被加载的?

JVM把描述类的数据从Class文件加载到内存,并对数据进行校验、转换解析和初始化,最终形成可以被JVM直接使用的Java类型,这就是JVM的类加载机制类的生命周期JVM规范中初始化的条件被动引用不会触发初始化类加载的过程加载:非数组类:数组类:验证文件格式验证元数据验证字节码验证符号引用验证准备解析初始化 类的生命周期 加载、验证、准备、初始化和卸载5个阶段的顺序是确认的,类加载过程必须按照这种顺序按部就班的开始,在动态绑定中解析可以在初始化后完成 JVM规范中初始化的条件 使用new关键字实例化对象

qq_24760259的博客 869

【JVM】JVM类的加载机制(详解)

类从加载到卸载,整个生命周期统共分为7个阶段: 其中,加载->验证->准备->解析->初始化,这5个过程就是类的加载过程,而且验证->准备->初始化这三个可以统称为连接过程; 解析阶段有时候会在初始化之后再开始; 那么,什么时候会触发类的加载? 1⃣️ main()所在的主类; 2⃣️ 在遇到new、要对某个类的静态变量进行get或set、或者调用它的静态方法时; 3⃣️ 对某个类使用反射时; 4⃣️ 已经在对某个类进行加载,并且进行到初始化阶段时,而它的父..

卷柏的博客 390

JVM虚拟机加载类原理机制

<br />JVM虚拟机加载类原理机制

liu1695347的专栏 543

反射、 Class类、JVM的类加载机制、Class的常用方法

反射、 Class类、JVM的类加载机制、Class的常用方法

hutao8896的博客 1192

JVM--类的加载机制

本文介绍JVM中类加载器的种类和类加载机制(双亲委派)以及JDK9以后的类加载器的变化由不同的类加载器解析相同路径下的类信息得到的类对象不会相同Tomcat:在Tomcat中启动了两个Web服务,这两个服务有着相同的类名不同实现的实现类,此时如果不打破双亲委派机制,先启动的Web服务就会去加载好对应的类,那么后启动的Web服务在自下而上查询类是否被加载过时,就会直接返回先启动服务的类对象那么Tomcat如何打破双亲委派机制呢?给每个服务都专门弄一个类加载器。

nobestnobest的博客 1030
上一篇: JVM-内存分配策略和垃圾回收策略
下一篇: 集合-ArrayList源码分析
Java-fly
博客等级 码龄9年 13粉丝 31原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值