反射相關(guān)

學(xué)習(xí)目的

  1. 了解反射的概念與作用意義
  2. 掌握java提供的反射機(jī)制使用到的包和類(lèi)
  3. 了解反射機(jī)制的實(shí)現(xiàn)原理與Spring框架的結(jié)合

一.反射

  1. 概念
    在日常開(kāi)發(fā)中,通常的開(kāi)發(fā)步驟是:程序員建立項(xiàng)目 --> 編寫(xiě)源代碼 --> 編譯得到.class字節(jié)碼文件 --> java虛擬機(jī)JVM加載字節(jié)碼文件 --> 執(zhí)行運(yùn)行。
    而反射的步驟則是:通過(guò)編譯好的字節(jié)碼文件 --> 創(chuàng)建字節(jié)碼對(duì)象 --> 對(duì)編譯后的文件進(jìn)行操作,操作包括創(chuàng)建實(shí)例對(duì)象、讀取或修改對(duì)象屬性、獲取和執(zhí)行對(duì)象方法等。
  2. 實(shí)質(zhì)
    反射對(duì)字節(jié)碼文件內(nèi)容的操作都基于"字節(jié)碼對(duì)象",而對(duì)實(shí)例對(duì)象、屬性、方法等也有專(zhuān)屬的反射"類(lèi)"對(duì)象。
  3. 原則
    一切皆對(duì)象。

1.1 java.lang.reflect反射包

  1. 定義
    提供用于獲取類(lèi)和對(duì)象的反射信息(字節(jié)碼信息) 的類(lèi)和接口。
  2. 實(shí)質(zhì)
    提供操作字節(jié)碼文件的"操作對(duì)象"。
  3. 反射常用接口
  • Type:Java中所有類(lèi)型的公共高級(jí)接口
  1. 反射常用類(lèi)
  • Class:所有類(lèi)或接口的"類(lèi)型";
  • Constructor:構(gòu)造器類(lèi);
  • Field:屬性類(lèi);
  • Method:方法類(lèi);
  • Modifier:修飾符類(lèi);
  1. 反射最重要方法
  • Object invoke(Object obj, Object... args):該方法屬于Method類(lèi)中的方法,obj為字節(jié)碼對(duì)象創(chuàng)建出的一個(gè)實(shí)例對(duì)象;使用Method對(duì)象調(diào)用該方法意為 調(diào)用obj對(duì)象的該Method方法,并且方法的參數(shù)為...args。
         // 使用反射機(jī)制來(lái)調(diào)用一個(gè)對(duì)象的方法
         // 創(chuàng)建字節(jié)碼對(duì)象
        Class userClass = Class.forName("com.java.service.User");
        // 通過(guò)字節(jié)碼反射創(chuàng)建實(shí)例對(duì)象
        Object obj = userServiceClass.newInstance();
        // 獲取字節(jié)碼對(duì)象中的Method對(duì)象(實(shí)則為一個(gè)方法),通過(guò)"方法名"和參數(shù)的類(lèi)型(重載根據(jù)參數(shù)列表區(qū)分)
        Method loginMethod = userClass.getDeclaredMethod("login", String.class, String.class);
        //Method loginMethod = userClass.getDeclaredMethod("login", int.class);
        // 調(diào)用方法4要素:Method方法對(duì)象,實(shí)例對(duì)象Obj,參數(shù),返回值
        // 通過(guò)Method對(duì)象.invoke()執(zhí)行obj對(duì)象的Method方法,參數(shù)為...
        Object retValue = loginMethod.invoke(obj, "admin","123123");
        System.out.println(retValue);

1.2 java.lang.reflect.Type接口

  1. 定義
    Type 是Java中所有"類(lèi)型"的公共高級(jí)接口,包括原始類(lèi)型、參數(shù)化類(lèi)型、數(shù)組類(lèi)型、類(lèi)型變量和基本類(lèi)型等。
  2. 實(shí)質(zhì)
    "數(shù)據(jù)類(lèi)型",包括類(lèi)的類(lèi)型、參數(shù)的類(lèi)型、元素的類(lèi)型、返回值的類(lèi)型等等。

1.3 java.lang.Class<T>類(lèi)

  1. 定義
    Class類(lèi)表示Java應(yīng)用程序中的類(lèi)和接口,包括我們自定義的"class類(lèi)" 和 "interface接口"等。Class類(lèi)用于反射指的是字節(jié)碼文件內(nèi)容中代表的"類(lèi)型",如public類(lèi)的字節(jié)碼文件名代表的就是該"類(lèi)",是一個(gè)Class。Class還實(shí)現(xiàn)了Type接口。
  2. 實(shí)質(zhì)
    Class類(lèi)代表所有的"類(lèi)" 和 "接口"。
  3. 特點(diǎn)
    Class沒(méi)有公共構(gòu)造方法(只有一個(gè)private的構(gòu)造 類(lèi)加載器的構(gòu)造器),Class對(duì)象是在加載類(lèi)時(shí)由Java虛擬機(jī)以及 通過(guò)調(diào)用類(lèi)加載器中的defineClass方法自動(dòng)構(gòu)造的。
  4. 常用方法
  • String toString():將該Class對(duì)象轉(zhuǎn)換為字符串,返回的字符串表示形式為 "class" / "interface" + 空格 + 該Class對(duì)象代表的完整類(lèi)名;
  • Class<?> forName(String className):返回 給定字符串名的類(lèi)或接口相關(guān)的 Class字節(jié)碼對(duì)象,采用默認(rèn)的類(lèi)加載器;
  • Class<?> forName(String name, boolean initialize,ClassLoader loader):返回 給定字符串名的類(lèi)或接口相關(guān)的 Class字節(jié)碼對(duì)象,采用指定的類(lèi)加載器,并有可能初始化該字節(jié)碼對(duì)象;
  • T newInstance():創(chuàng)建此Class字節(jié)碼對(duì)象所代表的類(lèi)的一個(gè)新實(shí)例;
  • boolean isInstance(Object obj):判斷obj對(duì)象是否 是該Class字節(jié)碼對(duì)象代表的類(lèi)的一個(gè)實(shí)例;
  • boolean isInterface():判定該Class字節(jié)碼對(duì)象是否代表一個(gè)接口類(lèi)型;
  • boolean isArray():判定該Class字節(jié)碼對(duì)象是否代表一個(gè)數(shù)組類(lèi)型;
  • boolean isPrimitive():判定該Class字節(jié)碼對(duì)象是否代表一個(gè)基本類(lèi)型;
  • boolean isAnnotation():判定該Class字節(jié)碼對(duì)象是否代表一個(gè)注釋類(lèi)型;
  • String getName():返回該Class字節(jié)碼對(duì)象所代表類(lèi)的全(路徑)類(lèi)名;
  • String getSimpleName():返回該Class字節(jié)碼對(duì)象所代表類(lèi)的簡(jiǎn)類(lèi)名;
  • ClassLoader getClassLoader():返回加載該Class字節(jié)碼對(duì)象的類(lèi)加載器;
  • Class<? super T> getSuperclass():返回該Class字節(jié)碼對(duì)象所代表的類(lèi)的父類(lèi)或父接口;
  • Class<?>[] getInterfaces():返回該Class字節(jié)碼對(duì)象所代表的類(lèi)所實(shí)現(xiàn)的所有接口,使用數(shù)組存儲(chǔ);
  • int getModifiers():返回該Class字節(jié)碼對(duì)象所代表的類(lèi)的修飾符,返回的是表示該類(lèi)修飾符的int數(shù)(需要配合Modifier類(lèi)的toString()方法將其轉(zhuǎn)換為字符串);
  • Class<?> getDeclaringClass():若該Class字節(jié)碼對(duì)象是另一個(gè)類(lèi)或接口的成員,返回該Class字節(jié)碼對(duì)象的聲明類(lèi)或接口;
  • boolean isAnonymousClass():判斷該Class字節(jié)碼對(duì)象底層是否是內(nèi)部類(lèi);
  • boolean isLocalClass():判斷該Class字節(jié)碼對(duì)象底層是否是native本地類(lèi);
  • Field getField(String name):返回一個(gè)Field對(duì)象,代表該Class字節(jié)碼對(duì)象所代表的類(lèi)或接口的"公共"成員屬性;
  • Method getMethod(String name, Class<?>... parameterTypes):返回一個(gè)Method對(duì)象,根據(jù)指定的方法名和參數(shù)類(lèi)型查找返回;
  • Constructor<T> getConstructor(Class<?>... parameterTypes):返回一個(gè)Constructor對(duì)象,根據(jù)參數(shù)類(lèi)型查找返回(僅返回public構(gòu)造器);
  • Field[] getDeclaredFields():返回一個(gè)Field數(shù)組對(duì)象,代表該Class字節(jié)碼對(duì)象所代表的類(lèi)或接口的所有成員屬性(包括公開(kāi)的私有的);
  • Method[] getDeclaredMethods():返回一組 包含了該字節(jié)碼對(duì)象所有的Method方法對(duì)象;
  • Constructor<?>[] getDeclaredConstructors():返回一組 Constructor對(duì)象,包含了該字節(jié)碼對(duì)象中的所有、構(gòu)造器對(duì)象;
  • Field getDeclaredField(String name):返回一個(gè) Field對(duì)象,根據(jù)指定的字段屬性名來(lái)查找返回;
  • Method getDeclaredMethod(mName,pType...):返回一個(gè)Method方法對(duì)象,根據(jù)方法名、參數(shù)類(lèi)型作為區(qū)分;
  • Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes):返回一個(gè)任意修飾符的Constructor對(duì)象,根據(jù)參數(shù)類(lèi)型查找返回;
  • java.net.URL getResource(String name):
  • T cast(Object obj):將指定obj對(duì)象強(qiáng)制轉(zhuǎn)換成Class字節(jié)碼對(duì)象所代表的類(lèi)。
  1. 代碼示例
//創(chuàng)建字節(jié)碼對(duì)象
            Class c = Class.forName("com.yry.pratice.reflection.bean.User");
            System.out.println(c);
            //將字節(jié)碼對(duì)象c換成字符串輸出:Class或Interface 全類(lèi)名
            String s = c.toString();
            System.out.println(s);
            //獲取字節(jié)碼對(duì)象所代表類(lèi)的名稱(chēng)
            String name = c.getName();//全類(lèi)名
            System.out.println(name);//com.yry.pratice.reflection.bean.User
            String simpleName = c.getSimpleName();//簡(jiǎn)類(lèi)名
            System.out.println(simpleName);//User
            //由字節(jié)碼對(duì)象 反射創(chuàng)建 實(shí)例對(duì)象s
            Object instance = c.newInstance();
            System.out.println(instance);//輸出instance.toString()的執(zhí)行結(jié)果
            //判斷指定obj對(duì)象是否 該字節(jié)碼對(duì)象的一個(gè)實(shí)例
            Object oo = new Object();
            boolean b = c.isInstance(oo);
            System.out.println(b);
            //獲取加載該字節(jié)碼對(duì)象的類(lèi)加載器
            ClassLoader classLoader = c.getClassLoader();
            System.out.println(classLoader);//

            //獲取該字節(jié)碼對(duì)象的修飾符--public公開(kāi)的修飾符
            int modifiers = c.getModifiers();//不同的int值代表不同的修飾符
            System.out.println(modifiers);//1
            //將int類(lèi)型修飾符 轉(zhuǎn)換成 String字符串表示
            String s1 = Modifier.toString(modifiers);
            System.out.println(s1);//1對(duì)應(yīng)public

1.4 java.lang.reflect.Constructor<T>構(gòu)造器類(lèi)

  1. 定義
    Constructor提供關(guān)于類(lèi)的單個(gè)構(gòu)造方法的信息 以及對(duì)它的訪問(wèn)權(quán)限。
  2. 實(shí)質(zhì)
    Constructor在反射中指的是Class字節(jié)碼對(duì)象所代表類(lèi)的構(gòu)造器。
  3. 常用方法
  • Class<T> getDeclaringClass():返回Class字節(jié)碼對(duì)象,返回聲明此Constructor構(gòu)造器 表示的Class"類(lèi)"對(duì)象;
  • String getName():返回此構(gòu)造方法的名稱(chēng);
  • int getModifiers():返回此構(gòu)造方法的修飾符(需要配合Modifier類(lèi)的toString()方法將其轉(zhuǎn)換成字符串);
  • Class<?>[] getParameterTypes():按聲明順序返回此構(gòu)造方法參數(shù)列表中的 參數(shù)類(lèi)型數(shù)組;
  • int getParameterCount():返回此構(gòu)造方法參數(shù)列表中的 參數(shù)的個(gè)數(shù);
  • Class<?>[] getExceptionTypes():返回一組 此構(gòu)造方法拋出的所有異常類(lèi)型數(shù)組;
  • boolean equals(Object obj):將此Constructor對(duì)象與obj對(duì)象進(jìn)行比較是否相同,如果兩個(gè)對(duì)象由相同的類(lèi)聲明并且具有相同的形參類(lèi)型則是相同的。
  • int hashCode():返回此Constructor的哈希碼,與此Constructor所代表的類(lèi)的哈希碼相同;
  • String toString():返回描述此構(gòu)造器的字符串,構(gòu)造方法唯一可能的修飾符是訪問(wèn)修飾符public、protected或private;
  • T newInstance(Object ... initargs):通過(guò)此構(gòu)造方法所代表的類(lèi)來(lái) 創(chuàng)建的新對(duì)象;
  • boolean isVarArgs():判斷此構(gòu)造方法是否帶可變數(shù)量的參數(shù);
  • T getAnnotation(Class<T> annotation):如果此構(gòu)造器上 存在指定annotation.Class類(lèi)型的注釋?zhuān)祷剡@些注釋?zhuān)?/li>
  • Annotation[] getDeclaredAnnotations():返回一組 直接存在于此構(gòu)造器上的所有注釋?zhuān)?/li>
  1. 代碼示例
            //創(chuàng)建字節(jié)碼對(duì)象
            Class c = Class.forName("com.yry.pratice.reflection.bean.User");
            //獲取該字節(jié)碼對(duì)象的構(gòu)造器
            Constructor[] constructors = c.getConstructors();
            for (Constructor con:constructors) {
                System.out.println(con.getModifiers());//構(gòu)造器的修飾符
                System.out.println(con.getDeclaringClass());//聲明該構(gòu)造器的類(lèi)
                System.out.println(con.getName());//構(gòu)造器的名稱(chēng)
                //獲取構(gòu)造器的參數(shù)類(lèi)型數(shù)組
                Class[] parameterTypes = con.getParameterTypes();
                for (Class cas: parameterTypes) {
                    System.out.println(cas.getClass());//構(gòu)造器參數(shù)的類(lèi)型
                    System.out.println(cas.getSimpleName());//構(gòu)造器參數(shù)的名稱(chēng)
                }
            }

1.5 java.lang.reflect.Field屬性類(lèi)<重要掌握>

  1. 定義
    Field提供有關(guān) 類(lèi)或接口的單個(gè)字段的信息,以及對(duì)它的動(dòng)態(tài)訪問(wèn)權(quán)限。反射的字段可能是一個(gè)類(lèi)字段(靜態(tài)字段)或?qū)嵗侄巍?/li>
  2. 實(shí)質(zhì)
    Field指的是Class字節(jié)碼對(duì)象所代表的類(lèi)中的普通字段或?qū)傩?,每一個(gè)字段或?qū)傩远际且粋€(gè)對(duì)象。
  3. 常用方法
  • Class<?> getDeclaringClass():返回聲明此Field對(duì)象所表示字段的類(lèi)或接口 的Class對(duì)象;
  • String getName():返回此Field對(duì)象所表示字段的名稱(chēng);
  • int getModifiers():返回此Field對(duì)象所表示字段的修飾符;
  • boolean isEnumConstant():判斷該Filed對(duì)象所表示的字段是否是枚舉類(lèi)型的元素;
  • Class<?> getType():返回此Field對(duì)象所表示字段的數(shù)據(jù)類(lèi)型;
  • boolean equals(Object obj):判斷兩個(gè)字段對(duì)象obj與此Filed對(duì)象比較是否相同,如果兩個(gè)對(duì)象由相同的類(lèi)聲明并且具有相同的名稱(chēng)和類(lèi)型,則相同的;
  • int hashCode():返回此Field對(duì)象所表示字段的哈希地址;
  • String toString():返回該Field對(duì)象所表示字段的字符串表示形式(原字段的定義格式);
  • Object get(Object obj):從obj對(duì)象中獲取 此Field表示的字段的值(obj對(duì)象需要擁有相同F(xiàn)iled表示的字段);
  • boolean getBoolean(Object obj):從obj對(duì)象中 獲取一個(gè)靜態(tài)或?qū)嵗?boolean字段的值(相同用法可以獲取其他數(shù)據(jù)類(lèi)型字段的值);
  • void set(Object obj, Object value):將obj對(duì)象上此Field對(duì)象表示的字段 設(shè)置為指定的新值;
  • T getAnnotation(Class<T> annotation):如果此字段屬性上 存在指定annotation.Class類(lèi)型的注釋?zhuān)祷剡@些注釋?zhuān)?/li>
  1. 代碼示例
            //創(chuàng)建字節(jié)碼對(duì)象
            Class c = Class.forName("com.yry.pratice.reflection.bean.User");

            //獲取該字節(jié)碼對(duì)象的public公開(kāi)的"字段對(duì)象"
            Field no = c.getField("no");//僅獲取public字段
            System.out.println(no.getType().getSimpleName());//字段類(lèi)型:int
            System.out.println(no.getName());//字段名/變量名:no
            //獲取該字節(jié)碼對(duì)象所有的"字段對(duì)象"
            Field[] declaredFields = c.getDeclaredFields();
            for (Field f: declaredFields) {
                System.out.println(f.getModifiers());//字段修飾符
                System.out.println(f.getType());//字段數(shù)據(jù)類(lèi)型
                System.out.println(f.getName());//字段名或變量名
            }

1.6 java.lang.reflect.Method方法類(lèi)<重要掌握>

  1. 定義
    Method提供關(guān)于 類(lèi)或接口上單獨(dú)某個(gè)方法的信息,以及如何訪問(wèn)該方法。所反映的方法可能是類(lèi)方法或?qū)嵗椒ǎòǔ橄蠓椒ǎ?/li>
  2. 實(shí)質(zhì)
    Method指的是Class字節(jié)碼對(duì)象所代表的類(lèi)中的方法,即常用的自定義方法或普通方法 對(duì)象。
  3. 常用方法
  • Class<?> getDeclaringClass():返回聲明此Method對(duì)象所表示方法的類(lèi)或接口 的Class對(duì)象;
  • String getName():返回此Method對(duì)象所表示方法的名稱(chēng);
  • int getModifiers():返回此Method對(duì)象所表示方法的修飾符(需要配合Modifier類(lèi)的toString()方法將其轉(zhuǎn)換為字符串);
  • Class<?> getReturnType():返回此Method對(duì)象所表示方法的返回值類(lèi)型;
  • Class<?>[] getParameterTypes():返回一組 此Method對(duì)象所表示方法的參數(shù)(類(lèi)型)列表;
  • int getParameterCount():返回此Method對(duì)象所表示方法的 參數(shù)個(gè)數(shù);
  • Class<?>[] getExceptionTypes()::返回一組 此Method對(duì)象所表示方法拋出的 異常類(lèi)型;
  • boolean equals(Object obj):判斷兩個(gè)方法對(duì)象 obj對(duì)象與此Method對(duì)象是否相同,兩個(gè)對(duì)象代表的方法由相同的類(lèi)聲明 并具有相同的名稱(chēng)、形參類(lèi)型和返回類(lèi)型,則相同;
  • String toString():返回該Method對(duì)象的字符串表示形式(該Method對(duì)象所代表方法的定義格式);
  • boolean isVarArgs():判斷此Method對(duì)象所表示方法是否有可變數(shù)量的參數(shù);
  • T getAnnotation(Class<T> annotation):如果此Method對(duì)象所表示的方法上存在指定annotation.Class類(lèi)型的注釋?zhuān)祷剡@些注釋?zhuān)?/li>
  • Annotation[] getDeclaredAnnotations():返回一組 直接存在于此Method對(duì)象所表示的方法上的所有注釋。
  1. 代碼示例
            //創(chuàng)建字節(jié)碼對(duì)象
            Class c = Class.forName("com.yry.pratice.reflection.bean.User");
            //獲取該字節(jié)碼對(duì)象的"方法對(duì)象"
            Method[] methods = c.getMethods();
            for (Method me:methods) {
                System.out.println(me.getDeclaringClass().getSimpleName());//聲明該方法的類(lèi)
                System.out.println(me.getModifiers());//方法的修飾符
                System.out.println(me.getReturnType());//方法的返回值類(lèi)型
                System.out.println(me.getName());//方法的名稱(chēng)
                Class<?>[] parameterTypes = me.getParameterTypes();//方法的參數(shù)列表
                for (Class cs:parameterTypes) {
                    System.out.println(cs.getClass().getSimpleName());//參數(shù)類(lèi)型的名稱(chēng)
                    System.out.println(cs.getName());//參數(shù)的名稱(chēng)
                    //System.out.println(cs.getSimpleName());//參數(shù)的名稱(chēng)
                }
            }

1.7 java.lang.reflect.Modifier修飾符類(lèi)

  1. 定義
    Modifier提供關(guān)于 類(lèi)或接口上的字段、屬性、方法的修飾符信息,Modifier類(lèi)中提供的都是static方法和常量,直接使用類(lèi)名.調(diào)用,可以對(duì)類(lèi)和成員的訪問(wèn)修飾符進(jìn)行解碼。
  2. 特點(diǎn)
    修飾符集被表示為整數(shù),用不同的位-位置 (bit position) 表示不同的修飾符,需要使用toString(位置)方法將位置轉(zhuǎn)換為字符串(真正的修飾符表示)。
  3. 實(shí)質(zhì)
    Modifier指的是Class字節(jié)碼對(duì)象所代表的類(lèi)中的修飾符,即常用的修飾符對(duì)象。
  4. 字段
  • int PUBLIC = 0x00000001:表示public修飾符的 int值,getModifiers()返回 1表示該修飾符為public;
  • int PRIVATE = 0x00000002:表示private修飾符的 int值,getModifiers()返回 2(以下同理:返回值是幾對(duì)應(yīng)不同的修飾符);
  • int PROTECTED = 0x00000004:表示protected修飾符的 int值,getModifiers()返回 4;
  • int STATIC = 0x00000008:表示static修飾符的 int值,getModifiers()返回 8;
  • int FINAL = 0x00000010:表示final修飾符的 int值,getModifiers()返回 10;
  • int SYNCHRONIZED = 0x00000020:表示synchronized修飾符的 int值,getModifiers()返回 20;
  • int VOLATILE = 0x00000040:表示volatile修飾符的 int值,getModifiers()返回 40;
  • int TRANSIENT = 0x00000080:表示transient修飾符的 int值,getModifiers()返回 80
  • int NATIVE = 0x00000100:表示native修飾符的 int值,getModifiers()返回 100;
  • int INTERFACE = 0x00000200:表示interface修飾符的 int值,getModifiers()返回 200;
  • int ABSTRACT = 0x00000400:表示abstract修飾符的 int值,getModifiers()返回 400
  1. 常用方法
  • String toString(int mod):將getModifiers()返回的代表指定修飾符的int值 轉(zhuǎn)換為字符串;
  • boolean isPublic(int mod):判斷整數(shù)參數(shù)mod是否包括public修飾符;
  • boolean isXxx(int mod):判斷整數(shù)參數(shù)mod是否包括Xxx修飾符。
  1. 代碼示例
            //創(chuàng)建字節(jié)碼對(duì)象,獲取字節(jié)碼文件
            Class c = Class.forName("com.yry.pratice.reflection.bean.User");
            //獲取字節(jié)碼中 Filed字段對(duì)象
            Field no = c.getField("no");
            //獲取修飾Field字段的修飾符--返回的int值代表不同的修飾符
            int modifiers = no.getModifiers();
            System.out.println(modifiers);//返回int值為1
            //將返回的int值轉(zhuǎn)換為對(duì)應(yīng)修飾符的字符串表示
            String s = Modifier.toString(modifiers);
            System.out.println(s);//int值為1對(duì)應(yīng)的修飾符為:Public
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容