【Java】反射入门

Java新手入门200例121之通过Java反射创建类对象 文章目录作者简介引言导航热门专栏推荐创建类Person实现小结导航热门专栏推荐 作者简介 作者名:编程界明世隐 简介:优快云博客专家,从事软件开发多年,精通Java、JavaScript,博主也是从零开始一步步把学习成长、深知学习和积累的重要性,喜欢跟广大ADC一起打野升级,欢迎您关注,期待与您一起学习、成长、起飞! 引言 很多Java初学者问我,新手明明很用心、很努力学习的Java知识,转头又忘记了,很让人犯愁,小白如何能够快速成长、成为大牛呢? 其实要成为大神的技巧只有一个:“多学多练”,于是明 阅读详情

本文是面向初学者的反射入门教程。主要内容是在运行时获取类的构造方法、成员方法、成员变量。文章侧重于怎么做(代码怎么写),弱化对反射内部原理的解释说明。

目录

什么是反射

类加载器

Class类

Constructor类

Field类

Method类


什么是反射

反射的定义:允许运行中的 Java 程序获取自身的信息,并且可以操作类或对象的内部属性。通过 Class类 获取 某类的字节码信息称之为反射(Reflection)。

反射的功能:

  1. 对于任意一个类,都能够知道这个类的所有属性和方法;
  2. 对于任意一个对象,都能够调用它的任意一个方法和属性;

反射的前提:

  1. 被反射的类,一定要有空参数的构造方法;
  2. 构造方法权限必须是public;

JAVA语言编译之后会生成一个.class文件,反射就是通过字节码文件找到某一个类、类中的方法以及属性等。并且调用该类的方法和属性。

反射的实现主要借助以下四个类:

  1. Class:代表任何的类
  2. Constructor:代表类的构造方法
  3. Field:代表类中的属性
  4. Method:代表类中的方法

类加载器

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

类的加载过程:

  1. 加载
    1. 就是指将class文件读入内存,并为之创建一个Class对象。
    2. 任何类被使用时系统都会建立一个Class对象
  2. 连接
    1. 验证 是否有正确的内部结构,并和其他类协调一致
    2. 准备 负责为类的静态成员分配内存,并设置默认初始化值
    3. 解析 将类的二进制数据中的符号引用替换为直接引用
  3. 初始化
    1. 创建类的实例
    2. 类的静态变量,或者为静态变量赋值
    3. 类的静态方法
    4. 使用反射方式来强制创建某个类或接口对应的java.lang.Class对象
    5. 初始化某个类的子类
    6. 直接使用java.exe命令来运行某个主类

类加载器的组成

  • Bootstrap ClassLoader 根类加载器
  1. 也被称为引导类加载器,负责Java核心类的加载,最基础的文件加载
  2. 比如System,String等。在JDK中JRE/lib/rt.jar文件中
  • Extension ClassLoader 扩展类加载器
  1. 负责JRE的扩展目录中jar包的加载,也即加载JRE/lib/ext/*jar
  2. 在JDK中JRE的lib目录下ext目录
  • System ClassLoader 系统类加载器
  1. 负责在JVM启动时加载来自java命令的class文件,以及classpath环境变量所指定的jar包和类路径。例如,在MySQL的驱动的时候,就是在系统类加载器中实现加载的。

通过这些描述就可以知道我们常用的类,都是由谁来加载完成的。到目前为止我们已经知道把class文件加载到内存了,那么,如果我们仅仅站在这些class文件的角度,我们如何来使用这些class文件中的内容呢?这就是我们反射要研究的内容。

如何获得类加载器:

获得该类的字节码对象:Class c = 类名.class;

获得类加载器:ClassLoader cl = c.getClassLoader();

获得该类下的所有资源:getResource(“资源名”);

Class类

什么是Class类:

  1. 当JVM装载了字节码文件(即.class文件)后,会把每一个类都封装到Class类实例中,每一个类都对应着一个Class实例。
  2. Class类实例(即Class对象)中保存的是创建类的一些列数据信息,比如创建一个HelloWorld类,那么JVM会生成一个内容是HelloWorld的Class类对象。
  3. Class类的作用是运行时提供或获得某个对象的类型信息,和C++中的typeid()函数类似。这些信息也可用于反射。

特性:

  • Class 没有公共构造方法。即不能程序员创建。
  • Class 对象是在加载类时由 Java 虚拟机以及通过调用类加载器中的 defineClass 方法自动构造的。
  • 所在位置:java.lang.Class<T>

获取Class对象的三种方式:

  1. 对象获取
    类名 变量名1 = new 类名();
    Class 变量名2 = 变量名1.getClass();
  2. 类名获取
    Class 变量名 = 类名.class;
  3. Class类的静态方法获取
    Class 变量名 = Class.forName(字符串的类名,即包名和类名要一起);(注意需要抛出异常ClassNotFoundException)

注意:三种方式获取到的Class对象相等!

如何通过反射创建对象?

  1. 方案一:获取Class类对象,调用newInstance()方法,注意这种方式只能生成object类的实例
  2. 方案二:获取Class类对象,获取构造器,由构造器调用newInstance()方法

通过反射快速创建类实例

//前提:①必须又有空构造方法; ②构造方法权限必须是public
package kyle;

import entity.Person;

import java.lang.reflect.Constructor;

public class Main {
    public static void main(String[] args) throws Exception {
        Class c = Class.forName("entity.Person");
        Object obj = c.newInstance();
        System.out.println(obj.toString());

        Constructor<Person> con = c.getConstructor(String.class,Integer.class,String.class);
        Person person = con.newInstance("kyle",22,"man");
        System.out.println(person.toString());
    }
}
/*
    输出:
    Person{name='null', age=null, sex='null'}
    Person{name='kyle', age=22, sex='man'}
 */

Constructor类

java.lang.reflect.Constructor<T>

获取构造器:

public构造器

  1. Constructor getConstructor()
  2. Constructor[] getConstructors()
  3. Constructor<T> getConstructor(Class<?>... parameterTypes)  获取指定参数名的构造器。例如Constructor con = c.getConstructor(String.class,int.class);就是获取参数为String和int型的构造函数

所有(含private)构造器

  1. Constructor[] getDeclaredConstructors()  获取全部构造器,即使是private的构造器
  2. Constructor getDeclaredConstructor(Class... parameterTypes)  获取指定参数的构造器,即使是private的构造器

操作构造器:

  1. void setAccessible(true)  修改构造器访问权限,true代表暴力攻破权限,false表示保留不可访问权限(暴力反射)
  2. T newInstance(Object… initargs)  调用构造器传入初始化参数,创建对象

获取public的构造器

import java.lang.reflect.Constructor;

public class Main {
	public static void main(String[] args) throws Exception {
		Class c = Class.forName("kyle.Person"); //获取kyle包下的Person类
		
		// Constructor[] getConstructors() 获取class文件对象中的所有公共的构造方法
		Constructor[] cons = c.getConstructors();
		for (Constructor con : cons) {
			System.out.println(con);
		}
		/*输出
			public kyle.Person(java.lang.String,int)
			public kyle.Person()
		*/
		
		//获取空参数的构造方法
		Constructor con =  c.getConstructor();
		System.out.println(con); //输出:public kyle.Person()
		
		//使用空参构造器创建类实例
		Object obj = con.newInstance();
		System.out.println(obj.toString()); //输出:Person [name=null, age=0]
	}
}

获取public有参构造器

import java.lang.reflect.Constructor;

public class Main {
	public static void main(String[] args) throws Exception {
		Class c = Class.forName("kyle.Person");
		//获取带有指定参数的构造方法
		//Constructor<T> getConstructor(Class<?>... parameterTypes)  
		//Class<?>... parameterTypes 传递要获取的构造方法的参数列表
		Constructor con = c.getConstructor(String.class,int.class);

		//使用该构造器创建实例
		// T newInstance(Object... initargs)  
		//Object... initargs 运行构造方法后,传递的实际参数
		Object obj = con.newInstance("张三",20);
		System.out.println(obj);
	}
}
//输出;Person [name=张三, age=20]

获取私有的构造方法

import java.lang.reflect.Constructor;

public class Main {
	public static void main(String[] args) throws Exception {
		Class c = Class.forName("kyle.Person");
		//Constructor[] getDeclaredConstructors()获取所有的构造方法,包括私有的
		Constructor[] cons = c.getDeclaredConstructors();
		for(Constructor con : cons){
			System.out.println(con);
		}
		/*输出:
		private kyle.Person(int,java.lang.String)
		public kyle.Person(java.lang.String,int)
		public kyle.Person()
		*/
		
		//Constructor getDeclaredConstructor(Class...c)获取到指定参数列表的构造方法
		Constructor con = c.getDeclaredConstructor(int.class, String.class);

		// Constructor类的父类中有一个父类AccessibleObject
		// 该类有个方法setAccessible(boolean b),可以实现私有的变量和方法的获取
		con.setAccessible(true);

		Object obj = con.newInstance(18, "lisi");
		System.out.println(obj);
	}
}

Field类

java.lang.reflect.Field

 

public成员变量:

  1. Field getField(String name);
  2. Field [] getFields();

全部(含private、常量、静态)成员变量:

  1. Field getDeclaredField(String name);
  2. Field[] getDeclaredFields();

操作成员变量:

  1. void set(Object obj, Object value):给对象注入某个成员变量数据
  2. Object get(Object obj):获取对象的成员变量的值。
  3. void setAccessible(true);暴力反射,设置为可以直接访问私有类型的属性。
  4. Class getType(); 获取属性的类型,返回Class对象。
  5. String getName(); 获取属性的名称。

获取public成员变量

import java.lang.reflect.Field;

public class Main {
	public static void main(String[] args) throws Exception {
		Class c = Class.forName("kyle.Person");
		
		// Class类的方法:getFields()可以获取被反射类中的所有public成员变量
		// 返回值是Field[],其中Field类描述成员变量对象的类
		Field[] fields = c.getFields();
		for(Field f : fields){
			System.out.println(f);
		} //输出:public java.lang.String kyle.Person.name
		
		//获取指定的成员变量: Field getField(传递字符串类型的变量名)
		Field field = c.getField("name");
	   
		//修改成员变量的值:void set(Object obj, Object value)
		//Object obj 必须有对象的支持,  Object value 修改后的值
		Object obj = c.newInstance();
		field.set(obj,"王五");
		System.out.println(obj); //输出:Person [name=王五, age=0]
	}
}

Method类

java.lang.reflect.Method

 

获取public方法:

  1. public Method[] getMethods() throws SecurityException; 返回某个类的所有公用(public)方法,包括其继承类的公用方法。
  2. public Method getMethod(String name, Class<?>... parameterTypes);

获取全部(含private)方法:

  1. public Method[] getDeclaredMethods() throws SecurityException; 返回类或接口声明的所有方法,包括公共、保护、默认(包)访问和私有方法,但不包括继承的方法。
  2. Method getDeclaredMethod(String name, Class<?>... parameterTypes);

操作方法:

Object invoke(Object obj, Object... args)  参数一:触发的是哪个对象的方法执行。参数二: args:调用方法时传递的实际参数

获取并执行成员方法

import java.lang.reflect.Method;

public class Main {
	public static void main(String[] args) throws Exception {
		Class c = Class.forName("kyle.Person");
		//获取被反射类中的成员方法:Method[] getMethods()获取的是class文件中的所有公共成员方法,包括继承的
		Method[] methods = c.getMethods();
		for(Method m : methods){
			System.out.println(m);
		}
		
		//获取指定的方法:Method getMethod(String methodName,Class...c)
		Method method = c.getMethod("eat"); //获取“eat”方法
		
		//运行获取到的方法
		Object obj = c.newInstance();
		//Object invoke(Object obj, Object...o)
		method.invoke(obj);
	}
}

 

总结:

  • 获取Class:
  1. Class c = new 类名().getClass();
  2. Class c = 类.class;
  3. Class c = Class.forName("类全名");
  • 获取构造方法Constructor:getConstructor、getConstructors、getDeclaredConstructor
  • 获取成员变量 Field:getField、getDeclaredField
  • 获取成员方法Method:getMethod、getDeclaredMethod

 

 

Java新手入门200例119之Java反射机制得到类的包名和类名 文章目录作者简介引言导航热门专栏推荐小结导航热门专栏推荐 作者简介 作者名:编程界明世隐 简介:优快云博客专家,从事软件开发多年,精通Java、JavaScript,博主也是从零开始一步步把学习成长、深知学习和积累的重要性,喜欢跟广大ADC一起打野升级,欢迎您关注,期待与您一起学习、成长、起飞! 引言 很多Java初学者问我,新手明明很用心、很努力学习的Java知识,转头又忘记了,很让人犯愁,小白如何能够快速成长、成为大牛呢? 其实要成为大神的技巧只有一个:“多学多练”,于是明哥就整理了比较典型的练习 阅读详情

相关推荐

Cadence IC5141保姆级教程:Bandgap电路四大仿真(稳定性/噪声/启动/PSRR)完整流程与调参心得

本文提供Cadence IC5141中Bandgap电路的四大仿真(稳定性仿真、噪声仿真、启动仿真、PSRR仿真)的完整流程与调参心得。从原理图检查到ADE L配置,详细解析各仿真步骤的关键参数设置与优化策略,帮助工程师高效完成电路设计与性能调优。

weixin_30399821的博客 1650

java反射获取和设置实体类的属性值 递归所有父类

最近做一个通用数据操作接口,需要动态获取和设置实体类的属性值,为了通用实体做了多重继承,开始网上找到代码都不支持父类操作,只能自己搞一个工具类了,此工具类可以设置和获取所有父类属性,代码贴下面拿走不谢。我也是刚入手小白,代码可能有待优化 package com.muyuer.common.utils.common; import lombok.extern.slf4j.Slf4j; i...

weixin_30897079的博客 727

Ollama模型路径迁移实战:Windows/Mac/Linux三系统保姆级教程(附常见问题排查)

本文提供了一份详细的Ollama模型路径迁移教程,涵盖Windows、macOS和Linux三大操作系统。针对默认安装路径占用系统盘空间的问题,文章指导用户如何安全移动模型文件、配置环境变量、重启服务,并附有迁移后的验证步骤与常见问题排查方法,帮助用户高效管理本地AI模型存储。

gray5的博客 540

Java类类getDeclaredMethods()方法及示例

类类getDeclaredMethods()方法 (Class class getDeclaredMethods() method) getDeclaredMethods() method is available in java.lang package. getDeclaredMethods()方法在java.lang包中可用。 getDeclaredMethods() method is ...

cumubi7552的博客 1万+

AF3 ProteinDataset类的_patch方法解读

AlphaFold3 protein_dataset模块 ProteinDataset 类  _patch 方法的主要目的是围绕锚点残基(anchor residues)裁剪蛋白质数据,提取一个局部补丁(patch)作为模型输入。

qq_27390023的博客 1147

VS2022配置Qt6

VS2022配置QT教程

Life is a struggle ! 6359

(反射与类操作)反射调用普通方法

获取方法 在进行反射处理的时候也可以通过反射来获取类之中的全部方法,但是需要提醒的是,如果要想通过反射调用这些方法,必须在类之中提供有实例化对象。 在Class类里面提供有如下的操作可以获取方法对象: 获取全部方法(反映此 类对象表示的类或接口的所有已声明方法,但不包括继承的方法): public Method[] getDeclaredMethods() throws SecurityException 获取指定方法:public Method getDeclaredMethod​(String.

weixin_46245201的博客 268

【ROS2】Arduino系列之机器人底盘实现

介绍ros中提供的一个已经封装了的模块: ros_arduino_bridge,该模块由下位机驱动和上位机控制两部分组成,通过该模块可以更为快捷、方便的实现自己的机器人平台

guilin 1483

Java 递归 反射 正则表达式

一 递归 1. 就是函数自身调用自身 (就是在栈内存中不断的加载同一个函数) 2. 什么时候用递归呢? 当一个功能被重复使用 而每一次使用该功能时的参数不确定 都由上次的功能元素结果来确定 简单说: 功能内部又用到该功能 但是传递的参数值不确定(每次功能参与运算的未知内容不确定) 3. 递归的注意事项 1> 一定要定义递归的条件 2> 递归的次数不要过多 容易出现 Sta...

weixin_30487701的博客 238

Android GWP-Asan机制详解

基本用途:GWP-ASan是一种原生内存分配器功能,在内存分配时额外记录一些信息,用于检测DOUBLE_FREE、USE_AFTER_FREE、INVALID_FREE、BUFFER_OVERFLOW、BUFFER_UNDERFLOW五种内存错误问题。

专注于系统快稳省领域 4143

Trae中配置和使用MCP 服务保姆级教程

您好,我是程序员夏叶,深度AI编程使用者,专注于分享AI编程方面的使用技巧和经验,有兴趣的可以关注我的公众号,一起学习,共同进步。从21号开始,Trae开始陆陆续续的灰度推送了一次新版本,有的用户是21号收到的更新,有的用户是22号收到的更新,本次更新我愿称之为王炸级更新,具体更新内容可以去看我的上一篇文章。本次更新其中的一个内容就是支持了MCP 服务,那么什么是MCP呢,它的全称是。

cpp加油站的专栏 8195

java 递归树结构,采用反射动态id,父类id,children

@Service public class BaseTreeService { /** * 集合转树结构 * * @param allList 目标集合 * @param id 节点编号字段名称 * @param parent 父节点编号字段名称 * @param children 子节点集合属性名称 ...

weixin_34503526的博客 1138

uniapp [全端兼容] - 详细实现集成接入萤石云摄像头监控示例代码,页面单个或多个九宫格监控画面同时监控播放推流(视频控制方向上下左右移动/调节音量声音/全屏/截屏录制/回放/对讲/切换清晰度)

uni-app,h5移动端网页,小程序,安卓,苹果ios,app,nvue,EZVIZ萤石,uniapp萤石云摄像头监控,uniApp项目集成萤石云详细示例代码,Uniapp中使用萤石云播放视频,使用萤石云播放视频,萤石云实现多窗口监控,展示多个监控画面同时播放,ezuikit.js,云台控制左右移动,莹石摄像头直播视频,萤石视频回放,摄像头黑屏不显示,加载慢报错出错,多个摄像头宫格布局,niapp萤石云视频监控对接,实现海康萤石直播预览、回放、云台控制功能,如何利用萤石实现直播推流回流,实时监控播放,监控

🏆 前端领域优质创作者 1万+

谈谈Java反射:从入门到实践,再到原理

前言反射是Java底层框架的灵魂技术,学习反射非常有必要,本文将从入门概念,到实践,再到原理讲解反射,希望对大家有帮助。反射理解官方解析Oracle 官方对反射的解释是:Reflecti...

weiwenhou的博客 1172

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

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

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

java的反射机制入门

理解Java的反射机制对学习Java框架有很大帮助,比如Spring框架的核心就是使用Java反射实现的,同时对做一些Java底层操作也会有帮助,比如字节码操作、自定义注解等。 什么是反射 Java反射说的是在运行状态中,对于任何一个类,我们都能够直到这个类有哪些方法和属性。对于任何一个对象,我们都能够对它的方法和属性进行调用。这种动态获取对象信息和调用对象方法的功能就是Java的反...

weixin_30391339的博客 102

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

java——反射入门

文章目录反射介绍反射的四大核心类1.Class类获取Class对象的三种方式获取构造器获取字段获取方法2.Constructot类3.Field类4.Method类setAccessible 反射介绍 反射是java中很重要的一个高级特性,在很多框架中都有用到,动态代理也是使用反射来实现的。 通过反射,我们可以在程序运行期间就获得类或对象的所有信息。对于一个类,反射可以获得它的所有属性和方法信息,对于一个对象,我们可以调用它的所有方法和属性,可以理解反射就是对类的解剖 反射的四大核心类 1.Class类 ​

m0_47191576的博客 353

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

JAVA入门之反射

Class类的使用 万物皆对象 类是java.lang.Class类的实例对象。 这个对象如何表示 class Foo{ } Foo foo1 = new Foo(); Class c1 = Foo.class; Class c2 = foo1.getClass(); // Class 是类类型 // 不管c1 or c2 都是Foo类的类类型,一个类只可能是Class类的一个...

308

【java反射·入门技巧】

反射入门案例与技巧

weixin_60351739的博客 245

Java小白入门到实战应用教程-反射

Java小白入门到实战应用教程-反射前言我们前面关于Java基础语法的所有知识点基本上都讲完了,今天我们来了解一个相对高级一点的知识点:反射。我们知道在Java中创建对象我们可以通过关键字new去创建类的对象实例。那么除了这种方式,在java中还可以通过反射去创建Java类的实例。正文在Java中,当我们使用某个类时,首先...

weixin_40273193的博客 82

JAVA入门——反射

/返回所有公共构造方法对象的数组。//返回所有构造方法对象的数组。//返回所有公共成员变量对象的数组。//返回所有成员变量对象的数组。//返回所有成员方法对象,//返回单个公共成员变量对象。

2301_80216298的博客 844

大白话说Java反射:入门、使用、原理

大白话说Java反射:入门、使用、原理 - 陈树义 - 博客园

qq_34828100的博客 157

java反射入门,JAVA从入门到精通之java反射

本篇文章探讨了JAVA从入门到精通之java反射,希望阅读本篇文章以后大家有所收获,帮助大家对相关内容的理解更加深入。<java反射java反射机制按照百度百科的解释,即:Java反射说的是在运行状态中,对于任何一个类,我们都能够知道这个类有哪些方法和属性。对于任何一个对象,我们都能够对它的方法和属性进行调用。我们把这种动态获取对象信息和调用对象方法的功能称之为反射机制。public cla...

weixin_39736934的博客 92

java有5位字符怎么表示_Java基础入门要学哪些 怎么掌握反射和枚举

  Java基础入门要学哪些?怎么掌握反射和枚举?Java是老牌编程语言,是一种可以撰写跨平台应用软件的面向对象的程序设计语言。Java所包含的基础知识点很多,只有掌握了这些知识才能更好地运用,下面就来给大家分享一下Java基础入门学习中有关枚举和反射的知识。  反射  反射就是动态加载一个指定的类,并获取该类中的所有的内容。反射可以将字节码文件封装成对象,并将字节码文件中的内容都封装成对象,这样...

weixin_30280259的博客 243

反射java 入门_Java 反射简单入门

Java 反射简单入门Java反射介绍Java反射的作用在Java运行时环境中,对于任意一个类,可以知道这个类有哪些属性和方法。 对于任意一个对象,可以调用它的任意一个方法。 这种动态获取类的信息以及动态调用对象的方法的功能来自于Java 语言的反射(Reflection)机制。反射结构分析Java反射原理:将普通java类的各个组成部分分别封装为对象,包括类的成员变量、成员方法、成员构造。其所对...

weixin_39870199的博客 110

Java反射:入门、使用、原理

反射之中包含了一个「反」字,所以想要解释反射就必须先从「正」开始解释。 一般情况下,我们使用某个类时必定知道它是什么类,是用来做什么的。于是我们直接对这个类进行实例化,之后使用这个类对象进行操作。 Apple apple = new Apple(); //直接初始化,「正射」 apple.setPrice(4); 上面这样子进行类对象的初始化,我们可以理解为「正」。 而反射则是一开始并不知道...

鲸小鱼的优快云私人博客 73

java反射三种方法_Java基础入门要学哪些 怎么掌握反射和枚举

  Java基础入门要学哪些?怎么掌握反射和枚举?Java是老牌编程语言,是一种可以撰写跨平台应用软件的面向对象的程序设计语言。Java所包含的基础知识点很多,只有掌握了这些知识才能更好地运用,下面就来给大家分享一下Java基础入门学习中有关枚举和反射的知识。  反射  反射就是动态加载一个指定的类,并获取该类中的所有的内容。反射可以将字节码文件封装成对象,并将字节码文件中的内容都封装成对象,这样...

weixin_39785286的博客 72
上一篇: 【Java】流(Stream)快速入门
下一篇: 【Java】基于util包的日期时间
ALGO阿狗
博客等级 码龄9年 64粉丝 149原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值