Java 基础 反射机制

Java 反射机制

--------------- 

认识Class类

在正常情况下,必须知道一个类的完整路径之后才可以实例化对象,但是在JAVA中也允许通过一个对象来找到其所在的类的信息,那么这实际上就是 Class类的功能。

package org.cwt.demo15.getclassdemo ;
class X{
};
public class GetClassDemo01{
       publicstatic void main(String args[]){
              Xx = new X() ;     // 实例化X类的对象
              System.out.println(x.getClass().getName());       // 得到对象所在的类
       }
};


此时,所有的操作都是反着来的。

Object类的支持

在Object类中定义了以下的方法,此方法将被所有子类继承:

       publicfinal Class getClass()

       以上的方法返回值的类型是一个“Class”类,实际上此类是JAVA反射的源头。可以通过对象反射求出类的名称。

Class类

Class本身表示一个类的本身,通过Class可以完整的得到一个类中的完整结构,包括此类中的方法定义,属性定义等。

实例化Class类对象

       第一种:通过forName()方法

       第二种:类.Class

       第三种:对象.getClass()

实例:

package org.cwt.demo15.getclassdemo ;
class X{
};
public class GetClassDemo02{
       publicstatic void main(String args[]){
              Class<?>c1 = null ;              // 指定泛型
              Class<?>c2 = null ;              // 指定泛型
              Class<?>c3 = null ;              // 指定泛型
              try{
                     //以下的操作形式是在开发中最常用的一种形式
                     c1= Class.forName("org.cwt.demo15.getclassdemo.X") ;
              }catch(ClassNotFoundExceptione){
                     e.printStackTrace();
              }
              c2= new X().getClass() ;             // 通过Object类中的方法实例化
              c3= X.class ;  // 通过类.class实例化
              System.out.println("类名称:" + c1.getName())  ;    // 得到类的名称
              System.out.println("类名称:" + c2.getName())  ;    // 得到类的名称
              System.out.println("类名称:" + c3.getName())  ;    // 得到类的名称
       }
};

Class类的使用

Class主要是反射的源头,不光可以取得对象所在的类的信息,也可以直接通过Class类的方法进行对象的实例化操作。

实例:

package org.cwt.demo15.instancedemo ;
class Person{
       privateString name ;     // name属性
       privateint age ;             // age属性
       publicvoid setName(String name){
              this.name= name ;
       }
       publicvoid setAge(int age){
              this.age= age ;
       }
       publicString getName(){
              returnthis.name ;
       }
       publicint getAge(){
              returnthis.age ;
       }
       publicString toString(){       // 覆写toString()方法
              return"姓名:" +this.name + ",年龄:" + this.age  ;
       }
};
public class InstanceDemo01{
       publicstatic void main(String args[]){
              Class<?>c = null ;        // 声明Class对象
              try{
                     c= Class.forName("org.cwt.demo15.instancedemo.Person") ;
              }catch(ClassNotFoundExceptione){
                     e.printStackTrace();
              }
              Personper = null ;  // 声明Person对象
              try{
                     per= (Person)c.newInstance() ;    // 实例化对象
              }catch(Exceptione){
                     e.printStackTrace();
              }
              per.setName("曹文涛") ;              // 设置姓名
              per.setAge(26);                          // 设置年龄
              System.out.println(per);       // 内容输出,调用toString()
       }
};

通过以上的代码,可以发现,即使不使用关键字new对象也可以进行实例化操作。

但是在使用以上操作的时候,在操作类中必须存在无参构造方法,否则无法实例化。

实例:

package org.cwt.demo15.instancedemo ;
class Person{
       privateString name ;     // name属性
       privateint age ;             // age属性
       publicPerson(String name,int age){
              this.setName(name);
              this.setAge(age);
       }
       publicvoid setName(String name){
              this.name= name ;
       }
       publicvoid setAge(int age){
              this.age= age ;
       }
       publicString getName(){
              returnthis.name ;
       }
       publicint getAge(){
              returnthis.age ;
       }
       publicString toString(){       // 覆写toString()方法
              return"姓名:" +this.name + ",年龄:" + this.age  ;
       }
};
public class InstanceDemo02{
       publicstatic void main(String args[]){
              Class<?>c = null ;        // 声明Class对象
              try{
                     c= Class.forName("org.cwt.demo15.instancedemo.Person") ;
              }catch(ClassNotFoundExceptione){
                     e.printStackTrace();
              }
              Personper = null ;  // 声明Person对象
              try{
                     per= (Person)c.newInstance() ;    // 实例化对象
              }catch(Exceptione){
                     e.printStackTrace();
              }
              per.setName("曹文涛") ;              // 设置姓名
              per.setAge(26);                          // 设置年龄
              System.out.println(per);       // 内容输出,调用toString()
       }
};

以上程序会出现错误。

所以发现,使用以上的方式实际上还是需要类中的构造方法的支持。

实例:调用有参构造方法完成实例化

package org.cwt.demo15.instancedemo ;
import java.lang.reflect.Constructor ;   // 导入反射机制包
class Person{
       privateString name ;     // name属性
       privateint age ;             // age属性
       publicPerson(String name,int age){
              this.setName(name);
              this.setAge(age);
       }
       publicvoid setName(String name){
              this.name= name ;
       }
       publicvoid setAge(int age){
              this.age= age ;
       }
       publicString getName(){
              returnthis.name ;
       }
       publicint getAge(){
              returnthis.age ;
       }
       publicString toString(){       // 覆写toString()方法
              return"姓名:" +this.name + ",年龄:" + this.age  ;
       }
};
public class InstanceDemo03{
       publicstatic void main(String args[]){
              Class<?>c = null ;        // 声明Class对象
              try{
                     c= Class.forName("org.cwt.demo15.instancedemo.Person") ;
              }catch(ClassNotFoundExceptione){
                     e.printStackTrace();
              }
              Personper = null ;  // 声明Person对象
              Constructor<?>cons[] = null ;
              cons= c.getConstructors() ;
              try{
                     per= (Person)cons[0].newInstance("曹文涛",26) ;     // 实例化对象
              }catch(Exceptione){
                     e.printStackTrace();
              }
              System.out.println(per);       // 内容输出,调用toString()
       }
};

反射应用——取得类的结构

定义操作类Person:

package org.cwt.demo15 ;
interface China{     // 定义China接口
       publicstatic final String NATIONAL = "China" ; // 定义全局常量
       publicstatic final String AUTHOR = "曹文涛" ; // 定义全局常量
       publicvoid sayChina() ;        // 无参的,没有返回值的方法
       publicString sayHello(String name,int age) ;      //定义有两个参数的方法,并返回内容
}
public class Person implements China{
       privateString name ;
       privateint age ;
       publicPerson(){     // 无参构造
       }
       publicPerson(String name){
              this.name= name ; // 设置name属性
       }
       publicPerson(String name,int age){
              this(name);
              this.age= age ;
       }
       publicvoid sayChina(){ // 覆写方法
              System.out.println("作者:" + AUTHOR + ",国籍:" + NATIONAL) ;
       }
       publicString sayHello(String name,int age){
              returnname + ",你好!我今年:"+ age + "岁了!" ;
       }
       publicvoid setName(String name){
              this.name= name ;
       }
       publicvoid setAge(int age){
              this.age= age ;
       }
       publicString getName(){
              returnthis.name ;
       }
       publicint getAge(){
              returnthis.age ;
       }
};

实例:取得类所实现的全部接口

package org.cwt.demo15.classinfodemo ;
public class GetInterfaceDemo{
       publicstatic void main(String args[]){
              Class<?>c1 = null ;              // 声明Class对象
              try{
                     c1= Class.forName("org.cwt.demo15.Person") ; // 实例化对象
              }catch(ClassNotFoundExceptione){
                     e.printStackTrace();
              }
              Class<?>c[] = c1.getInterfaces() ; // 以数组形式返回实现的全部接口
              for(inti=0;i<c.length;i++){
                     System.out.println("实现的接口名称:" + c[i].getName()) ;    // 输出接口名称
              }
       }
};

实例:取得类所继承的父类

package org.cwt.demo15.classinfodemo ;
public class GetSuperClassDemo{
       publicstatic void main(String args[]){
              Class<?>c1 = null ;              // 声明Class对象
              try{
                     c1= Class.forName("org.cwt.demo15.Person") ; // 实例化对象
              }catch(ClassNotFoundExceptione){
                     e.printStackTrace();
              }
              Class<?>c2 = c1.getSuperclass() ;       // 取得父类
              System.out.println("父类名称:" + c2.getName()) ;
       }
};

实例:取得类中的全部构造方法

package org.cwt.demo15.classinfodemo ;
import java.lang.reflect.Constructor ;   // 导入构造方法的包
import java.lang.reflect.Modifier ;       // 导入构造方法的包
public class GetConstructorDemo03{
       publicstatic void main(String args[]){
              Class<?>c1 = null ;              // 声明Class对象
              try{
                     c1= Class.forName("org.cwt.demo15.Person") ; // 实例化对象
              }catch(ClassNotFoundExceptione){
                     e.printStackTrace();
              }
              Constructor<?>con[] = c1.getConstructors() ;     // 取得一个类中的全部构造
              for(inti=0;i<con.length;i++){
                     Class<?>p[] = con[i].getParameterTypes() ;        //得到构造方法中的全部参数
                     System.out.print("构造方法:" ) ;       // 输出构造,直接打印
                     intmo = con[i].getModifiers() ; // 得到所要的访问权限
                     System.out.print(Modifier.toString(mo)+ " ") ;  // 得到修饰符
                     System.out.print(con[i].getName());    // 取得构造方法的名字
                     System.out.print("(");
                     for(intj=0;j<p.length;j++){
                            System.out.print(p[j].getName()+ " arg" + i) ;
                            if(j<p.length-1){
                                   //判断此是否是最后一个参数
                                   System.out.print(",");    // 输出“,”
                            }
                     }
                     System.out.println("){}");
              }
       }
};

实例:取得类中的方法

package org.cwt.demo15.classinfodemo ;
import java.lang.reflect.Method ;  // 导入构造方法的包
import java.lang.reflect.Modifier ;       // 导入构造方法的包
public class GetMethodDemo{
       publicstatic void main(String args[]){
              Class<?>c1 = null ;              // 声明Class对象
              try{
                     c1= Class.forName("org.cwt.demo15.Person") ; // 实例化对象
              }catch(ClassNotFoundExceptione){
                     e.printStackTrace();
              }
              Methodm[] = c1.getMethods() ;   // 取得全部方法
              for(inti=0;i<m.length;i++){
                     Class<?>r = m[i].getReturnType() ;     // 得到返回值类型
                     Class<?>p[] = m[i].getParameterTypes() ;   // 取得全部参数的类型
                     intxx = m[i].getModifiers() ;       // 得到修饰符
                     System.out.print(Modifier.toString(xx)+ " ") ;   // 输出修饰符
                     System.out.print(r+ " ") ;
                     System.out.print(m[i].getName());
                     System.out.print("(");
                     for(intj=0;j<p.length;j++){
                            System.out.print(p[j].getName()+ " " + "arg" + j) ;
                            if(j<p.length-1){
                                   System.out.print(",");
                            }
                     }
                     Class<?>ex[] = m[i].getExceptionTypes() ; // 取出异常
                     if(ex.length>0){
                            System.out.print(")throws ") ;
                     }else{
                            System.out.print(")");
                     }
                     for(intj=0;j<ex.length;j++){
                            System.out.print(ex[j].getName());
                            if(j<p.length-1){
                                   System.out.print(",");
                            }
                     }
                     System.out.println();
              }
       }
};

实例:取得类中的属性

package org.cwt.demo15.classinfodemo ;
import java.lang.reflect.Field ;      // 导入构造方法的包
import java.lang.reflect.Modifier ;       // 导入构造方法的包
public class GetFieldDemo{
       publicstatic void main(String args[]){
              Class<?>c1 = null ;              // 声明Class对象
              try{
                     c1= Class.forName("org.cwt.demo15.Person") ; // 实例化对象
              }catch(ClassNotFoundExceptione){
                     e.printStackTrace();
              }
              {     // 本类属性
                     Fieldf[] = c1.getDeclaredFields() ;      // 取得本类中的属性
                     for(inti=0;i<f.length;i++){
                            Class<?>r = f[i].getType() ;  // 得到属性类型
                            intmo = f[i].getModifiers() ; // 得到修饰符的数字
                            Stringpriv = Modifier.toString(mo) ; // 还原修饰符
                            System.out.print("本类属性:") ;
                            System.out.print(priv+ " ") ;      
                            System.out.print(r.getName()+ " ") ;   // 得到属性类型
                            System.out.print(f[i].getName());       // 输出属性名称
                            System.out.println(";") ;
                     }
              }
              {     // 公共属性
                     Fieldf[] = c1.getFields() ;     // 取得本类中的公共属性
                     for(inti=0;i<f.length;i++){
                            Class<?>r = f[i].getType() ;  // 得到属性类型
                            intmo = f[i].getModifiers() ; // 得到修饰符的数字
                            Stringpriv = Modifier.toString(mo) ; // 还原修饰符
                            System.out.print("公共属性:") ;
                            System.out.print(priv+ " ") ;      
                            System.out.print(r.getName()+ " ") ;   // 得到属性类型
                            System.out.print(f[i].getName());       // 输出属性名称
                            System.out.println(";") ;
                     }
              }
       }
};

Java反射机制的深入研究

通过反射调用类中的方法:在正常情况下一个类的反射功能产生之后,就可以直接调用类中的方法了,如果要想调用的话,则必须知道方法名称是什么,之后通过Class类中的方法调用。

定义操作类:

package org.cwt.demo15 ;
interface China{     // 定义China接口
       publicstatic final String NATIONAL = "China" ; // 定义全局常量
       publicstatic final String AUTHOR = "曹文涛" ; // 定义全局常量
       publicvoid sayChina() ;        // 无参的,没有返回值的方法
       publicString sayHello(String name,int age) ;      //定义有两个参数的方法,并返回内容
}
public class Person implements China{
       privateString name ;
       privateint age ;
       publicPerson(){     // 无参构造
       }
       publicPerson(String name){
              this.name= name ; // 设置name属性
       }
       publicPerson(String name,int age){
              this(name);
              this.age= age ;
       }
       publicvoid sayChina(){ // 覆写方法
              System.out.println("作者:" + AUTHOR + ",国籍:" + NATIONAL) ;
       }
       publicString sayHello(String name,int age){
              returnname + ",你好!我今年:"+ age + "岁了!" ;
       }
       publicvoid setName(String name){
              this.name= name ;
       }
       publicvoid setAge(int age){
              this.age= age ;
       }
       publicString getName(){
              returnthis.name ;
       }
       publicint getAge(){
              returnthis.age ;
       }
};


实例操作:

package org.cwt.demo15.invokedemo ;
import java.lang.reflect.Method ;
public class InvokeSayHelloDemo{
       publicstatic void main(String args[]){
              Class<?>c1 = null ;
              try{
                     c1= Class.forName("org.cwt.demo15.Person") ; // 实例化Class对象
              }catch(Exceptione){}
              try{
                     Method  met =c1.getMethod("sayHello",String.class,int.class) ;      // 找到sayChina()方法
                     Stringrv = null ;
                     rv= (String)met.invoke(c1.newInstance(),"曹文涛",26) ;   // 调用方法
                     System.out.println(rv);
              }catch(Exceptione){
                     e.printStackTrace();
              }
       }
};

通过反射调用setter及getter

setter及getter方法是一个标准的属性的访问方法,如果一个类的属性被封装,则必须通过setter及getter方法设置和取得,实际上此方法的操作之所以这样规定,主要原因就是由于反射机制可以给予支持。

实例:通过反射调用setter及getter方法

package org.cwt.demo15.invokedemo ;
import java.lang.reflect.Method ;
public class InvokeSetGetDemo{
       publicstatic void main(String args[]){
              Class<?>c1 = null ;
              Objectobj = null ;
              try{
                     c1= Class.forName("org.cwt.demo15.Person") ; // 实例化Class对象
              }catch(Exceptione){}
              try{
                     obj= c1.newInstance() ;
              }catch(Exceptione){}
              setter(obj,"name","曹文涛",String.class) ;   // 调用setter方法
              setter(obj,"age",26,int.class);       // 调用setter方法
              System.out.print("姓名:") ;
              getter(obj,"name");
              System.out.print("年龄:") ;
              getter(obj,"age");
       }
       /**
              Objectobj:要操作的对象
              Stringatt:要操作的属性
              Objectvalue:要设置的属性内容
              Class<?>type:要设置的属性类型
       */
       publicstatic void setter(Object obj,String att,Object value,Class<?> type){
              try{
                     Methodmet = obj.getClass().getMethod("set"+initStr(att),type) ;      // 得到setter方法
                     met.invoke(obj,value);  // 设置setter的内容
              }catch(Exceptione){
                     e.printStackTrace();
              }
       }
       publicstatic void getter(Object obj,String att){
              try{
                     Methodmet = obj.getClass().getMethod("get"+initStr(att)) ;      // 得到setter方法
                     System.out.println(met.invoke(obj));   // 调用getter取得内容
              }catch(Exceptione){
                     e.printStackTrace();
              }
       }
       publicstatic String initStr(String old){ // 将单词的首字母大写
              Stringstr = old.substring(0,1).toUpperCase() + old.substring(1) ;
              returnstr ;
       }
};

通过反射调用属性

如果要操作一个类中的属性,则也可以通过Filed完成:

package org.cwt.demo15.invokedemo ;
import java.lang.reflect.Field ;
public class InvokeFieldDemo{
       publicstatic void main(String args[]) throws Exception{
              Class<?>c1 = null ;
              Objectobj = null ;
              c1= Class.forName("org.cwt.demo15.Person") ; // 实例化Class对象
              obj= c1.newInstance() ;
              FieldnameField = null ;
              FieldageField = null ;
              nameField= c1.getDeclaredField("name") ; //取得name属性
              ageField= c1.getDeclaredField("age") ;       //取得name属性
              nameField.setAccessible(true);     // 此属性对外部可见
              ageField.setAccessible(true); // 此属性对外部可见
              nameField.set(obj,"曹文涛") ;      // 设置name属性内容
              ageField.set(obj,26);                   // 设置age属性内容
              System.out.println("姓名:" + nameField.get(obj)) ;
              System.out.println("年龄:" + ageField.get(obj)) ;
       }
};

通过反射操作数组

实例:

package org.cwt.demo15.invokedemo ;
import java.lang.reflect.Array ;
public class ClassArrayDemo{
       publicstatic void main(String args[]) throws Exception{
              inttemp[] = {1,2,3} ;// 声明一整型数组
              Class<?>c = temp.getClass().getComponentType() ;   //取得数组的Class对象
              System.out.println("类型:" + c.getName()) ;    // 取得数组类型名称
              System.out.println("长度:" + Array.getLength(temp)) ;
              System.out.println("第一个内容:" + Array.get(temp,0)) ;
              Array.set(temp,0,6);
              System.out.println("第一个内容:" + Array.get(temp,0)) ;
       }
};

实例:通过反射实现对数组中元素的操作

package org.cwt.demo15.invokedemo ;
import java.lang.reflect.Array ;
public class ChangeArrayDemo{
       publicstatic void main(String args[]) throws Exception{
              inttemp[] = {1,2,3} ;// 声明一整型数组
              intnewTemp[] = (int []) arrayInc(temp,5) ;  //重新开辟空间5
              print(newTemp);
              System.out.println("\n-------------------------");
              Stringt[] = {"cwt","mldn","mldnjava"} ;
              Stringnt[] = (String [])arrayInc(t,8) ;
              print(nt);
       }
       publicstatic Object arrayInc(Object obj,int len){
              Class<?>c = obj.getClass() ;
              Class<?>arr = c.getComponentType() ;       // 得到数组的
              ObjectnewO = Array.newInstance(arr,len) ; // 开辟新的大小
              intco = Array.getLength(obj) ;
              System.arraycopy(obj,0,newO,0,co);   // 拷贝内容
              returnnewO ;
       }
       publicstatic void print(Object obj){     // 数组输出
              Class<?>c = obj.getClass() ;
              if(!c.isArray()){     // 判断是否是数组
                     return;
              }
              Class<?>arr = c.getComponentType() ;
              System.out.println(arr.getName()+"数组的长度是:" +Array.getLength(obj)) ;     // 输出数组信息
              for(inti=0;i<Array.getLength(obj);i++){
                     System.out.print(Array.get(obj,i)+ "、") ;  // 通过Array输出
              }
       }
};

动态代理

代理设计:一个操作的接口有两个子类,其中一个是真实操作的实现类,另外一个是代理类,代理类实现类要完成比真实操作类更多的内容。

实例:通过Proxy类、类加载器完成动态代理

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy ;
import java.lang.reflect.Method ;
interface Subject{
       publicString say(String name,int age) ;       //定义抽象方法say
}
class RealSubject implements Subject{ // 实现接口
       publicString say(String name,int age){
              return"姓名:" +name + ",年龄:" +age ;
       }
};
class MyInvocationHandler implementsInvocationHandler{
       privateObject obj ;
       publicObject bind(Object obj){
              this.obj= obj ;       // 真实主题类
              returnProxy.newProxyInstance(obj.getClass().getClassLoader(),obj.getClass().getInterfaces(),this);
       }
       publicObject invoke(Object proxy,Method method,Object[] args) throws Throwable{
              Objecttemp = method.invoke(this.obj,args) ;      //调用方法
              returntemp ;
       }
};
public class DynaProxyDemo{
       publicstatic void main(String args[]){
              Subjectsub = (Subject)new MyInvocationHandler().bind(new RealSubject()) ;
              Stringinfo = sub.say("曹文涛",26) ;
              System.out.println(info);
       }
};

工厂设计模式

实例:简单的工厂设计

package org.cwt.demo15.factorydemo01 ;
interface Fruit{
       publicvoid eat() ;   // 吃水果
}
class Apple implements Fruit{
       publicvoid eat(){                 // 覆写eat()方法
              System.out.println("**吃苹果");
       }
};
class Orange implements Fruit{
       publicvoid eat(){
              System.out.println("**吃橘子") ;
       }
};
class Factory{
       publicstatic Fruit getInstance(String className){
              Fruitfruit = null ;
              try{
                     fruit= (Fruit)Class.forName(className).newInstance() ;
              }catch(Exceptione){
                     e.printStackTrace();
              }
              returnfruit ;
       }
};
public class FactoryDemo01{
       publicstatic void main(String args[]){
              Fruitf = Factory.getInstance("org.cwt.demo15.factorydemo01.Apple") ;
              if(f!=null){
                     f.eat();
              }
       }
};

实例:通过反射完成工厂设计

package org.cwt.demo15.factorydemo02 ;
import java.util.Properties ;
import java.io.File ;
import java.io.FileOutputStream ;
import java.io.FileInputStream ;
interface Fruit{
       publicvoid eat() ;   // 吃水果
}
class Apple implements Fruit{
       publicvoid eat(){                 // 覆写eat()方法
              System.out.println("**吃苹果");
       }
};
class Orange implements Fruit{
       publicvoid eat(){
              System.out.println("**吃橘子") ;
       }
};
class Init{
       publicstatic Properties getPro(){
              Propertiespro = new Properties() ;
              Filef = new File("d:\\fruit.properties") ;      // 找到属性文件
              try{
                     if(f.exists()){  // 文件存在
                            pro.load(newFileInputStream(f)) ;      // 读取属性
                     }else{
                            pro.setProperty("apple","org.cwt.demo15.factorydemo02.Apple");
                            pro.setProperty("orange","org.cwt.demo15.factorydemo02.Orange");
                            pro.store(newFileOutputStream(f),"FRUIT CLASS") ;
                     }
              }catch(Exceptione){}
              returnpro ;
       }
};
class Factory{
       publicstatic Fruit getInstance(String className){
              Fruitfruit = null ;
              try{
                     fruit= (Fruit)Class.forName(className).newInstance() ;
              }catch(Exceptione){
                     e.printStackTrace();
              }
              returnfruit ;
       }
};
public class FactoryDemo02{
       publicstatic void main(String args[]){
              Propertiespro = Init.getPro() ;
              Fruitf = Factory.getInstance(pro.getProperty("apple")) ;
              if(f!=null){
                     f.eat();
              }
       }
};

其中要建立配置文件:

fruit.properties:

apple = org.cwt.demo15.factorydemo02.Apple

orange = org.cwt.demo15.factorydemo02.Orange

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值