<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          反射知識(shí)點(diǎn)總匯

          共 11332字,需瀏覽 23分鐘

           ·

          2021-10-20 08:08

          點(diǎn)擊上方“程序員大白”,選擇“星標(biāo)”公眾號(hào)

          重磅干貨,第一時(shí)間送達(dá)

          一、概念

          1.1 概念

          簡(jiǎn)單說(shuō),JAVA反射機(jī)制是指在運(yùn)行態(tài)可直接操作任意類或?qū)ο蟮乃袑傩院头椒ǖ墓δ堋?/span>

          1.2 反射的用途

          • 在運(yùn)行時(shí)獲取任意對(duì)象所屬的類
            Class clazz = Class.forName(String className);

          • 在運(yùn)行時(shí)構(gòu)造任意類的對(duì)象
            Object obj = clazz.newInstance();

          • 在運(yùn)行時(shí)獲取任意類所具有的成員變量和方法
            field.set(Object obj, Object value);
            field.get(Object obj);

          • 在運(yùn)行時(shí)調(diào)用任意對(duì)象的方法 (最常見的需求,尤其是當(dāng)該方法是私有方法或者隱藏方法)
            method.invoke(Object obj, Object... args);

          反射還可以獲取類的其他信息,包含modifiers(下面會(huì)介紹),以及superclass, 實(shí)現(xiàn)的interfaces等。

          針對(duì)動(dòng)態(tài)語(yǔ)言,大致認(rèn)同的一個(gè)定義是:“程序運(yùn)行時(shí),允許改變程序結(jié)構(gòu)或變量類型,這種語(yǔ)言稱為動(dòng)態(tài)語(yǔ)言”。反射機(jī)制在運(yùn)行時(shí)只能調(diào)用methods或改變fields內(nèi)容,卻無(wú)法修改程序結(jié)構(gòu)或變量類型。從這個(gè)觀點(diǎn)看,Perl,Python,Ruby是動(dòng)態(tài)語(yǔ)言,C++,Java,C#不是動(dòng)態(tài)語(yǔ)言。

          二、反射

          2.1 核心類

          java.lang.Class:代表類
          java.lang.reflect.Constructor: 代表類的構(gòu)造方法
          java.lang.reflect.Field: 代表類的屬性
          java.lang.reflect.Method: 代表類的方法
          java.lang.reflect.Modifier:代表類、方法、屬性的描述修飾符。

          其中Modifier取值范圍如下:
          public, protected, private, abstract, static, final, transient, volatile, synchronized, native, strictfp, interface。

          Constructor, Field, Method這三個(gè)類都繼承AccessibleObject,該對(duì)象有一個(gè)非常重要的方法setAccessible(boolean flag), 借助該方法,能直接調(diào)用非Public的屬性與方法。

          2.2 核心方法

          1.成員屬性(Field):

          1getFields():獲得類的public類型的屬性。
          2getDeclaredFields():獲得類的所有屬性。
          3getField(String?name)
          4getDeclaredField(String?name):獲取類的特定屬性

          2.成員方法(Method):

          1getMethods():獲得類的public類型的方法。
          2getDeclaredMethods():獲得類的所有方法。
          3getMethod(String?name,?Class[] parameterTypes):獲得類的特定方法
          4getDeclaredMethod(String?name,?Class[] parameterTypes):獲得類的特定方法

          3.構(gòu)造方法(Constructor):

          1getConstructors():獲得類的public類型的構(gòu)造方法。
          2getDeclaredConstructors():獲得類的所有構(gòu)造方法。
          3getConstructor(Class[] parameterTypes):獲得類的特定構(gòu)造方法
          4getDeclaredConstructor(Class[] params);獲得類的特定方法

          2.3 深入Class類

          Java所有的類都是繼承于Oject類,其內(nèi)聲明了多個(gè)應(yīng)該被所有Java類覆寫的方法:hashCode()、equals()、clone()、toString()、notify()、wait()、getClass()等,其中g(shù)etClass返回的便是一個(gè)Class類的對(duì)象。Class類也同樣是繼承Object類,擁有相應(yīng)的方法。

          Java程序在運(yùn)行時(shí),運(yùn)行時(shí)系統(tǒng)對(duì)每一個(gè)對(duì)象都有一項(xiàng)類型標(biāo)識(shí),用于記錄對(duì)象所屬的類。虛擬機(jī)使用運(yùn)行時(shí)類型來(lái)選擇相應(yīng)方法去執(zhí)行,保存所有對(duì)象類型信息的類便是Class類。

          Class類沒有公共構(gòu)造方法,Class對(duì)象是在加載類時(shí)由 Java 虛擬機(jī)以及通過(guò)調(diào)用ClassLoader的defineClass 方法自動(dòng)構(gòu)造的,因此不能顯式地聲明一個(gè)Class對(duì)象。

          虛擬機(jī)為每種類型管理一個(gè)獨(dú)一無(wú)二的Class對(duì)象。也就是說(shuō),每個(gè)類(型)都有一個(gè)Class對(duì)象。運(yùn)行程序時(shí),Java虛擬機(jī)(JVM)首先檢查是否所要加載的類對(duì)應(yīng)的Class對(duì)象是否已經(jīng)加載。如果沒有加載,JVM就會(huì)根據(jù)類名查找.class文件,并將其Class對(duì)象載入。

          基本的 Java 類型(boolean、byte、char、short、int、long、float 和 double)和關(guān)鍵字 void 也都對(duì)應(yīng)一個(gè) Class 對(duì)象。每個(gè)數(shù)組屬于被映射為 Class 對(duì)象的一個(gè)類,所有具有相同元素類型和維數(shù)的數(shù)組都共享該 Class 對(duì)象。一般某個(gè)類的Class對(duì)象被載入內(nèi)存,它就用來(lái)創(chuàng)建這個(gè)類的所有對(duì)象。

          三、用處

          1.如何通過(guò)反射獲取一個(gè)類?

          Class.forName(String className); (最常用)

          2.如何調(diào)用私有類,或者類的私有方法或?qū)傩裕?/span>

          • 私有類:通過(guò)getDeclaredConstructor獲取constructor,再調(diào)用constructor.setAccessible(true);

          • 私有方法:通過(guò)getDeclaredMethod獲取method,再調(diào)用method.setAccessible(true);

          • 私有屬性:通過(guò)getDeclaredField獲取field,再調(diào)用field.setAccessible(true);

          3.@hide標(biāo)記是做什么的,反射能否調(diào)用@hide標(biāo)記的類?

          在Android的源碼中,我們會(huì)發(fā)現(xiàn)有很多被”@hide”標(biāo)記的類,它的作用是使這個(gè)類或方法在生成SDK時(shí)不可見。那么應(yīng)用程序便不可以直接調(diào)用。而反射機(jī)制可調(diào)用@hide標(biāo)記的類或方法,如入無(wú)人之地,暢通無(wú)阻。

          4.如何通過(guò)反射調(diào)用內(nèi)部類?

          假設(shè)com.reflect.Outer類有一個(gè)內(nèi)部類inner,調(diào)用方法如下:

          1String?className?=?"com.reflect.Outer$inner";
          2Class.forName(className);

          五、反射用法

          前面介紹到,反射是為了在運(yùn)行態(tài)能操作類和對(duì)象,接下來(lái)重點(diǎn)介紹如何反射使用。

          對(duì)于正常方式來(lái)調(diào)用方法,往往只需要一行到兩行代碼,即可完成相應(yīng)工作。而反射則顯得比較繁瑣,之所以繁瑣仍然使用反射方式,是因?yàn)榉瓷淠芨珊芏嗾?shí)例化對(duì)象的方式所無(wú)法做到的事。比如操作那些private的類、方法、屬性,以及@hide標(biāo)記過(guò)的類、方法、屬性。

          為了到達(dá)即能有反射的功效,同時(shí)調(diào)用方法簡(jiǎn)單易用,寫了一個(gè)ReflectUtils類。對(duì)于方法調(diào)用,與正常對(duì)象的調(diào)用過(guò)程差不多。主要有以下4類需要用到反射的地方:

          1. 調(diào)用類的靜態(tài)方法

          2. 調(diào)用類的非靜態(tài)方法

          3. set/get類的靜態(tài)屬性

          4. set/get類的非靜態(tài)屬性

          5.1?ReflectUtils類用法

          調(diào)用流程一般為先獲取類或?qū)ο?,再調(diào)用相應(yīng)方法。針對(duì)上述4種需求,用法分別如下:

          1. 調(diào)用類的靜態(tài)方法
          對(duì)于參數(shù)方法,只需把參數(shù),緊跟方法名后面,可以跟不定長(zhǎng)的參數(shù)個(gè)數(shù)。

          1Class?clazz?=?ReflectUtils.getClazz("com.yuanhh.model.Outer");?//獲取class
          2ReflectUtils.invokeStaticMethod(clazz,?"outerStaticMethod");??//無(wú)參方法
          3ReflectUtils.invokeStaticMethod(clazz,?"outerStaticMethod","yuanhh");?//有參數(shù)方法

          2. 調(diào)用類的非靜態(tài)方法

          1Object?obj?=?ReflectUtils.newInstance("com.yuanhh.model.Outer");??//實(shí)例化對(duì)象
          2ReflectUtils.invokeMethod(obj,?"outerMethod");??//無(wú)參方法
          3ReflectUtils.invokeMethod(obj,?"outerMethod",?"yuanhh");?//有參方法?**3.?set/get類的靜態(tài)屬性**?
          4
          5ReflectUtils.getStaticField(clazz,?"outerStaticField");?//get操作
          6ReflectUtils.setStaticField(clazz,?"outerStaticField",?"new?value");?//set操作

          4. set/get類的非靜態(tài)屬性

          1ReflectUtils.getField(obj,?"outerField");??//get操作
          2ReflectUtils.setField(obj,?"outerField",?"new?value");?//set操作

          如果只知道類名,需先查看該類的所有方法詳細(xì)參數(shù)信息,可以通過(guò)調(diào)用dumpClass(String className)?,返回值是String,記錄著所有構(gòu)造函數(shù),成員方法,屬性值的信息。

          5.2 核心代碼

          關(guān)于ReflectUtils類,列表部分核心方法。

          先定義一個(gè)Outer類, 包名假設(shè)為com.yuanhh.model,對(duì)于該類,非public,構(gòu)造方法,成員方法,屬性都是private:

           1class?Outer?{
          2????private?String?outerField?=?"outer?Field";
          3????private?static?String?outerStaticField?=?"outer?static?Field";
          4
          5????private?Outer(){
          6????????System.out.println("I'am?outer?construction?without?args");
          7????}
          8
          9????private?Outer(String?outerField){
          10????????this.outerField?=?outerField;
          11????????System.out.println("I'am?outer?construction?with?args?"+?this.outerField);
          12????}
          13
          14????private?void?outerMethod(){
          15????????System.out.println("I'am?outer?method");
          16????}
          17
          18????private?void?outerMethod(String?param){
          19????????System.out.println("I'am?outer?method?with?param?"+param);
          20????}
          21
          22????private?static?void?outerStaticMethod(){
          23????????System.out.println("I'am?outer?static?method");
          24????}
          25
          26????private?static?void?outerStaticMethod(String?param){
          27????????System.out.println("I'am?outer?static?method?with?param?"+param);
          28????}
          29}

          構(gòu)造函數(shù),獲取類的實(shí)例化對(duì)象:

           1/**?*?實(shí)例化獲取類名對(duì)應(yīng)的類?*?*?@param?clazz?類?*?@param?constructorArgs?構(gòu)造函數(shù)的各個(gè)參數(shù)?*?@return?實(shí)例化對(duì)象?*/
          2public?static?Object?newInstance(Class?clazz,?Object...?constructorArgs)?{
          3????if?(clazz?==?null)?{
          4????????return?null;
          5????}
          6
          7????Object?object?=?null;
          8
          9????int?argLen?=?constructorArgs?==?null???0?:?constructorArgs.length;
          10????Class[]?parameterTypes?=?new?Class[argLen];
          11????for?(int?i?=?0;?i?12????????parameterTypes[i]?=?constructorArgs[i].getClass();
          13????}
          14
          15????try?{
          16????????Constructor?constructor?=?clazz.getDeclaredConstructor(parameterTypes);
          17????????if?(!constructor.isAccessible())?{
          18????????????constructor.setAccessible(true);
          19????????}
          20????????object?=?constructor.newInstance(constructorArgs);
          21
          22????}?catch?(Exception?e)?{
          23????????e.printStackTrace();
          24????}
          25
          26????return?object;
          27}

          對(duì)象方法的反射調(diào)用如下:

           1/**?*?反射調(diào)用方法?*?*?@param?object?反射調(diào)用的對(duì)象實(shí)例?*?@param?methodName?反射調(diào)用的對(duì)象方法名?*?@param?methodArgs?反射調(diào)用的對(duì)象方法的參數(shù)列表?*?@return?反射調(diào)用執(zhí)行的結(jié)果?*/
          2public?static?Object?invokeMethod(Object?object,?String?methodName,?Object...?methodArgs)?{
          3????if?(object?==?null)?{
          4????????return?null;
          5????}
          6
          7????Object?result?=?null;
          8????Class?clazz?=?object.getClass();
          9????try?{
          10????????Method?method?=?clazz.getDeclaredMethod(methodName,?obj2class(methodArgs));
          11????????if?(method?!=?null)?{
          12????????????if?(!method.isAccessible())?{
          13????????????????method.setAccessible(true);??//當(dāng)私有方法時(shí),設(shè)置可訪問
          14????????????}
          15????????????result?=?method.invoke(object,?methodArgs);
          16????????}
          17????}?catch?(Exception?e)?{
          18????????e.printStackTrace();
          19????}
          20
          21????return?result;
          22
          23}

          對(duì)象屬性值的反射獲取方法:

           1/**?*?反射調(diào)用,獲取屬性值?*?*?@param?object?操作對(duì)象?*?@param?fieldName?對(duì)象屬性?*?@return?屬性值?*/
          2public?static?Object?getField(Object?object,?String?fieldName)?{
          3????if?(object?==?null)?{
          4????????return?null;
          5????}
          6
          7????Object?result?=?null;
          8????Class?clazz?=?object.getClass();
          9????try?{
          10????????Field?field?=?clazz.getDeclaredField(fieldName);
          11????????if?(field?!=?null)?{
          12????????????if?(!field.isAccessible())?{
          13????????????????field.setAccessible(true);
          14????????????}
          15????????????result?=?field.get(object);
          16????????}
          17????}?catch?(Exception?e)?{
          18????????e.printStackTrace();
          19????}
          20????return?result;
          21}

          類屬性的反射設(shè)置過(guò)程:

           1/**?*?反射調(diào)用,設(shè)置屬性值?*?*?@param?clazz?操作類?*?@param?fieldName?屬性名?*?@param?value?屬性的新值?*?@return?設(shè)置是否成功?*/
          2public?static?boolean?setStaticField(Class?clazz,?String?fieldName,?Object?value)?{
          3????if?(clazz?==?null)?{
          4????????return?false;
          5????}
          6
          7????Object?result?=?null;
          8????try?{
          9????????Field?field?=?clazz.getDeclaredField(fieldName);
          10????????if?(field?!=?null)?{
          11????????????if?(!field.isAccessible())?{
          12????????????????field.setAccessible(true);
          13????????????}
          14????????????field.set(null,?value);
          15????????}
          16????}?catch?(Exception?e)?{
          17????????e.printStackTrace();
          18????????return?false;
          19????}
          20????return?true;
          21}

          六、內(nèi)部類的反射用法

          對(duì)于內(nèi)部類,這里比較復(fù)雜,而內(nèi)部類又分static內(nèi)部類與非static內(nèi)部類,兩者的反射方式還是有區(qū)別的,剛開始在這邊折騰了好一陣子,一直反射失敗。static內(nèi)部類與非static內(nèi)部類的反射調(diào)用,根本區(qū)別在于構(gòu)造方法不一樣。下面通過(guò)代碼來(lái)告訴如何正確。

          6.1 static與非static內(nèi)部類的反射差異

          先定義一個(gè)包含兩個(gè)內(nèi)部類的類:

           1class?Outer?{
          2????/**?*?普通內(nèi)部類?*/
          3????class?Inner?{
          4????????private?String?innerField?=?"inner?Field";
          5
          6????????private?Inner(){
          7????????????System.out.println("I'am?Inner?construction?without?args");
          8????????}
          9
          10????????private?Inner(String?innerField){
          11????????????this.innerField?=?innerField;
          12????????????System.out.println("I'am?Inner?construction?with?args?"+?this.innerField);
          13????????}
          14
          15????????private?void?innerMethod(){
          16????????????System.out.println("I'am?inner?method");
          17????????}
          18????}
          19
          20????/**?*?靜態(tài)內(nèi)部類?*/
          21????static?class?StaticInner?{
          22
          23????????private?String?innerField?=?"StaticInner?Field";
          24????????private?static?String?innerStaticField?=?"StaticInner?static?Field";
          25
          26????????private?StaticInner(){
          27????????????System.out.println("I'am?StaticInner?construction?without?args");
          28????????}
          29
          30????????private?StaticInner(String?innerField){
          31????????????this.innerField?=?innerField;
          32????????????System.out.println("I'am?StaticInner?construction?with?args?"+?this.innerField);
          33????????}
          34
          35????????private?void?innerMethod(){
          36????????????System.out.println("I'am?StaticInner?method");
          37????????}
          38
          39????????private?static?void?innerStaticMethod(){
          40????????????System.out.println("I'am?StaticInner?static?method");
          41????????}
          42????}
          43}

          對(duì)于上面兩個(gè)內(nèi)部類,如果直接實(shí)例化內(nèi)部類,該怎么做,拋開private等權(quán)限不夠的問題,應(yīng)該是這樣的:

          • 靜態(tài)內(nèi)部類:Outer.StaticInner sInner = new Outer.StaticInner();

          • 非靜態(tài)內(nèi)部類:?Outer.Inner inner = new Outer().new Inner();

          這種差異,在于內(nèi)部類的構(gòu)造方法不一樣。我們可以通過(guò)下面的方法dumpClass()來(lái)比較。

           1/**?*?獲取類的所有?構(gòu)造函數(shù),屬性,方法?*?*?@param?className?類名?*?@return?*/
          2public?static?String?dumpClass(String?className)?{
          3????StringBuffer?sb?=?new?StringBuffer();
          4????Class?clazz;
          5????try?{
          6????????clazz?=?Class.forName(className);
          7????}?catch?(ClassNotFoundException?e)?{
          8????????e.printStackTrace();
          9????????return?"";
          10????}
          11
          12????Constructor[]?cs?=?clazz.getDeclaredConstructors();
          13????sb.append("------?Constructor?------>?").append("\n");
          14????for?(Constructor?c?:?cs)?{
          15????????sb.append(c.toString()).append("\n");
          16????}
          17
          18????sb.append("------?Field?------>").append("\n");
          19????Field[]?fs?=?clazz.getDeclaredFields();
          20????for?(Field?f?:?fs)?{
          21????????sb.append(f.toString()).append("\n");
          22????????;
          23????}
          24????sb.append("------?Method?------>").append("\n");
          25????Method[]?ms?=?clazz.getDeclaredMethods();
          26????for?(Method?m?:?ms)?{
          27????????sb.append(m.toString()).append("\n");
          28????}
          29????return?sb.toString();
          30}

          通過(guò)dumpClass(),對(duì)比我們會(huì)發(fā)現(xiàn),

          • static內(nèi)部類的默認(rèn)構(gòu)造函數(shù):?private void com.yuanhh.model.Outer$StaticInner.innerMethod()

          • 非static內(nèi)部類的默認(rèn)構(gòu)造函數(shù):?private com.yuanhh.model.Outer$Inner(com.yuanhh.model.Outer),多了一個(gè)參數(shù)com.yuanhh.model.Outer,也就是說(shuō)非static內(nèi)部類保持了外部類的引用。從屬性,我們也會(huì)發(fā)現(xiàn)多了一個(gè)final屬性final com.yuanhh.model.Outer com.yuanhh.model.Outer$Inner.this$0,這正是用于存儲(chǔ)外部類的屬性值。

          正是這差異,導(dǎo)致兩者的反射調(diào)用過(guò)程中構(gòu)造方法的使用不一樣。另外內(nèi)部類的類名使用采用$符號(hào),來(lái)連接外部類與內(nèi)部類,格式為outer$inner。

          6.2 static內(nèi)部類的?ReflectUtils類用法

          1. 調(diào)用類的靜態(tài)方法(先獲取類,再調(diào)用)

          1Class?clazz?=?ReflectUtils.getClazz("com.yuanhh.model.Outer$StaticInner");?//獲取class
          2?ReflectUtils.invokeStaticMethod(clazz,?"innerStaticMethod");??//無(wú)參方法
          3?ReflectUtils.invokeStaticMethod(clazz,?"innerStaticMethod","yuanhh");?//有參數(shù)方法

          2. 調(diào)用類的非靜態(tài)方法(先獲取對(duì)象,再調(diào)用)

          1Object?obj?=?ReflectUtils.newInstance("com.yuanhh.model.Outer$StaticInner");??//實(shí)例化對(duì)象
          2?ReflectUtils.invokeMethod(obj,?"innerMethod");??//無(wú)參方法
          3?ReflectUtils.invokeMethod(obj,?"innerMethod",?"yuanhh");?//有參方法

          3. set/get類的靜態(tài)屬性(先獲取類,再調(diào)用)

          1?ReflectUtils.getStaticField(clazz,?"innerField");?//get操作
          2?ReflectUtils.setStaticField(clazz,?"innerField",?"new?value");?//set操作

          4. set/get類的非靜態(tài)屬性(先獲取對(duì)象,再調(diào)用)

          1ReflectUtils.getField(obj,?"innerField");??//get操作
          2?ReflectUtils.setField(obj,?"innerField",?"new?value");?//set操作?### 2.2 非static內(nèi)部類的?`ReflectUtils`類用法?非static內(nèi)部類,不能定義靜態(tài)方法和靜態(tài)屬性,故操作只有兩項(xiàng):

          5. 調(diào)用類的非靜態(tài)方法(先獲取對(duì)象,再調(diào)用)

          1//?獲取外部類實(shí)例,這是static內(nèi)部類所不需要的,注意點(diǎn)
          2?Object?outObj?=?ReflectUtils.newInstance("com.yuanhh.model.Outer");?
          3?Object?obj?=?ReflectUtils.newInstance("com.yuanhh.model.Outer$Inner",?outObj);??//實(shí)例化對(duì)象
          4?ReflectUtils.invokeMethod(obj,?"innerMethod");??//無(wú)參方法
          5?ReflectUtils.invokeMethod(obj,?"innerMethod",?"yuanhh");?//有參方法

          6. set/get類的非靜態(tài)屬性(先獲取對(duì)象,再調(diào)用)

          1ReflectUtils.getField(obj,?"innerField");??//get操作
          2?ReflectUtils.setField(obj,?"innerField",?"new?value");?//set操作

          七、小結(jié)

          • 主要ReflectUtils類的用法,只需要按1.1?ReflectUtils類用法的方式使用即可,比如反射調(diào)用方法,只需知道類與方法名,即可調(diào)用完成invokeMethod(Object object, String methodName)操作簡(jiǎn)單。

          • static與非static內(nèi)部類的區(qū)別,在2.2與2.3這兩節(jié),對(duì)于內(nèi)部類差異僅僅在于傳遞參數(shù)多了一個(gè)$符號(hào),以及非static內(nèi)部類實(shí)例化需要加上外部類的實(shí)例。

          • ReflectUtils類,以及本文所有涉及的代碼,即將打包上傳。

          source: //yuanfentiank789.github.io/2015/07/18/java-reflection


          國(guó)產(chǎn)小眾瀏覽器因屏蔽視頻廣告,被索賠100萬(wàn)(后續(xù))

          年輕人“不講武德”:因看黃片上癮,把網(wǎng)站和786名女主播起訴了

          中國(guó)聯(lián)通官網(wǎng)被發(fā)現(xiàn)含木馬腳本,可向用戶推廣色情APP

          張一鳴:每個(gè)逆襲的年輕人,都具備的底層能力


          關(guān)


          ,學(xué),西學(xué)學(xué)運(yùn)營(yíng)護(hù)號(hào),質(zhì)結(jié)識(shí)關(guān)[],學(xué)習(xí)進(jìn)!


          瀏覽 127
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  蜜桃av电影网 | 毛片网站多少 | 影音先锋色网 | 亚洲午夜无码 | 亚洲AV第二区国产精品 |