反射

UE4-(反射反射采集 一、现在有两个反射采集形状:球体和盒体 通常将屏幕空间反射反射捕获相结合,两者各有优缺点,结合使用是希望同个结合两者的优点来弥补缺点。 大多情况下使用球体反射采集: 效果:不管怎么移动相机位置,屏幕上都会有反射效果。 问题: 当反射采集与屏幕空间反射过渡时,反射画面中的物体位置会发生变化。 原因:当屏幕空间反射过渡到反射捕获,引擎会切换使用两者,但是屏幕空间反射的优先级始终更高。 解释:反射采集会采集一张360度的瞬时图像,用于反射效果。图像中的物体位置与屏幕空间反射出来的物体位 阅读详情

 .问题的提出

在Java运行时而非编译时环境中:(1)对于任意一个类,能否知道这个类有哪些属性和方法?(2)对于任意一个对象,能否调用它的任意一个方法?答案是肯定的。这种动态获取类的信息以及动态调用对象的方法的功能来自于Java 语言的反射(Reflection)机制。

Java 反射机制主要提供了以下功能:(1)"在运行时"判断任意一个类所具有的成员变量和方法(当然在这之前需要 "在运行时"判断任意一个对象所属的类);(2)"在运行时"调用任意一个对象的方法(当然在这之前需要 "在运行时"构造任意一个类的对象)。

2.Reflection是什么:Reflection是Java被视为动态语言的一个关键性质。

(1)这个机制允许程序在运行时透过Reflection APIs取得任何一个已知名称的class的内部信息(包括其modifiers[诸如public, static 等等]、superclass[例如Object]、实现之interfaces[例如Serializable],也包括fields和methods的所有信息)。

(2)并可于运行时改变fields内容或调用methods。

一般而言,开发者社群说到动态语言,大致认同的一个定义是:“程序运行时,允许改变程序结构或变量类型,这种语言称为动态语言”。从这个观点看,Perl,Python,Ruby是动态语言,C++,Java,C#不是动态语言,但java却有动态机制:Reflection:用在Java身上指的是我们可以于运行时加载、探知、使用编译期间完全未知的classes。换句话说,Java程序可以加载一个运行时才得知名称的class,获悉其完整构造(但不包括methods定义,指method的代码),并生成其对象实体、或对其fields设值、或唤起其methods。这种“看透class”的能力(the ability of the program to examine itself)被称为introspection(内省、内观、反省)。Reflection和introspection是常被并提的两个术语。

3.Reflection的相关类及其方法

(1)在JDK中,主要由以下类来实现Java反射机制

java.lang.Class类:代表一个类。

java.lang.reflect.Field 类:代表类的成员变量(成员变量也称为类的属性)。

java.lang.reflect.Method类:代表类的方法。

java.lang.reflect.Constructor 类:代表类的构造方法。

java.lang.reflect.Array类:提供了动态创建数组,以及访问数组的元素的静态方法

package edu.hust.reflect;

import java.lang.reflect.Method;

public class DumpReflect {

    public static void printMethodOfClass(String className) {
        Class<?> classType = null;
        try {
            classType = Class.forName(className);
        } catch (ClassNotFoundException e) {
            System.err.println("没有这个类,请确认类的完整名称是正确的!!!");
        }
        
        Method[] methods = classType.getDeclaredMethods();
        
        for (Method method : methods) {
            System.out.println(method.toString() + " 方法的缩写为:" + method.getName());
        }
        
    }
    
    public static void main(String[] args) {
        printMethodOfClass("java.lang.Thread");
    }
}
package edu.hust.reflect;

import java.lang.reflect.Method;

public class InvokeTester {
    public int add(int parma1, int param2) {
        return parma1 + param2;
    }
    
    public String echo(String echo_msg) {
        return "The message of echo is: " + echo_msg;
    }
    
    public static void main(String[] args) throws Exception {
        //Class类的实例对象可以理解为一个类. 即相对于Class类来说, 它是一个对象, 但相对于其他java元素来说, 它还是一个类.
        Class<?> classType = InvokeTester.class;
        
        Object obj = classType.getConstructor(new Class[] {}).newInstance(new Object[] {});
        
        /*
         * 生成InvokeTester对象的add()/echo()方法. classType.getMethod()第一个参数是classType中某方法的名字, 第二个参数是classType中某方法的参数
         * 
         * 尽管add()方法的两个参数以及返回值都是int类型,调用addMethod对象的invoke()方法时,只能传递Integer 类型的参数,并且invoke()方法的返回类型也是Integer类型.
         * 
         * */
        Method addMethod = classType.getMethod("add", new Class[] {int.class, int.class});
        Method echoMethod = classType.getMethod("echo", new Class[] {String.class});
        
        Object result = addMethod.invoke(obj, new Object[] {new Integer(100), new Integer(150)});
        System.out.println((Integer) result);
        
        result = echoMethod.invoke(obj, new Object[] {"hi, forrest"});
        System.out.println((String) result);
        
    }
}
(2)java.lang.Class类是Reflection API 中的核心类,它有以下方法

getName():获得类的完整名字。

getFields():获得类的public类型的属性;返回Field类型数组。

getDeclaredFields():获得类的所有属性;返回Field类型数组。

getMethods():获得类的public类型的方法;返回Method类型数组。

getDeclaredMethods():获得类的所有方法;返回Method类型数组。

getConstructors():获得类的public类型的构造方法;返回Constructor类型数组。

getField(String name):获得类的public类型的指定名称的属性

getDeclaredField(String name):获得类的指定名称的属性

getMethod(String name, Class[] parameterTypes):获得类的特定方法,name参数指定方法的名字,parameterTypes参数指定方法的参数类型。

getDeclaredMethod(String name, Class[] parameterTypes):获得类的特定方法,name参数指定方法的名字,parameterTypes参数指定方法的参数类型。

getConstructor(Class[] parameterTypes):获得类的特定构造方法,parameterTypes 参数指定构造方法的参数类型。

newInstance():通过类的不带参数的构造方法创建这个类的一个对象。

package edu.hust.reflect;

import java.lang.reflect.Field;
import java.lang.reflect.Method;

public class CloneBean {

    public static Object cloneBean(Object originalObj) throws Exception {
        // 获得对象的类型
        Class<?> classType_Original = originalObj.getClass();
        
        /*
         * 通过默认构造方法创建一个新的对象
         * 
         * 使用classType_Original.getConstructor(new Class[] {}).newInstance(new Object[] {});方法获得对象, 该对象对应的类的构造方法必须显式的声明出来。
         * 即, public User(){}这句话必须写出来(虽然如果不写, 系统也会自动生成这样一个constructor)
         * 
         * Class类的getConstructor()方法获得一个Constructor对象,然后调用Constructor对象的newInstance()方法构造一个实例, 这里要注意:getConstructor()与newInstance()参数必须保持一致.
         * 
         * 使用classType_Original.newInstance();方法获得对象, 该对象对应的类的构造方法不必显式的声明出来。
         * 但这种方法只适合于:只有一个无参constructor, 而没有其他任何constructor的类
         * 
         * */   
        Object cloneObj = classType_Original.getConstructor(new Class[] {}).newInstance(new Object[] {});
        //Object cloneOb = classType_Original.newInstance();
        
        // 获得对象的所有属性
        Field[] fields = classType_Original.getDeclaredFields();
        
        for (Field field : fields) {
            // 获得和属性对应的getXXX()/setXXX()方法的名字
            String getMethodName = "get" + field.getName().substring(0, 1).toUpperCase() + field.getName().substring(1);
            String setMethodName = "set" + field.getName().substring(0, 1).toUpperCase() + field.getName().substring(1);
            
            // 获得和属性对应的getXXX()/setXXX()方法
            Method getMethod = classType_Original.getMethod(getMethodName, new Class[] {});
            Method setMethod = classType_Original.getMethod(setMethodName, new Class[] {field.getType()});
            
            // 调用原对象的getXXX()方法获得bean的属性值, 调用拷贝对象的setXXX()方法将这些属性值赋给拷贝对象.
            Object value = getMethod.invoke(originalObj, new Object[] {});
            setMethod.invoke(cloneObj, new Object[] {value});
        }
        return cloneObj;
    }
    
    public static void main(String[] args) {
        User1 originalUser = new User1();
        originalUser.setUsername("forrest");
        originalUser.setPassword("vivian");
        User1 cloneUser;
        try {
            cloneUser = (User1) cloneBean(originalUser);
            System.out.println("cloneUser.getUsername():" + cloneUser.getUsername());
            System.out.println("cloneUser.getPassword():" + cloneUser.getPassword());
        } catch (Exception e) {
            // 这里将Exception吞掉了, 这种方法万万要不得, 不过本例只用来演示而已.
        }
    }
    
}

class User1 {
    private String username;
    private String password;
    public User1() {}
    public String getUsername() {
        return username;
    }
    public void setUsername(String username) {
        this.username = username;
    }
    public String getPassword() {
        return password;
    }
    public void setPassword(String password) {
        this.password = password;
    }
}
运行时生成instances:在Reflection动态机制中有两种方法生成对象实体,一个针对"无自变量constructor";一个针对"带参数constructor"。如果欲调用的是"带参数constructor"就比较麻烦些,不再调用Class的newInstance(),而是调用Constructor 的newInstance(),首先准备一个Class[]做为constructor的参数类型,然后以此为自变量调用getConstructor()获得一个专属constructor。接下来再准备一个Object[] 做为constructor实参值,调用上述专属constructor的newInstance()。

运行时调用methods:为什么获得Method object时不需指定回返类型?因为method overloading机制要求signature必须唯一,而回返类型并非signature的一个成份。换句话说,只要指定了method名称和参数列,就一定指出了一个独一无二的method。

运行时变更fields内容:与先前两个动作相比,"变更field内容"轻松多了,因为它不需要参数和自变量。首先调用Class的getField()并指定field名称。获得特定的Field object之后便可直接调用Field的get()和set()方法。

package edu.hust.reflect;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

public class NewInstance {
    public static void main(String[] args) throws Exception {
        Class<?> classType = User2.class;
        
        Object obj1 = classType.newInstance();
        
        //(1) 运行时生成instances
        Class<?>[] parameterTypes = new Class[] {String.class, String.class};
        Constructor<?> construcotr = classType.getConstructor(parameterTypes);
        Object[] initargs = new Object[] {"forrest", "vivian"};
        Object obj2 = construcotr.newInstance(initargs);
        //以上四句可用下面一句代替, 上面的四句是一步步解释了通过constructor获得instance的整个过程, 而下面一句是通用写法.
        //Object obj2 = classType.getConstructor(new Class[] {String.class, String.class}).newInstance(new Object[] {"forrest", "vivian"});
        
        System.out.println(obj1.getClass().getMethod("getUsername", new Class[] {}).invoke(obj1, new Object[] {}));
        System.out.println(obj2.getClass().getMethod("getUsername", new Class[] {}).invoke(obj2, new Object[] {}));
        
        
        //(2) 运行时调用methods
        parameterTypes = new Class[] {String.class};
        Method getUsername_Method = obj1.getClass().getMethod("getUsername", new Class[] {});
        Method getPassword_Method = obj1.getClass().getMethod("getPassword", new Class[] {});
        Method setUsername_Method = obj1.getClass().getMethod("setUsername", parameterTypes);
        Method setPassword_Method = obj1.getClass().getMethod("setPassword", parameterTypes);
        
        Object[] arg1 = new Object[] {"土豆"};
        Object[] arg2 = new Object[] {"红薯"};
        setUsername_Method.invoke(obj1, arg1);
        setPassword_Method.invoke(obj1, arg2);
        Object usernameObj = getUsername_Method.invoke(obj1, new Object[] {});
        Object passwordObj = getPassword_Method.invoke(obj1, new Object[] {});
        
        System.out.println(usernameObj);
        System.out.println(passwordObj);
        
        
        //(3) 运行时变更fields内容
        Field email = classType.getDeclaredField("email");
        Field address = classType.getDeclaredField("address");
        
        email.set(obj1, "牛奶"); //这里要求属性不可以是private类型(如果是调用包外类的属性, 不可以是friendly类型, 如果..不可以是protected类型).
        address.set(obj1, "奶牛");
        
        Object emailObj = email.get(obj1);
        Object addressObj = address.get(obj1);
        
        System.out.println(emailObj);
        System.out.println(addressObj);
        
    }
}

class User2 {
    private String username;
    private String password;
    
    public String email;
    public String address;
    
    public User2(){}
    public User2(String username, String password) {
        this.setUsername(username);
        this.setPassword(password);
    }
    public String getUsername() {
        return username;
    }
    public void setUsername(String username) {
        this.username = username;
    }
    public String getPassword() {
        return password;
    }
    public void setPassword(String password) {
        this.password = password;
    }
    
}
(3)invoke()方法

java.lang.reflect.Method类有如下invoke()方法:public Object invoke(Object obj, Object... args)

Parameters: obj - the object which the underlying method is invoked from (方法所属的对象);args - the arguments used for the method call (方法的参数列表)

Returns: the result of dispatching the method represented by this object on obj with parameters args (方法的返回对象, 如方法为void则返回null, 如方法为int等八种基本类型则返回其对应的包装类)

Method类的invoke(Object obj,Object args[])方法接收的参数必须为对象,如果参数为基本类型数据,必须转换为相应的包装类型的对象。invoke()方法的返回值总是对象,如果实际被调用的方法的返回类型是基本类型数据,那么invoke()方法会把它转换为相应的包装类型的对象,再将其返回。

java.lang.reflect.InvocationHandler接口有如下invoke()方法:Object invoke(Object proxy, Method method, Object[] args) throws Throwable

Processes a method invocation on a proxy instance and returns the result. This method will be invoked on an invocation handler when a method is invoked on a proxy instance that it is associated with.

Parameters: proxy - the proxy instance that the method was invoked on;method - the Method instance corresponding to the interface method invoked on the proxy instance. The declaring class of the Method object will be the interface that the method was declared in, which may be a superinterface of the proxy interface that the proxy class inherits the method through.;args - an array of objects containing the values of the arguments passed in the method invocation on the proxy instance, or null if interface method takes no arguments. Arguments of primitive types are wrapped in instances of the appropriate primitive wrapper class, such as java.lang.Integer or java.lang.Boolean.

Returns: the value to return from the method invocation on the proxy instance. If the declared return type of the interface method is a primitive type, then the value returned by this method must be an instance of the corresponding primitive wrapper class; otherwise, it must be a type assignable to the declared return type. If the value returned by this method is null and the interface method's return type is primitive, then a NullPointerException will be thrown by the method invocation on the proxy instance. If the value returned by this method is otherwise not compatible with the interface method's declared return type as described above, a ClassCastException will be thrown by the method invocation on the proxy instance.

4.如何获得一个Class实例

Class class十分特殊。它和一般classes一样继承自Object,其实体用以表达Java程序运行时的classes和interfaces,也用来表达enum、array、primitive Java types(boolean, byte, char, short, int, long, float, double)以及关键词void。当一个class被加载,或当加载器(class loader)的defineClass()被JVM调用,JVM 便自动产生一个Class object。Class是Reflection起源。针对任何您想探勘的class,唯有先为它产生一个Class object,接下来才能经由后者唤起为数十多个的Reflection APIs.

得到一个对象的类的实例的方法:

(1)java.lang.Object类的getClass():返回一个对象所对应的Class类的实例,每个class都重载了此方法;还有一个Class.getSuperclass()。

(2)static方法, Class.forName():最常被使用,参数为类的全称(即包+类名)。

(3).class语法:例如,String.class、java.lang.Thread.class、Main.InnerClass.class、int.class、int[].class.

(4)primitive wrapper classes的.TYPE语法:例如,Boolean.TYPE、Integer.TYPE等8中包装类、再加一个Void.TYPE;实际上,凡是可以用.TYPE获得Class对象的类同样也可以通过.class获得Class的对象,这里我们只是提供了另外一种选择。


本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/ForWayfarer/archive/2008/09/24/2970438.aspx

Java反射 Java的反射(reflection)机制是指在程序的运行状态中,借助取得任何类的内部信息,可以动态地构造任意一个类的对象,并能直接操作任意对象的属性和方法。这种动态获取程序信息以及动态调用对象的功能称为Java语言的反射机制。反射被视为动态语言的关键。反射主要用到java.lang.Class类和包下的一些类,是 Java 反射机制的核心包,提供了操作类及其成员(字段、方法、构造函数等)的类和接口。表示类的对象。提供了获取类的字段、方法、构造函数等方法。 阅读详情

相关推荐

反射一、反射的基本概念

Java程序在编写完成之后,为了能够运行,首先会被编译为class文件。然后,在Java程序的运行过程当中,每当需要一个新的类,就需要将其对应的class文件加载到JVM虚拟机当中。加载class文件的叫作ClassLoader。 JDK具有多个层次的ClassLoader,最根上的那个叫作BootStrap ClassLoader,负责加载JDK中最核心的类。BootStrap ClassLo...

sun_lm的博客 2672

Java 反射

反射(reflection)是 Java 中的一项特性,它允许程序在运行时查询和操作类的信息。即,在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能调用它的任意方法和属性。获取到方法和属性后,就可以对其进行修改。这种动态获取信息以及动态调用对象方法的功能也就是Java的反射机制

2301_76161469的博客 8668

反射和负反射的含义:

​正反射和负反射的含义: 前两节我们讨论反射的过程中,一直使用电压数值来计算反射量的大小。使用电压数值来计算理想方波信号(上升时间为0)的上升沿引起的反射现象的确很方便,尽管在数值上是正确的,但是这种方式有可能会造成理解上的误区。问题的关键在于:使用数值是否合理?该如何处理数值? 接下来讨论一个很有趣的问题:理想方波下降沿的反射。如果传输线末端开路,驱动器输出阻抗小于传输线的特征阻抗,末端波形会是什么样的?下降沿后信号电平为0V,信号到达末端,由于末端开路,反射系数为1。如果使用电压数值计算,根据反射

2401_87854160的博客 906

UE4-(反射)平面反射

一、创建 注意:平面反射拖拽到场景后,会创建一大块平面,这个平面是临时创建的,当程序运行后,我们不会看到这个平面。 平面反射会捕获反射信息,只能用于平面反射效果,所以只适用于平整的对象,例如镜子,水池水面、窗户玻璃。任何尺寸较小表面平整的对象,都可以用平面反射覆盖。 二、属性 1.平面反射既可以实时渲染,也可以一次性捕获(属性面板中设置) 平面反射使用实时渲染,性能开销非常大,因为平面反射实际上将从反射方向再次对关卡进行渲染。所以要比屏幕空间反射更加精确。 对比: 左侧屏幕空间反射..

Stone的博客 1万+

java反射&python反射

作为一只主学java,次学python的猿,反射的梗,怎能不知道 一、反射是什么: 维基百科上给出的定义:在计算机科学中,反射是指计算机程序在运行时(Run time)可以访问、检测和修改它本身状态或行为的一种能力。用比喻来说,反射就是程序在运行的时候能够“观察”并且修改自己的行为。 以我浅薄的编程思想理解的反射反射可以让我们在不打开程序文件的情况下,清楚的知道该程序的内部结构...

远处 1463

如何创建反射以及通过反射拿到值

本文介绍了创建反射的三种方式,主要了解如何通过反射获取对象中的构造器、成员变量和成员方法。三种创建反射的方式熟练掌握,学会拿到对象的构造器、成员变量和成员方法,拿到这三个的方式差不多,方法不一样但都有规律,很容易记住。

qq_53118426的博客 1280

java反射三种方法_反射及暴力反射

作者:逯小逯出自:SegmentFault 思否原文:segmentfault.com/a/1190000037432381反射一、概述(1)反射的定位是很重要的,JVM和底层框架都离不开反射(2)反射的原理是拿到你的class文件里的数据,进行数据的操作(CURD)(3)反射提供了丰富的方法,来操作类里的各种数据(属性/方法/构造)(4)REflection(反射)是Java程序开发语言的特征之...

weixin_39586353的博客 2377

关于反射探头的实时反射

反射探头实现镜面反射 之前看到过一个日本人写的文章,关于如何使用Unity的反射探头来实现地板的镜面反射效果。 文章地址:http://nn-hokuson.hatenablog.com/entry/2016/10/17/202135。 核心代码很短,主要是根据下图所示实时更新反射探头的位置: 先贴一下位置计算的代码: using System.Collections; using Syste...

weixin_45979158的博客 1034

平面反射

GitHub项目地址 平面反射的实现步骤: 1、抓取屏幕图像——渲染纹理RenderTexture+额外摄像机 2、反射矩阵(ReflectMatrix)——获得反射的屏幕图像 3、斜裁剪矩阵(ObliqueMatrix)——裁剪掉反射平面以下的部分 4、高斯模糊——模糊反射的倒影 5、将反射纹理渲染到地面 1、抓取屏幕图像 之前的文章已经提过了,抓取屏幕图像有两种方法: 1、GrabPass 2、渲染纹理RenderTexture+额外摄像机 这里需要使用第二种方法: private Camera ma.

leo_hui_leo的博客 2062

反射 及 Reflections反射框架

一、类加载过程 要知道反射机制,还需要理解类的加载过程。总的来说,类加载的五个过程:加载、验证、准备、解析、初始化。 除了加载阶段,用户可以通过自定义的类加载器参与,其他阶段都完全由虚拟机主导和控制。 (1)装载 加载指的是把class字节码文件从各个来源通过类加载器装载入内存中。有两处需要说明一下: 字节码来源。一般的加载来源包括从本地路径下编译生成的.class文件,从jar包中的.cla...

1771

反射和镜面反射

学习了镜面反射和漫反射以后,不少同学总是误认为看到的物体是光亮的,就是发生了镜面反射;看到的物体是昏暗的,一定是发生了漫反射。造成错误的原因是没有完全理解镜面反射和漫反射的概念。为了帮助同学们理解,我们先通过下面的实验来认识镜面反射和漫反射。   实验让一束太阳光从室外斜射到平面镜上,反射光照在墙壁上,形成一个明亮的光斑;然后将一张白纸放在平面镜上,仍让这束太阳光斜射到白纸上,会发现墙壁上的光斑不见了,而教室里各个位置的同学都能看到这张纸变亮了。   问题为什么同样一束太阳光射到平面镜和白纸上,产生的现

jinking01的专栏 7994

什么是反射,为什么要用反射反射的知识讲解

面试难免让人焦虑不安。经历过的人都懂的。但是如果你提前预测面试官要问你的问题并想出得体的回答方式,就会容易很多。此外,都说“面试造火箭,工作拧螺丝”,那对于准备面试的朋友,你只需懂一个字:刷!给我刷刷刷刷,使劲儿刷刷刷刷刷!今天既是来谈面试的,那就必须得来整点面试真题,这不花了我整28天,做了份“Java一线大厂高岗面试题解析合集:JAVA基础-中级-高级面试+SSM框架+分布式+性能调优+微服务+并发编程+网络+设计模式+数据结构与算法等”

2401_85358130的博客 1081

什么是反射反射用途,spring哪些地方用到了反射,我们项目中哪些地方用到了反射

在Java中,反射(Reflection)是一种强大的工具,它允许程序在运行时类、接口、构造器、方法和字段等。反射是Java语言的一个重要特性,它为开发人员提供了许多灵活性,尤其是在构建框架和库时非常有用。

zhzjn的博客 1819

C++反射

本文介绍了C++中的反射机制及其实现方式。反射是程序在运行时获取并操作自身信息的能力,C++标准虽未原生支持,但可通过技术手段模拟实现。文章首先通过Python示例展示了反射的基本用法(获取属性/方法、动态创建对象),然后阐述了反射的应用场景(动态类型处理、解耦、序列化等)。接着将反射分为动态反射(运行时)和静态反射(编译时),并对比了两者的特性差异。最后详细介绍了动态反射的实现思路,包括用于存储类型信息的FieldInfo、MethodInfo、TypeInfo类设计,以及全局类型注册器TypeRegis

梦的灰色边沿... 1319

光线反射设置&反射探针

光线反射设置&反射探针

zaizai1007的博客 3937

Java-反射以及反射调用类中方法

认识反射 反射是对象的反射处理操作。 先来看看“正”操作。 在默认情况下,必须要先导入一个包,而后才能产生类的实例化对象。 如下就是一个正操作。 import java.util.Date;//导入的包 public class Test{ public static void main(String[] args){ Date date = new Date();//产...

阿巴卡的博客 4773
上一篇: 代理
下一篇: HQL语法结构
J2EE_dev
博客等级 码龄18年 237粉丝 94原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值