日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程语言 > java >内容正文

java

Java编程的逻辑 (84) - 反射

發(fā)布時(shí)間:2023/12/10 java 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Java编程的逻辑 (84) - 反射 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

?本系列文章經(jīng)補(bǔ)充和完善,已修訂整理成書(shū)《Java編程的邏輯》,由機(jī)械工業(yè)出版社華章分社出版,于2018年1月上市熱銷(xiāo),讀者好評(píng)如潮!各大網(wǎng)店和書(shū)店有售,歡迎購(gòu)買(mǎi),京東自營(yíng)鏈接:http://item.jd.com/12299018.html


上節(jié)介紹完了并發(fā),從本節(jié)開(kāi)始,我們來(lái)探討Java中的一些動(dòng)態(tài)特性,包括反射、類(lèi)加載器、注解和動(dòng)態(tài)代理等。利用這些特性,可以以?xún)?yōu)雅的方式實(shí)現(xiàn)一些靈活和通用的功能,經(jīng)常用于各種框架、庫(kù)和系統(tǒng)程序中,比如:

  • 在63節(jié)介紹的實(shí)用序列化庫(kù)Jackson,利用反射和注解實(shí)現(xiàn)了通用的序列化/反序列化機(jī)制
  • 有多種庫(kù)如Spring MVC, Jersey用于處理Web請(qǐng)求,利用反射和注解,能方便的將用戶(hù)的請(qǐng)求參數(shù)和內(nèi)容轉(zhuǎn)換為Java對(duì)象,將Java對(duì)象轉(zhuǎn)變?yōu)轫憫?yīng)內(nèi)容
  • 有多種庫(kù)如Spring, Guice利用這些特性實(shí)現(xiàn)了對(duì)象管理容器,方便程序員管理對(duì)象的生命周期以及其中復(fù)雜的依賴(lài)關(guān)系
  • 應(yīng)用服務(wù)器比如Tomcat利用類(lèi)加載器實(shí)現(xiàn)不同應(yīng)用之間的隔離、JSP技術(shù)也利用類(lèi)加載器實(shí)現(xiàn)修改代碼不用重啟就能生效的特性
  • 面向方面的編程(AOP - Aspect Oriented Programming)將編程中通用的關(guān)注點(diǎn)比如日志記錄、安全檢查等與業(yè)務(wù)的主體邏輯相分離,減少冗余代碼,提高程序的可維護(hù)性,AOP需要依賴(lài)上面的這些特性來(lái)實(shí)現(xiàn)

本節(jié)先來(lái)看反射機(jī)制。

在一般操作數(shù)據(jù)的時(shí)候,我們都是知道并且依賴(lài)于數(shù)據(jù)的類(lèi)型的,比如:

  • 根據(jù)類(lèi)型使用new創(chuàng)建對(duì)象
  • 根據(jù)類(lèi)型定義變量,類(lèi)型可能是基本類(lèi)型、類(lèi)、接口或數(shù)組
  • 將特定類(lèi)型的對(duì)象傳遞給方法
  • 根據(jù)類(lèi)型訪問(wèn)對(duì)象的屬性,調(diào)用對(duì)象的方法

編譯器也是根據(jù)類(lèi)型,進(jìn)行代碼的檢查編譯。

反射不一樣,它是在運(yùn)行時(shí),而非編譯時(shí),動(dòng)態(tài)獲取類(lèi)型的信息,比如接口信息、成員信息、方法信息、構(gòu)造方法信息等,根據(jù)這些動(dòng)態(tài)獲取到的信息創(chuàng)建對(duì)象、訪問(wèn)/修改成員、調(diào)用方法等。這么說(shuō)比較抽象,下面我們會(huì)具體來(lái)說(shuō)明,反射的入口是名稱(chēng)為"Class"的類(lèi),我們來(lái)看下。

"Class"類(lèi)

獲取Class對(duì)象

我們?cè)?span style="color:#000000;">17節(jié)介紹過(guò)類(lèi)和繼承的基本實(shí)現(xiàn)原理,我們提到,每個(gè)已加載的類(lèi)在內(nèi)存都有一份類(lèi)信息,每個(gè)對(duì)象都有指向它所屬類(lèi)信息的引用。Java中,類(lèi)信息對(duì)應(yīng)的類(lèi)就是java.lang.Class,注意不是小寫(xiě)的class,class是定義類(lèi)的關(guān)鍵字,所有類(lèi)的根父類(lèi)Object有一個(gè)方法,可以獲取對(duì)象的Class對(duì)象:

public final native Class<?> getClass()

Class是一個(gè)泛型類(lèi),有一個(gè)類(lèi)型參數(shù),getClass()并不知道具體的類(lèi)型,所以返回Class<?>。

獲取Class對(duì)象不一定需要實(shí)例對(duì)象,如果在寫(xiě)程序時(shí)就知道類(lèi)名,可以使用<類(lèi)名>.class獲取Class對(duì)象,比如:

Class<Date> cls = Date.class;

接口也有Class對(duì)象,且這種方式對(duì)于接口也是適用的,比如:

Class<Comparable> cls = Comparable.class;

基本類(lèi)型沒(méi)有g(shù)etClass方法,但也都有對(duì)應(yīng)的Class對(duì)象,類(lèi)型參數(shù)為對(duì)應(yīng)的包裝類(lèi)型,比如:

Class<Integer> intCls = int.class; Class<Byte> byteCls = byte.class; Class<Character> charCls = char.class; Class<Double> doubleCls = double.class;

void作為特殊的返回類(lèi)型,也有對(duì)應(yīng)的Class:

Class<Void> voidCls = void.class;

對(duì)于數(shù)組,每種類(lèi)型都有對(duì)應(yīng)數(shù)組類(lèi)型的Class對(duì)象,每個(gè)維度都有一個(gè),即一維數(shù)組有一個(gè),二維數(shù)組有一個(gè)不同的,比如:

String[] strArr = new String[10]; int[][] twoDimArr = new int[3][2]; int[] oneDimArr = new int[10]; Class<? extends String[]> strArrCls = strArr.getClass(); Class<? extends int[][]> twoDimArrCls = twoDimArr.getClass(); Class<? extends int[]> oneDimArrCls = oneDimArr.getClass();

枚舉類(lèi)型也有對(duì)應(yīng)的Class,比如:

enum Size {SMALL, MEDIUM, BIG }Class<Size> cls = Size.class;

Class有一個(gè)靜態(tài)方法forName,可以根據(jù)類(lèi)名直接加載Class,獲取Class對(duì)象,比如:

try {Class<?> cls = Class.forName("java.util.HashMap");System.out.println(cls.getName()); } catch (ClassNotFoundException e) {e.printStackTrace(); }

注意forName可能拋出異常ClassNotFoundException。

有了Class對(duì)象后,我們就可以了解到關(guān)于類(lèi)型的很多信息,并基于這些信息采取一些行動(dòng),Class的方法很多,大部分比較簡(jiǎn)單直接,容易理解,下面,我們分為若干組,進(jìn)行簡(jiǎn)要介紹。

名稱(chēng)信息

Class有如下方法,可以獲取與名稱(chēng)有關(guān)的信息:

public String getName() public String getSimpleName() public String getCanonicalName() public Package getPackage()

getSimpleName不帶包信息,getName返回的是Java內(nèi)部使用的真正的名字,getCanonicalName返回的名字更為友好,getPackage返回的是包信息,它們的不同可以看如下表格:

需要說(shuō)明的是數(shù)組類(lèi)型的getName返回值,它使用前綴[表示數(shù)組,有幾個(gè)[表示是幾維數(shù)組,數(shù)組的類(lèi)型用一個(gè)字符表示,I表示int,L表示類(lèi)或接口,其他類(lèi)型與字符的對(duì)應(yīng)關(guān)系為: boolean(Z), byte(B), char(C), double(D), float(F), long(J), short(S),對(duì)于引用類(lèi)型的數(shù)組,注意最后有一個(gè)分號(hào)";"。

字段(實(shí)例和靜態(tài)變量)信息

類(lèi)中定義的靜態(tài)和實(shí)例變量都被稱(chēng)為字段,用類(lèi)Field表示,位于包java.util.reflect下,后文涉及到的反射相關(guān)的類(lèi)都位于該包下,Class有四個(gè)獲取字段信息的方法:

//返回所有的public字段,包括其父類(lèi)的,如果沒(méi)有字段,返回空數(shù)組 public Field[] getFields() //返回本類(lèi)聲明的所有字段,包括非public的,但不包括父類(lèi)的 public Field[] getDeclaredFields() //返回本類(lèi)或父類(lèi)中指定名稱(chēng)的public字段,找不到拋出異常NoSuchFieldException public Field getField(String name) //返回本類(lèi)中聲明的指定名稱(chēng)的字段,找不到拋出異常NoSuchFieldException public Field getDeclaredField(String name)

Field也有很多方法,可以獲取字段的信息,也可以通過(guò)Field訪問(wèn)和操作指定對(duì)象中該字段的值,基本方法有:

//獲取字段的名稱(chēng) public String getName() //判斷當(dāng)前程序是否有該字段的訪問(wèn)權(quán)限 public boolean isAccessible() //flag設(shè)為true表示忽略Java的訪問(wèn)檢查機(jī)制,以允許讀寫(xiě)非public的字段 public void setAccessible(boolean flag) //獲取指定對(duì)象obj中該字段的值 public Object get(Object obj) //將指定對(duì)象obj中該字段的值設(shè)為value public void set(Object obj, Object value)

在get/set方法中,對(duì)于靜態(tài)變量,obj被忽略,可以為null,如果字段值為基本類(lèi)型,get/set會(huì)自動(dòng)在基本類(lèi)型與對(duì)應(yīng)的包裝類(lèi)型間進(jìn)行轉(zhuǎn)換,對(duì)于private字段,直接調(diào)用get/set會(huì)拋出非法訪問(wèn)異常IllegalAccessException,應(yīng)該先調(diào)用setAccessible(true)以關(guān)閉Java的檢查機(jī)制。

看段簡(jiǎn)單的示例代碼:

List<String> obj = Arrays.asList(new String[]{"老馬","編程"}); Class<?> cls = obj.getClass(); for(Field f : cls.getDeclaredFields()){f.setAccessible(true);System.out.println(f.getName()+" - "+f.get(obj)); }

代碼比較簡(jiǎn)單,就不贅述了。我們?cè)赥hreadLocal一節(jié)介紹過(guò)利用反射來(lái)清空ThreadLocal,這里重復(fù)下其代碼,含義就比較清楚了:

protected void beforeExecute(Thread t, Runnable r) {try {//使用反射清空所有ThreadLocalField f = t.getClass().getDeclaredField("threadLocals");f.setAccessible(true);f.set(t, null);} catch (Exception e) {e.printStackTrace();}super.beforeExecute(t, r); }

除了以上方法,Field還有很多別的方法,比如:

//返回字段的修飾符 public int getModifiers() //返回字段的類(lèi)型 public Class<?> getType() //以基本類(lèi)型操作字段 public void setBoolean(Object obj, boolean z) public boolean getBoolean(Object obj) public void setDouble(Object obj, double d) public double getDouble(Object obj)//查詢(xún)字段的注解信息 public <T extends Annotation> T getAnnotation(Class<T> annotationClass) public Annotation[] getDeclaredAnnotations()

getModifiers返回的是一個(gè)int,可以通過(guò)Modifier類(lèi)的靜態(tài)方法進(jìn)行解讀,比如,假定Student類(lèi)有如下字段:

public static final int MAX_NAME_LEN = 255;

可以這樣查看該字段的修飾符:

Field f = Student.class.getField("MAX_NAME_LEN"); int mod = f.getModifiers(); System.out.println(Modifier.toString(mod)); System.out.println("isPublic: " + Modifier.isPublic(mod)); System.out.println("isStatic: " + Modifier.isStatic(mod)); System.out.println("isFinal: " + Modifier.isFinal(mod)); System.out.println("isVolatile: " + Modifier.isVolatile(mod));

輸出為:

public static final isPublic: true isStatic: true isFinal: true isVolatile: false

關(guān)于注解,我們下節(jié)再詳細(xì)介紹。

方法信息

類(lèi)中定義的靜態(tài)和實(shí)例方法都被稱(chēng)為方法,用類(lèi)Method表示,Class有四個(gè)獲取方法信息的方法:

//返回所有的public方法,包括其父類(lèi)的,如果沒(méi)有方法,返回空數(shù)組 public Method[] getMethods() //返回本類(lèi)聲明的所有方法,包括非public的,但不包括父類(lèi)的 public Method[] getDeclaredMethods() //返回本類(lèi)或父類(lèi)中指定名稱(chēng)和參數(shù)類(lèi)型的public方法,找不到拋出異常NoSuchMethodException public Method getMethod(String name, Class<?>... parameterTypes) //返回本類(lèi)中聲明的指定名稱(chēng)和參數(shù)類(lèi)型的方法,找不到拋出異常NoSuchMethodException public Method getDeclaredMethod(String name, Class<?>... parameterTypes)

Method也有很多方法,可以獲取方法的信息,也可以通過(guò)Method調(diào)用對(duì)象的方法,基本方法有:

//獲取方法的名稱(chēng) public String getName() //flag設(shè)為true表示忽略Java的訪問(wèn)檢查機(jī)制,以允許調(diào)用非public的方法 public void setAccessible(boolean flag) //在指定對(duì)象obj上調(diào)用Method代表的方法,傳遞的參數(shù)列表為args public Object invoke(Object obj, Object... args) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException

對(duì)invoke方法,如果Method為靜態(tài)方法,obj被忽略,可以為null,args可以為null,也可以為一個(gè)空的數(shù)組,方法調(diào)用的返回值被包裝為Object返回,如果實(shí)際方法調(diào)用拋出異常,異常被包裝為InvocationTargetException重新拋出,可以通過(guò)getCause方法得到原異常。

看段簡(jiǎn)單的示例代碼:

Class<?> cls = Integer.class; try {Method method = cls.getMethod("parseInt", new Class[]{String.class});System.out.println(method.invoke(null, "123")); } catch (NoSuchMethodException e) {e.printStackTrace(); } catch (InvocationTargetException e) {e.printStackTrace(); }

Method還有很多方法,可以獲取方法的修飾符、參數(shù)、返回值、注解等信息,比如:

//獲取方法的修飾符,返回值可通過(guò)Modifier類(lèi)進(jìn)行解讀 public int getModifiers() //獲取方法的參數(shù)類(lèi)型 public Class<?>[] getParameterTypes() //獲取方法的返回值類(lèi)型 public Class<?> getReturnType() //獲取方法聲明拋出的異常類(lèi)型 public Class<?>[] getExceptionTypes() //獲取注解信息 public Annotation[] getDeclaredAnnotations() public <T extends Annotation> T getAnnotation(Class<T> annotationClass) //獲取方法參數(shù)的注解信息 public Annotation[][] getParameterAnnotations()

創(chuàng)建對(duì)象和構(gòu)造方法

Class有一個(gè)方法,可以用它來(lái)創(chuàng)建對(duì)象:

public T newInstance() throws InstantiationException, IllegalAccessException

它會(huì)調(diào)用類(lèi)的默認(rèn)構(gòu)造方法(即無(wú)參public構(gòu)造方法),如果類(lèi)沒(méi)有該構(gòu)造方法,會(huì)拋出異常InstantiationException??磦€(gè)簡(jiǎn)單示例:

Map<String,Integer> map = HashMap.class.newInstance(); map.put("hello", 123);

很多利用反射的庫(kù)和框架都默認(rèn)假定類(lèi)有無(wú)參public構(gòu)造方法,所以當(dāng)類(lèi)利用這些庫(kù)和框架時(shí)要記住提供一個(gè)。

newInstance只能使用默認(rèn)構(gòu)造方法,Class還有一些方法,可以獲取所有的構(gòu)造方法:

//獲取所有的public構(gòu)造方法,返回值可能為長(zhǎng)度為0的空數(shù)組 public Constructor<?>[] getConstructors() //獲取所有的構(gòu)造方法,包括非public的 public Constructor<?>[] getDeclaredConstructors() //獲取指定參數(shù)類(lèi)型的public構(gòu)造方法,沒(méi)找到拋出異常NoSuchMethodException public Constructor<T> getConstructor(Class<?>... parameterTypes) //獲取指定參數(shù)類(lèi)型的構(gòu)造方法,包括非public的,沒(méi)找到拋出異常NoSuchMethodException public Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes)

類(lèi)Constructor表示構(gòu)造方法,通過(guò)它可以創(chuàng)建對(duì)象,方法為:

public T newInstance(Object ... initargs) throws InstantiationException,
IllegalAccessException, IllegalArgumentException, InvocationTargetException

比如:

Constructor<StringBuilder> contructor= StringBuilder.class.getConstructor(new Class[]{int.class}); StringBuilder sb = contructor.newInstance(100);

除了創(chuàng)建對(duì)象,Constructor還有很多方法,可以獲取關(guān)于構(gòu)造方法的很多信息,比如:

//獲取參數(shù)的類(lèi)型信息 public Class<?>[] getParameterTypes() //構(gòu)造方法的修飾符,返回值可通過(guò)Modifier類(lèi)進(jìn)行解讀 public int getModifiers() //構(gòu)造方法的注解信息 public Annotation[] getDeclaredAnnotations() public <T extends Annotation> T getAnnotation(Class<T> annotationClass) //構(gòu)造方法中參數(shù)的注解信息 public Annotation[][] getParameterAnnotations()

類(lèi)型檢查和轉(zhuǎn)換

我們?cè)?6節(jié)介紹過(guò)instanceof關(guān)鍵字,它可以用來(lái)判斷變量指向的實(shí)際對(duì)象類(lèi)型,instanceof后面的類(lèi)型是在代碼中確定的,如果要檢查的類(lèi)型是動(dòng)態(tài)的,可以使用Class類(lèi)的如下方法:

public native boolean isInstance(Object obj)

也就是說(shuō),如下代碼:

if(list instanceof ArrayList){System.out.println("array list"); }

和下面代碼的輸出是相同的:

Class cls = Class.forName("java.util.ArrayList"); if(cls.isInstance(list)){System.out.println("array list"); }

除了判斷類(lèi)型,在程序中也往往需要進(jìn)行強(qiáng)制類(lèi)型轉(zhuǎn)換,比如:

List list = .. if(list instanceof ArrayList){ArrayList arrList = (ArrayList)list; }

在這段代碼中,強(qiáng)制轉(zhuǎn)換到的類(lèi)型是在寫(xiě)代碼時(shí)就知道的,如果是動(dòng)態(tài)的,可以使用Class的如下方法:

public T cast(Object obj)

比如:

public static <T> T toType(Object obj, Class<T> cls){return cls.cast(obj); }

isInstance/cast描述的都是對(duì)象和類(lèi)之間的關(guān)系,Class還有一個(gè)方法,可以判斷Class之間的關(guān)系:

// 檢查參數(shù)類(lèi)型cls能否賦給當(dāng)前Class類(lèi)型的變量 public native boolean isAssignableFrom(Class<?> cls);

比如,如下表達(dá)式的結(jié)果都為true:

Object.class.isAssignableFrom(String.class) String.class.isAssignableFrom(String.class) List.class.isAssignableFrom(ArrayList.class)

Class的類(lèi)型信息

Class代表的類(lèi)型既可以是普通的類(lèi)、也可以是內(nèi)部類(lèi),還可以是基本類(lèi)型、數(shù)組等,對(duì)于一個(gè)給定的Class對(duì)象,它到底是什么類(lèi)型呢?可以通過(guò)以下方法進(jìn)行檢查:

//是否是數(shù)組 public native boolean isArray(); //是否是基本類(lèi)型 public native boolean isPrimitive(); //是否是接口 public native boolean isInterface(); //是否是枚舉 public boolean isEnum() //是否是注解 public boolean isAnnotation() //是否是匿名內(nèi)部類(lèi) public boolean isAnonymousClass() //是否是成員類(lèi) public boolean isMemberClass() //是否是本地類(lèi) public boolean isLocalClass()

需要說(shuō)明下匿名內(nèi)部類(lèi)、成員類(lèi)與本地類(lèi)的區(qū)別,本地類(lèi)是指在方法內(nèi)部定義的非匿名內(nèi)部類(lèi),比如,如下代碼:

public static void localClass(){class MyLocal {}Runnable r = new Runnable() {@Overridepublic void run(){}};System.out.println(MyLocal.class.isLocalClass());System.out.println(r.getClass().isLocalClass()); }

MyLocal定義在localClass方法內(nèi)部,就是一個(gè)本地類(lèi),r的對(duì)象所屬的類(lèi)是一個(gè)匿名類(lèi),但不是本地類(lèi)。

成員類(lèi)也是內(nèi)部類(lèi),定義在類(lèi)內(nèi)部、方法外部,它不是匿名類(lèi),也不是本地類(lèi)。

類(lèi)的聲明信息

Class還有很多方法,可以獲取類(lèi)的聲明信息,如修飾符、父類(lèi)、實(shí)現(xiàn)的接口、注解等,如下所示:

//獲取修飾符,返回值可通過(guò)Modifier類(lèi)進(jìn)行解讀 public native int getModifiers() //獲取父類(lèi),如果為Object,父類(lèi)為null public native Class<? super T> getSuperclass() //對(duì)于類(lèi),為自己聲明實(shí)現(xiàn)的所有接口,對(duì)于接口,為直接擴(kuò)展的接口,不包括通過(guò)父類(lèi)間接繼承來(lái)的 public native Class<?>[] getInterfaces(); //自己聲明的注解 public Annotation[] getDeclaredAnnotations() //所有的注解,包括繼承得到的 public Annotation[] getAnnotations() //獲取或檢查指定類(lèi)型的注解,包括繼承得到的 public <A extends Annotation> A getAnnotation(Class<A> annotationClass) public boolean isAnnotationPresent(Class<? extends Annotation> annotationClass)

內(nèi)部類(lèi)

關(guān)于內(nèi)部類(lèi),Class有一些專(zhuān)門(mén)的方法,比如:

//獲取所有的public的內(nèi)部類(lèi)和接口,包括從父類(lèi)繼承得到的 public Class<?>[] getClasses() //獲取自己聲明的所有的內(nèi)部類(lèi)和接口 public Class<?>[] getDeclaredClasses() //如果當(dāng)前Class為內(nèi)部類(lèi),獲取聲明該類(lèi)的最外部的Class對(duì)象 public Class<?> getDeclaringClass() //如果當(dāng)前Class為內(nèi)部類(lèi),獲取直接包含該類(lèi)的類(lèi) public Class<?> getEnclosingClass() //如果當(dāng)前Class為本地類(lèi)或匿名內(nèi)部類(lèi),返回包含它的方法 public Method getEnclosingMethod()

類(lèi)的加載

Class有兩個(gè)靜態(tài)方法,可以根據(jù)類(lèi)名加載類(lèi):

public static Class<?> forName(String className) public static Class<?> forName(String name, boolean initialize, ClassLoader loader)

ClassLoader表示類(lèi)加載器,后面章節(jié)我們會(huì)進(jìn)一步介紹,initialize表示加載后,是否執(zhí)行類(lèi)的初始化代碼(如static語(yǔ)句塊)。第一個(gè)方法中沒(méi)有傳這些參數(shù),相當(dāng)于調(diào)用:

Class.forName(className, true, currentLoader)

currentLoader表示加載當(dāng)前類(lèi)的ClassLoader。

這里className與Class.getName的返回值是一致的,比如,對(duì)于String數(shù)組:

String name = "[Ljava.lang.String;"; Class cls = Class.forName(name); System.out.println(cls == String[].class);

需要注意的是,基本類(lèi)型不支持forName方法,也就是說(shuō),如下寫(xiě)法:

Class.forName("int");

會(huì)拋出異常ClassNotFoundException,那如何根據(jù)原始類(lèi)型的字符串構(gòu)造Class對(duì)象呢?可以對(duì)Class.forName進(jìn)行一下包裝,比如:

public static Class<?> forName(String className) throws ClassNotFoundException{if("int".equals(className)){return int.class;}//其他基本類(lèi)型...return Class.forName(className); }

反射與數(shù)組

對(duì)于數(shù)組類(lèi)型,有一個(gè)專(zhuān)門(mén)的方法,可以獲取它的元素類(lèi)型:

public native Class<?> getComponentType()

比如:

String[] arr = new String[]{}; System.out.println(arr.getClass().getComponentType());

輸出為:

class java.lang.String

java.lang.reflect包中有一個(gè)針對(duì)數(shù)組的專(zhuān)門(mén)的類(lèi)Array(注意不是java.util中的Arrays),提供了對(duì)于數(shù)組的一些反射支持,以便于統(tǒng)一處理多種類(lèi)型的數(shù)組,主要方法有:

//創(chuàng)建指定元素類(lèi)型、指定長(zhǎng)度的數(shù)組, public static Object newInstance(Class<?> componentType, int length) //創(chuàng)建多維數(shù)組 public static Object newInstance(Class<?> componentType, int... dimensions) //獲取數(shù)組array指定的索引位置index處的值 public static native Object get(Object array, int index) //修改數(shù)組array指定的索引位置index處的值為value public static native void set(Object array, int index, Object value) //返回?cái)?shù)組的長(zhǎng)度 public static native int getLength(Object array)

需要注意的是,在Array類(lèi)中,數(shù)組是用Object而非Object[]表示的,這是為什么呢?這是為了方便處理多種類(lèi)型的數(shù)組,int[],String[]都不能與Object[]相互轉(zhuǎn)換,但可以與Object相互轉(zhuǎn)換,比如:

int[] intArr = (int[])Array.newInstance(int.class, 10); String[] strArr = (String[])Array.newInstance(String.class, 10);

除了以O(shè)bject類(lèi)型操作數(shù)組元素外,Array也支持以各種基本類(lèi)型操作數(shù)組元素,如:

public static native double getDouble(Object array, int index) public static native void setDouble(Object array, int index, double d) public static native void setLong(Object array, int index, long l) public static native long getLong(Object array, int index)

反射與枚舉

枚舉類(lèi)型也有一個(gè)專(zhuān)門(mén)方法,可以獲取所有的枚舉常量:

public T[] getEnumConstants()

應(yīng)用示例

介紹了Class的這么多方法,有什么用呢?我們看個(gè)簡(jiǎn)單的示例,利用反射實(shí)現(xiàn)一個(gè)簡(jiǎn)單的通用序列化/反序列化類(lèi)SimpleMapper,它提供兩個(gè)靜態(tài)方法:

public static String toString(Object obj) public static Object fromString(String str)

toString將對(duì)象obj轉(zhuǎn)換為字符串,fromString將字符串轉(zhuǎn)換為對(duì)象。為簡(jiǎn)單起見(jiàn),我們只支持最簡(jiǎn)單的類(lèi),即有默認(rèn)構(gòu)造方法,成員類(lèi)型只有基本類(lèi)型、包裝類(lèi)或String。另外,序列化的格式也很簡(jiǎn)單,第一行為類(lèi)的名稱(chēng),后面每行表示一個(gè)字段,用字符'='分隔,表示字段名稱(chēng)和字符串形式的值。SimpleMapper可以這么用:

public class SimpleMapperDemo {static class Student {String name;int age;Double score;public Student() {}public Student(String name, int age, Double score) {super();this.name = name;this.age = age;this.score = score;}@Overridepublic String toString() {return "Student [name=" + name + ", age=" + age + ", score=" + score + "]";}}public static void main(String[] args) {Student zhangsan = new Student("張三", 18, 89d);String str = SimpleMapper.toString(zhangsan);Student zhangsan2 = (Student) SimpleMapper.fromString(str);System.out.println(zhangsan2);} }

代碼先調(diào)用toString方法將對(duì)象轉(zhuǎn)換為了String,然后調(diào)用fromString方法將字符串轉(zhuǎn)換為了Student,新對(duì)象的值與原對(duì)象是一樣的,輸出如下所示:

Student [name=張三, age=18, score=89.0]

我們來(lái)看SimpleMapper的示例實(shí)現(xiàn)(主要用于演示原理,在生產(chǎn)中謹(jǐn)慎使用),toString的代碼為:

public static String toString(Object obj) {try {Class<?> cls = obj.getClass();StringBuilder sb = new StringBuilder();sb.append(cls.getName() + "\n");for (Field f : cls.getDeclaredFields()) {if (!f.isAccessible()) {f.setAccessible(true);}sb.append(f.getName() + "=" + f.get(obj).toString() + "\n");}return sb.toString();} catch (IllegalAccessException e) {throw new RuntimeException(e);} }

fromString的代碼為:

public static Object fromString(String str) {try {String[] lines = str.split("\n");if (lines.length < 1) {throw new IllegalArgumentException(str);}Class<?> cls = Class.forName(lines[0]);Object obj = cls.newInstance();if (lines.length > 1) {for (int i = 1; i < lines.length; i++) {String[] fv = lines[i].split("=");if (fv.length != 2) {throw new IllegalArgumentException(lines[i]);}Field f = cls.getDeclaredField(fv[0]);if(!f.isAccessible()){f.setAccessible(true);}setFieldValue(f, obj, fv[1]);}}return obj;} catch (Exception e) {throw new RuntimeException(e);} }

它調(diào)用了setFieldValue方法對(duì)字段設(shè)置值,其代碼為:

private static void setFieldValue(Field f, Object obj, String value) throws Exception {Class<?> type = f.getType();if (type == int.class) {f.setInt(obj, Integer.parseInt(value));} else if (type == byte.class) {f.setByte(obj, Byte.parseByte(value));} else if (type == short.class) {f.setShort(obj, Short.parseShort(value));} else if (type == long.class) {f.setLong(obj, Long.parseLong(value));} else if (type == float.class) {f.setFloat(obj, Float.parseFloat(value));} else if (type == double.class) {f.setDouble(obj, Double.parseDouble(value));} else if (type == char.class) {f.setChar(obj, value.charAt(0));} else if (type == boolean.class) {f.setBoolean(obj, Boolean.parseBoolean(value));} else if (type == String.class) {f.set(obj, value);} else {Constructor<?> ctor = type.getConstructor(new Class[] { String.class });f.set(obj, ctor.newInstance(value));} }

setFieldValue根據(jù)字段的類(lèi)型,將字符串形式的值轉(zhuǎn)換為了對(duì)應(yīng)類(lèi)型的值,對(duì)于基本類(lèi)型和String以外的類(lèi)型,它假定該類(lèi)型有一個(gè)以String類(lèi)型為參數(shù)的構(gòu)造方法。

反射與泛型

在介紹泛型的時(shí)候,我們提到,泛型參數(shù)在運(yùn)行時(shí)會(huì)被擦除,這里,我們需要補(bǔ)充一下,在類(lèi)信息Class中依然有關(guān)于泛型的一些信息,可以通過(guò)反射得到,泛型涉及到一些更多的方法和類(lèi),上面的介紹中進(jìn)行了忽略,這里簡(jiǎn)要補(bǔ)充下。

Class有如下方法,可以獲取類(lèi)的泛型參數(shù)信息:

public TypeVariable<Class<T>>[] getTypeParameters()

Field有如下方法:

public Type getGenericType()

Method有如下方法:

public Type getGenericReturnType() public Type[] getGenericParameterTypes() public Type[] getGenericExceptionTypes()

Constructor有如下方法:

public Type[] getGenericParameterTypes()

Type是一個(gè)接口,Class實(shí)現(xiàn)了Type,Type的其他子接口還有:

  • TypeVariable:類(lèi)型參數(shù),可以有上界,比如:T extends Number
  • ParameterizedType:參數(shù)化的類(lèi)型,有原始類(lèi)型和具體的類(lèi)型參數(shù),比如:List<String>?
  • WildcardType:通配符類(lèi)型,比如:?, ? extends Number, ? super Integer

我們看一個(gè)簡(jiǎn)單的示例:

public class GenericDemo {static class GenericTest<U extends Comparable<U>, V> {U u;V v;List<String> list;public U test(List<? extends Number> numbers) {return null;}}public static void main(String[] args) throws Exception {Class<?> cls = GenericTest.class;// 類(lèi)的類(lèi)型參數(shù)for (TypeVariable t : cls.getTypeParameters()) {System.out.println(t.getName() + " extends " + Arrays.toString(t.getBounds()));}// 字段 - 泛型類(lèi)型Field fu = cls.getDeclaredField("u");System.out.println(fu.getGenericType());// 字段 - 參數(shù)化的類(lèi)型Field flist = cls.getDeclaredField("list");Type listType = flist.getGenericType();if (listType instanceof ParameterizedType) {ParameterizedType pType = (ParameterizedType) listType;System.out.println("raw type: " + pType.getRawType() + ",type arguments:"+ Arrays.toString(pType.getActualTypeArguments()));}// 方法的泛型參數(shù)Method m = cls.getMethod("test", new Class[] { List.class });for (Type t : m.getGenericParameterTypes()) {System.out.println(t);}} }

程序的輸出為:

U extends [java.lang.Comparable<U>] V extends [class java.lang.Object] U raw type: interface java.util.List,type arguments:[class java.lang.String] java.util.List<? extends java.lang.Number>

代碼比較簡(jiǎn)單,我們就不贅述了。

慎用反射

反射雖然是靈活的,但一般情況下,并不是我們優(yōu)先建議的,主要原因是:

  • 反射更容易出現(xiàn)運(yùn)行時(shí)錯(cuò)誤,使用顯式的類(lèi)和接口,編譯器能幫我們做類(lèi)型檢查,減少錯(cuò)誤,但使用反射,類(lèi)型是運(yùn)行時(shí)才知道的,編譯器無(wú)能為力
  • 反射的性能要低一些,在訪問(wèn)字段、調(diào)用方法前,反射先要查找對(duì)應(yīng)的Field/Method,性能要慢一些

簡(jiǎn)單的說(shuō),如果能用接口實(shí)現(xiàn)同樣的靈活性,就不要使用反射。

小結(jié)

本節(jié)介紹了Java中反射相關(guān)的主要類(lèi)和方法,通過(guò)入口類(lèi)Class,可以訪問(wèn)類(lèi)的各種信息,如字段、方法、構(gòu)造方法、父類(lèi)、接口、泛型信息等,也可以創(chuàng)建和操作對(duì)象,調(diào)用方法等,利用這些方法,可以編寫(xiě)通用的、動(dòng)態(tài)靈活的程序,本節(jié)演示了一個(gè)簡(jiǎn)單的通用序列化/反序列化類(lèi)SimpleMapper。反射雖然是靈活通用的,但它更容易出現(xiàn)運(yùn)行時(shí)錯(cuò)誤,所以,能用接口代替的時(shí)候,應(yīng)該盡量使用接口。

本節(jié)介紹的很多類(lèi)如Class/Field/Method/Constructor都可以有注解,注解到底是什么呢?

(與其他章節(jié)一樣,本節(jié)所有代碼位于 https://github.com/swiftma/program-logic,位于包shuo.laoma.dynamic.c84下)

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

未完待續(xù),查看最新文章,敬請(qǐng)關(guān)注微信公眾號(hào)“老馬說(shuō)編程”(掃描下方二維碼),從入門(mén)到高級(jí),深入淺出,老馬和你一起探索Java編程及計(jì)算機(jī)技術(shù)的本質(zhì)。用心原創(chuàng),保留所有版權(quán)。

總結(jié)

以上是生活随笔為你收集整理的Java编程的逻辑 (84) - 反射的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。

亚洲精品国产欧美在线观看 | 91九色视频在线播放 | 九九免费精品视频在线观看 | 97av视频在线观看 | 国产精品96久久久久久吹潮 | 91精品爽啪蜜夜国产在线播放 | www.五月婷婷| 中国精品少妇 | 亚洲精品玖玖玖av在线看 | 一区二区三区三区在线 | 日韩一区在线播放 | 少妇精品久久久一区二区免费 | 丁香六月色 | 在线亚洲午夜片av大片 | 色天堂在线视频 | 国产精品一区二区三区久久 | 日本久久久久久 | 在线电影播放 | 国产精品一区二区三区四 | 玖玖国产精品视频 | 免费在线观看a v | 美女视频黄色免费 | 国外成人在线视频网站 | 亚洲精品国产成人av在线 | 亚洲国产精品成人综合 | 久久久九色精品国产一区二区三区 | 欧美一区二区日韩一区二区 | 亚洲欧洲日韩在线观看 | 日韩av不卡在线观看 | 国产专区在线看 | 波多野结衣在线观看一区 | 99九九99九九九视频精品 | 国产日韩精品一区二区三区 | 国产免费中文字幕 | 午夜视频二区 | 能在线观看的日韩av | 欧美在线不卡一区 | 性色av免费在线观看 | 国产精品视频 | 久久精品国产亚洲aⅴ | 99久高清在线观看视频99精品热在线观看视频 | 成人丝袜 | 亚洲va欧美va人人爽 | 亚洲天天摸日日摸天天欢 | 免费a级黄色毛片 | 97国产精品久久 | 97视频免费 | 女人18毛片a级毛片一区二区 | 中文字幕a在线 | 96久久欧美麻豆网站 | 91精品视频在线看 | 国产精品999久久久 久产久精国产品 | 一区二区不卡高清 | 五月激情丁香婷婷 | 丁香九月婷婷 | 亚洲国内精品在线 | 久久久成人精品 | 免费看一级黄色 | 免费福利片2019潦草影视午夜 | 欧美日韩视频免费看 | 色吊丝在线永久观看最新版本 | 麻花豆传媒mv在线观看网站 | 亚洲黄色app | 性色av免费看 | 日韩欧美99 | 香蕉视频日本 | 国产一级片免费视频 | 国产精品免费人成网站 | 精品久久1 | 免费看亚洲毛片 | 一区二区三区在线视频观看58 | 日韩二区在线观看 | 成全免费观看视频 | 精品免费久久久久 | 婷婷亚洲综合 | 四虎国产精品成人免费影视 | 香蕉在线播放 | 欧美成人xxxxx | 国产亚洲视频系列 | 亚洲色图色| 色婷婷婷 | 精品久久久久久亚洲综合网站 | 中文字幕在线观看一区 | 国产精品美女在线观看 | 日韩理论视频 | 久久精品999| 国产成人精品亚洲日本在线观看 | 日韩精品久久一区二区三区 | 又爽又黄又无遮挡网站动态图 | 亚洲精品一区二区18漫画 | 69av久久| 在线观看日韩专区 | 97超碰人 | 五月婷婷激情综合 | 在线黄色免费av | 久久综合偷偷噜噜噜色 | 美女免费视频一区 | 超碰成人免费电影 | 免费日韩一级片 | 99免费在线播放99久久免费 | 久草电影在线观看 | 天天爱天天舔 | 国产无区一区二区三麻豆 | 日韩av进入 | 亚洲 欧美 国产 va在线影院 | 亚洲伊人成综合网 | 一级黄色大片 | 欧美黄在线 | 久草在线资源观看 | 成人久久久精品国产乱码一区二区 | 国产精品久久久99 | 999视频网 | 国产黄色免费看 | 黄色片网站av | 中文字幕在线播放av | 99久久er热在这里只有精品66 | 精品欧美乱码久久久久久 | 国产亚洲va综合人人澡精品 | 欧美性做爰猛烈叫床潮 | 人人网av | 蜜臀久久99精品久久久酒店新书 | 亚洲色图22p | 香蕉视频在线视频 | 国产精品精品久久久 | 中文字幕在线观看你懂的 | 97视频资源 | 国产一区视频在线播放 | 国产精品 国产精品 | 99热在线精品观看 | 免费观看一级视频 | 性色大片在线观看 | 国产三级在线播放 | 亚洲免费在线播放视频 | 天天操天天是 | 免费男女网站 | 中文字幕在线不卡国产视频 | 久久久黄视频 | 欧美精品在线一区二区 | 久久国产品 | 色婷婷骚婷婷 | 国产免费观看高清完整版 | 久久观看 | 在线播放91 | 日韩一区二区免费视频 | 99九九热只有国产精品 | 亚洲黄色av| 干干日日 | 草久久精品 | 免费网站看v片在线a | 亚洲伊人av | 91精品人成在线观看 | 国产一区二区在线看 | 99久精品视频 | 欧美国产日韩在线视频 | 日韩午夜高清 | 国产高h视频 | 精品国产成人在线 | 国产又粗又猛又爽 | 狠狠干狠狠艹 | 亚洲精品国产麻豆 | 国产中文字幕亚洲 | 99热这里只有精品1 av中文字幕日韩 | 欧美一区二区视频97 | 久久的色 | 黄色软件视频大全免费下载 | 极品久久久久 | 色欧美成人精品a∨在线观看 | 狠狠躁夜夜躁人人爽超碰97香蕉 | 久精品视频 | 欧美日韩一区二区免费在线观看 | 欧美福利片在线观看 | 成人蜜桃网 | 狠狠躁日日躁狂躁夜夜躁av | 黄色的片子 | 99精品欧美一区二区蜜桃免费 | 国产小视频免费在线观看 | adc在线观看 | 国产一级片毛片 | 69国产在线观看 | 国产成人在线观看免费 | 97影视| 丁香久久五月 | 色多视频在线观看 | 黄色av播放 | 丁香影院在线 | 天天综合五月天 | 国产精品一区二区三区在线播放 | 国产剧情在线一区 | 成人黄色电影在线观看 | 狠狠干天天干 | 日韩欧美在线视频一区二区三区 | 久草精品视频在线看网站免费 | 欧美在线视频一区二区 | 欧美午夜性 | 国产精品久久二区 | 国产精品中文字幕在线观看 | 亚洲国产999 | 成人网444ppp | 99热国产在线观看 | 国产精品一区二区三区在线 | 精品久久一区 | 日韩丝袜在线观看 | 97精品免费视频 | 国产精品久久久久久模特 | 99999精品 | 久产久精国产品 | 国产在线国偷精品产拍 | 国产精品99久久久久久久久久久久 | 97超碰色偷偷 | 五月婷婷影视 | 色综合天天| 亚洲精品美女在线 | 五月宗合网 | 一本一本久久aa综合精品 | 最近av在线| 免费看的黄色录像 | 日韩影片在线观看 | 欧美日韩一区二区三区视频 | 热久久在线视频 | 国产成人三级三级三级97 | 亚洲美女视频在线观看 | 欧美极品少妇xbxb性爽爽视频 | 97超碰人人澡人人 | 日韩资源在线播放 | av在线网站大全 | 亚洲成人av电影 | 亚洲黄色av| 亚洲综合成人专区片 | 天天干天天摸天天操 | 美女网站视频久久 | 久久亚洲人 | 日韩精品短视频 | 精品视频免费 | 91av在线播放视频 | 韩日电影在线观看 | 在线观看电影av | 久久人人爽人人爽人人片 | 成人黄色短片 | www久| 91av精品| 亚洲影院天堂 | 国产亚洲成av片在线观看 | 久久狠狠亚洲综合 | 久久视频精品在线 | 亚洲春色综合另类校园电影 | 中文字幕第一 | 日本mv大片欧洲mv大片 | 天天爱天天草 | 婷婷色中文网 | 91色偷偷 | 日韩大陆欧美高清视频区 | 久久视频这里只有精品 | av一级久久| 中文字幕丝袜 | 亚洲 成人 欧美 | 久久久在线观看 | 精品电影一区二区 | 国产精品久久久久久久久久久久午 | 国产一区视频免费在线观看 | 日韩毛片精品 | 天天操比 | 亚洲精品国产精品乱码在线观看 | 九九九视频精品 | 亚洲精品视频在线免费 | 色婷婷 亚洲 | 国产精品18久久久久久不卡孕妇 | 91福利视频免费 | 亚洲精品一区二区精华 | 欧美一级性生活 | 天堂av在线免费 | 久久久九色精品国产一区二区三区 | 久久免费视频精品 | 五月婷婷狠狠 | 欧美日韩免费网站 | 最新av观看 | 国产视频999| 精品久久精品久久 | 一级性生活片 | 久久久综合九色合综国产精品 | 免费99视频| 97视频在线 | 又黄又刺激视频 | 午夜国产一区二区 | 国产麻豆精品一区 | 亚洲永久精品在线 | 色综合色综合久久综合频道88 | 国产91综合一区在线观看 | 激情视频亚洲 | 国产精品一区二区白浆 | 2023av在线| jizz18欧美18 | 亚洲 中文 在线 精品 | 丁香五月缴情综合网 | 九九热视频在线播放 | 91成人精品一区在线播放69 | 久草资源在线观看 | 成人av在线亚洲 | 91亚洲网 | 91精品中文字幕 | 国产精品一区二区果冻传媒 | 麻豆视频免费看 | 日韩网站在线免费观看 | 国产成人综合在线观看 | a级片韩国 | 黄色免费电影网站 | 国产精品18久久久久久不卡孕妇 | 97理论电影| 久久国产精品精品国产色婷婷 | 色综合天天做天天爱 | 91亚洲精品在线 | 久久精品久久99精品久久 | 成人羞羞视频在线观看免费 | 免费一级毛毛片 | 国产二区视频在线观看 | 久久精品99视频 | 九九久久电影 | 伊人天天 | 国产视频中文字幕 | h视频日本 | 日本视频不卡 | 九九热中文字幕 | 日韩一二三区不卡 | 久久成人麻豆午夜电影 | 探花视频在线观看免费版 | 中文字幕国语官网在线视频 | 国产精品破处视频 | 日本韩国精品在线 | 天天躁日日躁狠狠躁 | 亚洲理论电影网 | av高清一区二区三区 | 狠狠色丁香久久婷婷综合_中 | 黄色在线成人 | 黄色软件视频网站 | 久草在线资源观看 | av网站在线观看免费 | 91成人区 | 超碰免费av | 蜜桃视频在线视频 | 天天摸夜夜添 | 婷婷综合激情 | 九色福利视频 | 国产精品亚洲综合久久 | 色黄久久久久久 | 中午字幕在线观看 | 亚洲精品日韩在线观看 | av中文字幕av| 久久久黄色av| 国产亚洲在线观看 | 国产一级二级三级视频 | 首页国产精品 | 免费看的黄色 | 久久婷五月 | 欧美日韩精品免费观看视频 | 一区二区 不卡 | www九九热 | 久久久国产精品一区二区中文 | 一区免费观看 | 97国产在线视频 | 少妇18xxxx性xxxx片 | 天天操天天操天天操天天操天天操 | 婷婷久久综合九色综合 | 亚洲国产片色 | 亚洲精品www久久久 www国产精品com | 国产精品成人一区二区 | 国产成人精品一区二区三区 | 日韩三级视频在线观看 | 欧美乱熟臀69xxxxxx | 国产精品99久久久精品免费观看 | 91成人在线免费观看 | 全黄色一级片 | 色爽网站 | 激情综合狠狠 | 操高跟美女 | 亚洲精品乱码 | 免费成人在线电影 | 麻豆视频免费在线播放 | 色就干| 国产精品毛片一区视频播不卡 | av免费电影在线观看 | 国产在线观看国语版免费 | 国产精品99精品 | 国产精品美女久久久网av | 最新超碰在线 | 国产黄色理论片 | 夜夜操天天干 | 欧美日韩一区二区三区免费视频 | 天天插伊人 | 中文字幕国产在线 | 欧美精品久久久久久久久老牛影院 | 国产精品久久久久久久久免费看 | 国产在线观看二区 | 超碰97在线人人 | 香蕉视频久久 | 国产1区2区3区在线 亚洲自拍偷拍色图 | 在线成人免费 | 久久综合久久综合九色 | 久久免费激情视频 | 亚洲黄色在线免费观看 | 绯色av一区 | 香蕉视频网站在线观看 | 国产精品九九九九九 | 午夜视频一区二区三区 | 日韩影视大全 | 5月丁香婷婷综合 | 国产视频在线免费 | 天天干一干 | 欧美成a人片在线观看久 | 亚洲精品日韩一区二区电影 | aaawww| 91免费高清观看 | 日本中文字幕在线免费观看 | 国产成人高清在线 | 婷婷新五月 | 天天艹 | 国产色区| 中文字幕在线成人 | 国产不卡一 | 激情欧美网| 插综合网 | 国产午夜精品理论片在线 | 久久久久欧美精品999 | 国产精品美女久久久久久久 | 欧美日韩视频在线播放 | 夜夜躁狠狠躁日日躁 | 国内精品99 | 亚洲成人国产精品 | 欧美夫妻生活视频 | 91久久爱热色涩涩 | 日韩免费中文 | 中文字幕一区二区三区乱码在线 | 特级a毛片 | 成人久久综合 | 国产精品一区二区免费看 | www国产在线 | 国产精品久久久久久久7电影 | 免费大片黄在线 | 亚洲黄色高清 | 国产精品一区二区三区久久 | 91在线免费看片 | 91污污| 久久九九九九 | 中文字幕精品一区 | 国产一区二区精品在线 | 久久久久女教师免费一区 | 精品1区2区3区 | 国产色拍 | 免费午夜av | 亚洲欧洲国产视频 | 久热久草在线 | 99久久er热在这里只有精品15 | 国产一二区在线观看 | 成人理论在线观看 | 黄色av电影一级片 | 亚洲少妇自拍 | 天堂av在线网址 | www久| 精品国产乱码一区二区三区在线 | 韩国精品一区二区三区六区色诱 | 99精品视频在线 | 久久久精品国产一区二区三区 | 日批视频在线 | 又黄又爽免费视频 | 99久久99视频只有精品 | 97成人在线观看 | 国产色爽 | 成年人在线免费看视频 | 91粉色视频| 亚洲 综合 国产 精品 | 色资源在线 | 97人人爽人人 | 日本精品一区二区三区在线播放视频 | 国产精品久久久久久久久久久久久久 | 天天色天天操天天爽 | 国产99久久久精品 | 国产一区二区三精品久久久无广告 | 久久免费视频6 | 久久久久久久久久久久亚洲 | 日韩精品一区二区三区免费观看视频 | 中文在线免费一区三区 | 久久免费高清视频 | 国产精品久久久久久久久免费 | 午夜视频在线观看一区二区 | 永久免费在线 | 国产黄a三级三级三级三级三级 | 日韩在线观看视频在线 | 在线观看国产麻豆 | 91福利视频久久久久 | 在线观看成人一级片 | 日本精品在线看 | 黄色片视频在线观看 | 国产精品久久久久久久午夜 | 国产中文欧美日韩在线 | 2021国产在线视频 | 中文字幕在线资源 | 久久综合狠狠综合 | 青青河边草免费观看 | 国产高清不卡 | 91高清视频免费 | 日韩在线中文字幕 | 91麻豆国产福利在线观看 | 黄色在线看网站 | 永久免费视频国产 | 欧美日本高清视频 | 免费黄色在线 | 欧美日韩久久一区 | 五月婷婷综合激情网 | 欧美日韩国产一二三区 | 91成人精品一区在线播放69 | 日韩视频a| 黄色在线视频网址 | 欧美久久综合 | 麻豆av电影 | 超碰在线日韩 | 国产精品一区二区久久久 | 欧美狠狠操 | 免费视频在线观看网站 | 亚洲午夜久久久久 | 蜜臀av网站 | 狠狠地日| 91在线小视频 | 国产黄a三级三级三级三级三级 | 国产精品久久99综合免费观看尤物 | www在线观看国产 | 99精品久久久 | 精品九九九 | 日韩免费在线观看视频 | 久久99精品久久久久蜜臀 | 亚洲黄色在线观看 | 欧美在线一 | 久久综合五月天 | 夜夜夜夜爽 | 亚州国产精品久久久 | 成年人免费在线观看 | 激情婷婷综合网 | 中文字幕精品久久 | 超碰激情在线 | 天天操夜夜叫 | 麻豆视频国产精品 | 超碰在线色| 国产精品黄色 | 国产资源网站 | 在线 高清 中文字幕 | 亚洲视频资源在线 | 欧美成人精品三级在线观看播放 | 国产97免费 | 色九九影院 | av电影中文字幕 | 视频在线观看91 | 丁香激情视频 | 国产成人免费av电影 | 国产午夜精品一区二区三区欧美 | 成人网页在线免费观看 | 国产精品久久久久永久免费观看 | 夜夜躁狠狠躁日日躁 | 美女网站一区 | 久久精品久久精品 | 国产视频一区二区在线播放 | 婷婷中文字幕 | 中文字幕视频一区 | 在线播放精品一区二区三区 | 久久精品三级 | 午夜色大片在线观看 | 久久99久久99精品免观看软件 | 麻豆国产在线播放 | 久久小视频 | 精品一区二区三区香蕉蜜桃 | 国产韩国精品一区二区三区 | 啪啪凸凸| 91丨精品丨蝌蚪丨白丝jk | 夜夜爽88888免费视频4848 | 婷婷综合电影 | 日韩电影在线观看一区二区三区 | 日韩免费一区二区三区 | 久久人人97超碰国产公开结果 | 狠狠色丁香久久婷婷综合五月 | 91在线视频观看 | 欧美一级片免费观看 | 亚洲午夜在线视频 | 国产成人精品一区二区三区在线观看 | 国产精品永久免费视频 | a视频在线观看免费 | 日韩在线不卡视频 | 国内精品毛片 | 男女全黄一级一级高潮免费看 | 久久国产综合视频 | 免费色网站 | 91成人久久| 国产日产欧美在线观看 | av中文字幕在线播放 | 天天干天天综合 | 久久99精品国产 | 久久久久久久久久久网站 | 97超碰成人在线 | 在线有码中文 | 精品国产伦一区二区三区 | 91九色porn在线资源 | 一区二区三区免费 | 日韩欧美视频免费在线观看 | 免费的国产精品 | 在线视频 91 | 国产色小视频 | 国产在线免费 | 九九在线视频 | 伊人六月 | 精品久久一区二区 | 久国产在线播放 | 亚洲欧美综合精品久久成人 | 欧美一级特黄高清视频 | av中文天堂 | 色婷婷成人网 | 激情开心站| 在线欧美最极品的av | 国产欧美精品在线观看 | 97超碰资源站 | 亚洲精品网址在线观看 | 欧美韩国日本在线 | 精品久久精品久久 | 国产色婷婷精品综合在线手机播放 | 久久99精品国产麻豆宅宅 | 国产精品一区二区你懂的 | 欧美一二三四在线 | 91精品免费在线视频 | 国产亚洲成人精品 | 福利区在线观看 | 狠狠色丁香婷婷综合最新地址 | 日本黄网站 | 国产一级片不卡 | 99热亚洲精品 | 五月天婷婷视频 | 天天射天天射天天射 | 五月激情综合婷婷 | 欧美日韩国产在线精品 | 成人在线观看影院 | 午夜免费在线观看 | 成人免费视频在线观看 | 麻豆国产网站入口 | 色偷偷88888欧美精品久久久 | 日本成人中文字幕在线观看 | 成年美女黄网站色大片免费看 | 欧美性生活免费 | 欧美日韩一区二区在线观看 | 日韩精品一区二区三区中文字幕 | 亚洲高清视频在线播放 | 欧美视频一区二 | 久久99国产精品免费 | 精品一区二区免费 | 久久人人97超碰精品888 | www视频在线免费观看 | 九九综合九九 | 丁香六月婷婷激情 | 天天综合网 天天综合色 | 亚洲成a人片在线观看网站口工 | av在线超碰 | 国产精品嫩草影院99网站 | 天天艹 | 久久成年人 | 国产亚洲成av人片在线观看桃 | 国产喷水在线 | 一级黄色电影网站 | 一级久久久 | 久久久久久久久久久福利 | 四虎在线免费观看 | 99久热在线精品视频成人一区 | 欧美精品久久久 | 狠狠躁夜夜躁人人爽超碰97香蕉 | 国产精品热视频 | 国产特级毛片aaaaaaa高清 | 夜夜骑日日 | 99久久精品免费看国产麻豆 | 中字幕视频在线永久在线观看免费 | 国产自在线 | 亚洲色综合 | 91在线文字幕| 欧美性视频网站 | 婷婷丁香自拍 | 天天干天天草天天爽 | 激情久久久久久久久久久久久久久久 | 激情网综合 | 国产成人精品一区二区三区网站观看 | 国产一区二区三区高清播放 | 九九热久久免费视频 | 国产视频丨精品|在线观看 国产精品久久久久久久久久久久午夜 | 在线免费观看涩涩 | 天天操天天射天天操 | 一区二区av | 99久久www| 亚洲综合色av | 国产精品美女在线观看 | 高潮毛片无遮挡高清免费 | 在线免费观看亚洲视频 | 超碰在线公开免费 | 国产精品久久久精品 | 亚洲更新最快 | 国内精品久久久久久中文字幕 | 日韩欧美在线综合网 | 日韩免费福利 | 日本中文字幕在线一区 | 91麻豆看国产在线紧急地址 | 97色在线视频 | 在线免费黄色 | 青草视频在线免费 | 中文字幕在线播放视频 | 国产二区视频在线 | 久草视频在线新免费 | 黄影院| 久久久久国产精品一区二区 | 国产精品毛片久久久久久久久久99999999 | 国产成人精品女人久久久 | 999ZYZ玖玖资源站永久 | 国产精品免费麻豆入口 | 国产一区二区在线影院 | 亚洲乱码精品久久久 | 欧美日韩国产一二三区 | 玖玖爱国产在线 | 精一区二区| 高清av在线 | 亚洲精品人人 | 日韩欧美高清不卡 | 日本超碰在线 | 国产精品久久久久免费a∨ 欧美一级性生活片 | 美女黄视频免费 | 亚洲午夜精品久久久 | 国产精品网红福利 | 人人草人 | 亚洲人xxx| 日韩在线视频观看 | 欧美日韩免费观看一区二区三区 | 激情开心网站 | 日韩一级黄色片 | 天天草天天 | 国产一级黄色免费看 | 国产成人久 | 欧美性直播 | 亚洲欧洲精品在线 | 久久黄色小说 | 超碰在线97免费 | 亚洲精品乱码久久久久v最新版 | 欧美 日韩 性 | 91九色在线 | 天海翼一区二区三区免费 | 精品久久久久久久久久久久久久久久久久 | 久久久久久久久久久福利 | 欧美日韩一级视频 | 亚洲三级黄色 | 97超碰在线久草超碰在线观看 | 五月婷在线视频 | 久久精品96 | 久久久免费在线观看 | 国产精品123 | 中文字幕中文 | 国产手机视频在线播放 | 国产香蕉97碰碰碰视频在线观看 | 国产99久| 去干成人网 | 国产麻豆精品久久一二三 | 久久精品香蕉视频 | 中文字幕高清在线 | 欧美午夜a | 日韩免费av网址 | 911久久| 狂野欧美激情性xxxx欧美 | 精品国产午夜 | 手机在线看永久av片免费 | 国产精品成人久久久久久久 | 色噜噜狠狠狠狠色综合久不 | 激情婷婷久久 | 久草在线资源网 | 精品国产一区二区三区久久久蜜臀 | 久久国产成人午夜av影院潦草 | av高清影院| av中文资源在线 | 国产精品久久久久一区二区三区共 | 成人av片在线观看 | 国产精品免费观看网站 | 色av网站| 国产一级免费在线 | 91看片淫黄大片在线播放 | 99福利影院| 国产视频在线观看免费 | 人人爽人人香蕉 | 中文字幕在线视频一区 | 高清美女视频 | 麻豆91精品视频 | 欧美国产日韩激情 | 久久99偷拍视频 | 欧美男男激情videos | 久久免费中文视频 | 欧美巨大 | 亚洲永久精品国产 | 综合久久五月天 | 国产精品久久久久四虎 | 日韩精品视频在线免费观看 | 欧美动漫一区二区三区 | 国产成人精品一区在线 | 日韩免费在线视频 | 国产免费不卡 | 欧美va天堂在线电影 | 国产精品毛片久久 | 成人av教育 | 国产中文字幕一区 | 91看国产| 麻豆91在线观看 | 欧美福利网址 | 中文字幕无吗 | 一区二区欧美激情 | 97干com| 亚洲区另类春色综合小说 | 日韩成人黄色 | 久久国产精品系列 | 亚洲综合色视频在线观看 | 免费看片成年人 | 中文字幕 欧美性 | 日韩在线免费看 | 91福利视频免费 | 高清av在线免费观看 | 黄污污网站 | 久久激情日本aⅴ | 精品久久福利 | 日韩精品一区二区免费视频 | 九九九免费视频 | 亚洲午夜在线视频 | 国产成在线观看免费视频 | 日韩欧美久久 | 午夜精品一区二区三区免费 | 人人爽人人av | 国产 成人 久久 | 国产高清在线免费观看 | 久久99热国产| 久久精品91久久久久久再现 | 偷拍精偷拍精品欧洲亚洲网站 | 日韩精品极品视频 | 日韩av片无码一区二区不卡电影 | 亚洲精选久久 | 国产99久久九九精品免费 | 日本黄色免费在线 | 91精品国自产在线 | 欧美一区二区精品在线 | 国模视频一区二区三区 | 久热久草| 在线有码中文字幕 | 国产视频 亚洲精品 | 欧美在线一| 特黄色大片| 中文字幕在线播放日韩 | 免费a级观看 | 天天干婷婷| 亚洲九九九在线观看 | 人交video另类hd | 又长又大又黑又粗欧美 | 日韩大片在线看 | 又长又大又黑又粗欧美 | 国产色综合 | 精品网站999www | 视频1区2区 | 精品福利在线视频 | 久久久久久国产精品 | 日本黄色黄网站 | 国产精品一区二区三区99 | 色综合天天视频在线观看 | 国产日韩视频在线观看 | 深爱婷婷激情 | 一区二区视频在线免费观看 | 在线观看91精品视频 | 中文字幕欧美激情 | 中文字幕久久亚洲 | 久久婷婷开心 | 欧美日韩精品影院 | 亚洲aⅴ乱码精品成人区 | 美女久久久久久久久久 | 免费看黄在线观看 | 黄色影院在线观看 | 国产欧美在线一区 | 久久99久国产精品黄毛片入口 | 国产精品原创av片国产免费 | 国产亚洲小视频 | 亚洲国产精品500在线观看 | 又湿又紧又大又爽a视频国产 | 国产一区二区三区在线免费观看 | .精品久久久麻豆国产精品 亚洲va欧美 | 亚洲一区二区三区毛片 | 91大片网站 | 亚洲精品国产第一综合99久久 | 人人精久| 日韩久久一区 | 亚洲男人天堂a | 成人黄色片在线播放 | 国产在线观看地址 | 97小视频 | 国产黄色在线 | 亚洲精品国产精品99久久 | 精品国产一区二区三区久久久 | 黄色毛片网站在线观看 | 日韩影视在线观看 | 国产精品成人aaaaa网站 | 精品自拍sae8—视频 | www.亚洲精品视频 | 69av免费视频 | 久久久久日本精品一区二区三区 | av在线免费不卡 | 韩日色视频 | 国产一区成人在线 | 免费男女羞羞的视频网站中文字幕 | 超碰官网| 日韩免费三区 | 亚洲日本va午夜在线影院 | 天天色综合久久 | 综合色播| 天天做天天射 | 久久久久久久久久久高潮一区二区 | 欧洲精品亚洲精品 | 国产精品女人久久久 | 久久久亚洲麻豆日韩精品一区三区 | 欧美一区成人 | 国产色在线 | 美女性爽视频国产免费app | 一本一本久久a久久精品牛牛影视 | 欧美最爽乱淫视频播放 | 国产中文字幕在线免费观看 | 精品久久久久久久久久久久久久久久久久 | 久久久激情网 | av一级片在线观看 | 亚洲美女精品 | 人人超碰免费 | 精品无人国产偷自产在线 | 最近中文字幕高清字幕免费mv | 日韩欧美视频二区 | 国产精品久久久久久久av大片 | av超碰在线| a视频免费在线观看 | 久久情侣偷拍 | av亚洲产国偷v产偷v自拍小说 | 五月天六月婷婷 | 国产97免费 | 欧美日韩二区三区 | 久久夜色精品国产亚洲aⅴ 91chinesexxx | 国产精品免费视频一区二区 | 色婷五月天 | 91精品在线麻豆 | 国产精品自产拍在线观看蜜 | 天天操天天射天天添 | 婷婷久月 | 日韩在线一级 | 婷婷色在线观看 | 亚洲最大成人网4388xx | 日韩网站免费观看 | 一级片黄色片网站 | 亚洲三级性片 | 久久精品在线 | 日韩r级电影在线观看 | 69国产精品视频 | 国产一区国产精品 | 视频在线观看亚洲 | 成人精品亚洲 | av在线免费观看不卡 | 久久99精品久久久久久秒播蜜臀 | 精品国产电影 | 2017狠狠干| 亚洲精品在线一区二区三区 | 精品国产精品一区二区夜夜嗨 | 激情电影影院 | 成人免费中文字幕 | 91成人免费视频 | 天天干亚洲| 欧美色图视频一区 | 欧美色图东方 | 色综合亚洲精品激情狠狠 | 天天干天天干天天射 | 欧美日韩一区二区视频在线观看 | 久久爽久久爽久久av东京爽 | 日韩精品在线一区 | 欧美日韩国产精品一区二区三区 | 亚洲精品一区二区三区高潮 | 又湿又紧又大又爽a视频国产 | 91毛片在线观看 | 麻豆高清免费国产一区 | 天天艹| 久久久国产精品亚洲一区 | 一区二区三区四区五区在线视频 | 婷婷中文字幕在线观看 | 国产探花视频在线播放 | 久久成人久久 | 日本视频精品 | 日本精品视频在线观看 | 黄网站色成年免费观看 | 色是在线视频 | 黄色软件网站在线观看 | 久久久久日本精品一区二区三区 | 成人免费精品 | 午夜私人影院 | 99国产成+人+综合+亚洲 欧美 | 日韩videos| 中文字幕中文字幕在线中文字幕三区 | 国产精品久久久久久久久费观看 | 99久久综合精品五月天 | 天天插综合 | 麻豆影视在线观看 | 久久美女视频 | 久久高清国产视频 |