在线观看www成人影院-在线观看www日本免费网站-在线观看www视频-在线观看操-欧美18在线-欧美1级

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

Java反射機制到底是什么?有什么作用

Wildesbeast ? 來源:今日頭條 ? 作者:程序猿的內心獨白 ? 2020-02-15 14:07 ? 次閱讀

什么是Java反射機制?

Java反射機制是 Java 語言的一個重要特性,它在服務器程序和中間件程序中得到了廣泛運用。在服務器端,往往需要根據客戶的請求,動態(tài)調用某一個對象的特定方法。此外,在 ORM 中間件的實現中,運用 Java 反射機制可以讀取任意一個 JavaBean 的所有屬性,或者給這些屬性賦值

通過反射機制,可以在運行的時候訪問到對象的屬性、方法、構造方法等等

哪些地方用到反射機制?

其實我們都用過反射機制,只是并不知道它是反射機制而已。比如我們使用JDBC連接數據庫的時候(Class.forName() 這個相信大家都用過),只是當時并沒有在意那么多(心里想能用就行,管它呢),使用到反射機制的框架有(Spring、SpringMVC、Mybatis、Hibernate、Structs)

反射機制提供了哪些功能?

在運行時判定任意一個對象所屬的類

在運行時構造任意一個類的對象

在運行時判定任意一個類所具有的成員變量和方法

在運行時調用任意一個對象的方法

生成動態(tài)代理

如何實現反射機制?

先來個實體類 Student

/**

* @author Woo_home

* @create by 2019/12/10

*/

public class Student {

private int id;

private String name;

public Student(){}

public int getId() {

return id;

}

public void setId(int id) {

this.id = id;

}

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

@Override

public String toString() {

return "Student{" +

"id=" + id +

", name='" + name + ''' +

'}';

}

}

反射的三種實現方式

一、通過對象的getClass()方法

getClass()方法是Object類的方法,因為所有類都繼承自Object類,所以可以直接使用getClass()方法

public class ReflectDemo {

public static void main(String[] args) {

Student student = new Student();

Class studentClass = student.getClass();

System.out.println(studentClass);

}

}

二、通過類的.class屬性

直接獲取一個類的class

public class ReflectDemo {

public static void main(String[] args) {

Class studentClass = Student.class;

System.out.println(studentClass);

}

}

三、通過Class類的forName()方法(常用)

Class.forName() 是一個靜態(tài)方法

public class ReflectDemo {

public static void main(String[] args) {

// 使用 try、catch 處理異常

try {

Class studentClass = Class.forName("com.example.app.demo.Student");

System.out.println(studentClass);

}catch (ClassNotFoundException e){

e.printStackTrace();

}

}

}

public class ReflectDemo {

// 使用 throws 處理異常

public static void main(String[] args) throws ClassNotFoundException{

Class studentClass = Class.forName("com.example.app.demo.Student");

System.out.println(studentClass);

}

}

三種方法打印的結果都是一樣的,如下圖所示

注意: 這里的Class.forName()方法需要使用try、catch語句括住或者在方法或類中拋出ClassNotFoundException 異常,不然會報錯

有些人就問了,為什么需要使用try、catch語句括住呢,來看下forName方法源碼:

可以看到forName需要拋出一個 ClassNotFoundException 異常,自然而然地你使用forName()方法也自然要拋出 / 處理日常了

@CallerSensitive

public static Class forName(String className)

throws ClassNotFoundException {

Class caller = Reflection.getCallerClass();

return forName0(className, true, ClassLoader.getClassLoader(caller), caller);

}

判斷一個類是否為某個類的實例

1、instanceof

public class ReflectDemo {

public static void main(String[] args) {

HashMap map = new HashMap<>();

if (map instanceof Map){

System.out.println("HashMap is Map instance");

}

}

}

輸出:HashMap is Map instance

2、isInstance

public class ReflectDemo {

public static void main(String[] args) {

HashMap map = new HashMap<>();

if (Map.class.isInstance(map)){

System.out.println("HashMap is Map Instance");

}

}

}

輸出:HashMap is Map Instance

利用反射創(chuàng)建對象實例

1、通過Class對象的 newInstance() 方法

public class ReflectDemo {

public static void main(String[] args) throws IllegalAccessException, InstantiationException {

// 這里的Student是使用上面一開始的Student類

Class studentClass = Student.class;

// 使用newInstance創(chuàng)建實例

Student student = (Student)studentClass.newInstance();

student.setId(1);

student.setName("John");

System.out.println(student);

}

}

輸出:John

2、通過Constructor對象的 getConstructor() 方法

public class ReflectDemo {

public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {

Class classes = List.class;

Constructor constructor = classes.getConstructor(List.class);

List result = (List) constructor.newInstance("John");

System.out.println(result);

}

}

輸出:John

Field

根據字段名獲取字段(只能獲取public的)

public class ReflectDemo {

public static void main(String[] args) throws NoSuchFieldException {

Class classes = Student.class;

Field id = classes.getField("id");

Field name = classes.getField("name");

System.out.println(id);

System.out.println(name);

}

}

class Student{

public int id;

public String name;

}

輸出:

以下為輸出結果

public int com.example.app.demo.Student.id

public java.lang.String com.example.app.demo.Student.name

如果獲取的字段是被private修飾的,那么將會拋出 NoSuchFieldException 異常

以下為輸出結果

Exception in thread “main” java.lang.NoSuchFieldException: id

at java.lang.Class.getField(Class.java:1703)

at com.example.app.demo.ReflectDemo.main(ReflectDemo.java:12)

為什么會這樣呢?我們朝著這個問題看下源碼是怎么實現的

getField(String name)

根據名稱獲取公有的(public)類成員

@CallerSensitive

public Field getField(String name)

throws NoSuchFieldException, SecurityException {

checkMemberAccess(Member.PUBLIC, Reflection.getCallerClass(), true);

// 可以看到在getField傳入的name實際是調用getField0來實現的

Field field = getField0(name);

if (field == null) {

throw new NoSuchFieldException(name);

}

return field;

}

getField0(String name)

而getField0主要判斷依據是searchFields,searchFields根據privateGetDeclaredFields判斷

private Field getField0(String name) throws NoSuchFieldException {

Field res;

// Search declared public fields

if ((res = searchFields(privateGetDeclaredFields(true), name)) != null) {

return res;

}

// 省略部分代碼...

return null;

}

privateGetDeclaredFields(boolean publicOnly)

可以看到當privateGetDeclaredFields傳入的值是true的時候表示使用的是 declaredPublicFields ,也就是說是public聲明的字段,當傳入的值為false的時候使用的是 declaredFields(所有聲明字段)

private Field[] privateGetDeclaredFields(boolean publicOnly) {

checkInitted();

Field[] res;

ReflectionData rd = reflectionData();

if (rd != null) {

// 判斷輸入的布爾值是true還是false

res = publicOnly ? rd.declaredPublicFields : rd.declaredFields;

if (res != null) return res;

}

// 省略部分代碼...

return res;

}

getFields(String name)

獲取所有 public 修飾的字段

public class ReflectDemo {

public static void main(String[] args) throws NoSuchFieldException {

Class classes = Student.class;

Field[] allField = classes.getFields();

for (Field field : allField) {

System.out.println(field);

}

}

}

class Student{

private int id;

public String name;

}

輸出:

以下為輸出結果

public java.lang.String com.example.app.demo.Student.name

可以看到我們的Student類中聲明了一個private修飾的id和一個public修飾的name,根據輸出結果可以知道getFields()方法只能獲取public修飾的字段

看下實現源碼:

在getFields中返回了一個copyFields方法,該方法中調用了 privateGetPublicFields 方法

@CallerSensitive

public Field[] getFields() throws SecurityException {

checkMemberAccess(Member.PUBLIC, Reflection.getCallerClass(), true);

return copyFields(privateGetPublicFields(null));

}

來看下privateGetPublicFields方法可以知道在該方法中調用了 privateGetDeclaredFields(true) 這個方法,關于這個方法上面已經講述過

private Field[] privateGetPublicFields(Set> traversedInterfaces) {

// Local fields

Field[] tmp = privateGetDeclaredFields(true);

addAll(fields, tmp);

// 省略部分代碼...

return res;

}

getDeclaredField(String name)

根據名稱獲取已聲明的類成員。但不能得到其父類的類成員

public class ReflectDemo {

public static void main(String[] args) throws NoSuchFieldException {

Class classes = Student.class;

Field allField = classes.getDeclaredField("name");

System.out.println(allField);

}

}

class Student{

private int id;

private String name;

}

Class Student{

public int id;

public String name;

}

輸出:可以看到getDeclaredField()方法即可以獲取public類型的字段也能獲取private類型的字段

以下為輸出結果:

private java.lang.String com.example.app.demo.Student.name

public java.lang.String com.example.app.demo.Student.name

來看下源碼的原理

@CallerSensitive

public Field getDeclaredField(String name)

throws NoSuchFieldException, SecurityException {

checkMemberAccess(Member.DECLARED, Reflection.getCallerClass(), true);

Field field = searchFields(privateGetDeclaredFields(false), name);

if (field == null) {

throw new NoSuchFieldException(name);

}

return field;

}

可以看到 getDeclaredField() 方法調用的也是 privateGetDeclaredFields 方法,上面已經講述過

getDeclaredFields()

獲取所有已聲明的類成員變量

public class ReflectDemo {

public static void main(String[] args) {

Class classes = Student.class;

Field[] allField = classes.getDeclaredFields();

for (Field field : allField) {

System.out.println(field);

}

}

}

class Student{

public int id;

public String name;

}

輸出:

以下為輸出結果:

public int com.example.app.demo.Student.id

public java.lang.String com.example.app.demo.Student.name

而且 getDeclaredFields 還可以獲取private修飾的字段

public class ReflectDemo {

public static void main(String[] args) {

Class classes = Student.class;

Field[] allField = classes.getDeclaredFields();

for (Field field : allField) {

System.out.println(field);

}

}

}

class Student{

private int id;

private String name;

}

輸出:

以下為輸出結果:

private int com.example.app.demo.Student.id

private java.lang.String com.example.app.demo.Student.name

來看下源碼 getDeclaredFields() 方法的源碼

可以看到 getDeclaredFields() 方法中也是調用 privateGetDeclaredFields 方法的,并且這里的 privateGetDeclaredFields傳入的值是 false ,也就是獲取所有已聲明的字段

@CallerSensitive

public Field[] getDeclaredFields() throws SecurityException {

checkMemberAccess(Member.DECLARED, Reflection.getCallerClass(), true);

return copyFields(privateGetDeclaredFields(false));

}

Method

getMethod(String name)

返回類或接口的特定方法。其中第一個參數為方法名稱,后面的參數為方法參數對應 Class 的對象的方法名

public class ReflectDemo {

public static void main(String[] args) throws NoSuchMethodException {

// 傳入CaseMethod的方法名

Method methods = CaseMethod.class.getMethod("caseOfMethod");

System.out.println(methods);

}

}

class CaseMethod{

public void caseOfMethod(){

System.out.println("case");

}

}

輸出:

以下為輸出結果:

public void com.example.app.demo.CaseMethod.caseOfMethod()

getMethods()

獲取類或接口的所有 public 方法,包括其父類的 public 方法

public class ReflectDemo {

public static void main(String[] args) throws NoSuchMethodException {

// 獲取所有方法,使用Method數組接收

Method[] methods = CaseMethod.class.getMethods();

for (Method method : methods) {

System.out.println(method);

}

}

}

class CaseMethod{

public void caseOfMethod(){

System.out.println("case");

}

}

輸出:

可以看到輸出結果中第一個就是我們自定義的CaseMethod中的方法,其余的都是Object類的方法

以下為輸出結果:

public void com.example.app.demo.CaseMethod.caseOfMethod()

public final void java.lang.Object.wait() throws java.lang.InterruptedException

public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException

public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException

public boolean java.lang.Object.equals(java.lang.Object)

public java.lang.String java.lang.Object.toString()

public native int java.lang.Object.hashCode()

public final native java.lang.Class java.lang.Object.getClass()

public final native void java.lang.Object.notify()

public final native void java.lang.Object.notifyAll()

getDeclaredMethod(String name, Class… parameterTypes)

獲取類或接口的特定聲明方法。其中第一個參數為方法名稱,后面的參數為方法參數對應 Class 的對象

public class ReflectDemo {

public static void main(String[] args) throws NoSuchMethodException {

Method methods = CaseMethod.class.getDeclaredMethod("caseOfMethod",null);

System.out.println(methods);

}

}

class CaseMethod{

public void caseOfMethod(){

System.out.println("case");

}

private void caseOf(){

System.out.println("case1");

}

}

getDeclaredMethods()

獲取類或接口聲明的所有方法,包括 public、protected、默認(包)訪問和 private 方法,但不包括繼承的方法

public class ReflectDemo {

public static void main(String[] args) {

Method[] methods = CaseMethod.class.getDeclaredMethods();

for (Method method : methods) {

System.out.println(method);

}

}

}

class CaseMethod{

public void caseOfMethod(){

System.out.println("case");

}

private void caseOf(){

System.out.println("case1");

}

}

輸出:

以下為輸出結果:

public void com.example.app.demo.CaseMethod.caseOfMethod()

private void com.example.app.demo.CaseMethod.caseOf()

使用invoke方法

當獲取一個對象之后就可以使用invoke方法,invoke方法示例如下:

public class ReflectDemo {

public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {

Method methods = CaseMethod.class.getMethod("caseOfMethod");

CaseMethod caseMethod = new CaseMethod();

methods.invoke(caseMethod);

}

}

class CaseMethod{

public void caseOfMethod(){

System.out.println("case");

}

private void caseOf(){

System.out.println("case1");

}

}

輸出:case

那么invoke是如何實現的呢?來看下源碼

boolean override;

@CallerSensitive

public Object invoke(Object obj, Object... args)

throws IllegalAccessException, IllegalArgumentException,

InvocationTargetException

{

// 判斷override是否為true

if (!override) {

// 判斷modifiers(方法的修飾符)是否為public

if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {

// 通過方法的修飾符(protected、private、)或聲明類(如子類可以訪問父類的protected方法)與caller之間的關系

Class caller = Reflection.getCallerClass();

// 判斷caller是否有權限方法該方法

checkAccess(caller, clazz, obj, modifiers);

}

}

MethodAccessor ma = methodAccessor; // read volatile

if (ma == null) {

ma = acquireMethodAccessor();

}

return ma.invoke(obj, args);

}

注意: invoke方法如果提供了錯誤的參數,會拋出一個異常,所以要提供一個異常處理器。建議在有必要的時候才使用invoke方法,有如下原因:

1、invoke方法的參數和返回值必須是Object類型,意味著必須進行多次類型轉換

2、通過反射調用方法比直接調用方法要明顯慢一些

Constructor

getConstructor(Class… parameterTypes)

獲取類的特定 public 構造方法。參數為方法參數對應 Class 的對象

public class ReflectDemo {

public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {

Constructor constructor = CaseMethod.class.getConstructor(int.class, String.class);

System.out.println(constructor);

}

}

class CaseMethod{

private int id;

private String name;

private int cap;

public CaseMethod(int id,String name){

this.id = id;

this.name = name;

}

public CaseMethod(int cap){

}

}

輸出:

以下為輸出結果:

public com.example.app.demo.CaseMethod(int,java.lang.String)

getConstructors()

獲取類的所有 public 構造方法

public class ReflectDemo {

public static void main(String[] args) {

Constructor[] constructors = CaseMethod.class.getConstructors();

for (Constructor constructor : constructors) {

System.out.println(constructor);

}

}

}

class CaseMethod{

private int id;

private String name;

private int cap;

public CaseMethod(int id,String name){

this.id = id;

this.name = name;

}

public CaseMethod(int cap){

}

}

輸出:

以下為輸出結果:

public com.example.app.demo.CaseMethod(int,java.lang.String)

public com.example.app.demo.CaseMethod(int)

getDeclaredConstructor(Class… parameterTypes)

public class ReflectDemo {

public static void main(String[] args) throws NoSuchMethodException {

// 注意:由于private修飾的CaseMethod構造函數沒有參數,所以getDeclaredConstructor()可以為空

// 默認的getDeclaredConstructor(Class... parameterTypes)方法是要傳參數類型的

Constructor constructor = CaseMethod.class.getDeclaredConstructor();

Constructor declaredConstructor = CaseMethod.class.getDeclaredConstructor(int.class, String.class);

System.out.println(constructor);

System.out.println(declaredConstructor);

}

}

class CaseMethod{

private int id;

private String name;

private int cap;

private CaseMethod(){

}

public CaseMethod(int id,String name){

this.id = id;

this.name = name;

}

}

輸出:

以下為輸出結果:

private com.example.app.demo.CaseMethod()

public com.example.app.demo.CaseMethod(int,java.lang.String)

getDeclaredConstructors()

獲取類的所有構造方法

public class ReflectDemo {

public static void main(String[] args) throws NoSuchMethodException {

Constructor[] constructors = CaseMethod.class.getDeclaredConstructors();

for (Constructor constructor : constructors) {

System.out.println(constructor);

}

}

}

class CaseMethod{

private int id;

private String name;

private int cap;

private CaseMethod(){

}

public CaseMethod(int id,String name){

this.id = id;

this.name = name;

}

}

輸出:

以下為輸出結果:

private com.example.app.demo.CaseMethod()

public com.example.app.demo.CaseMethod(int,java.lang.String)

使用newInstance創(chuàng)建實例

public class ReflectDemo {

public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {

Constructor constructor = CaseMethod.class.getConstructor(String.class);

CaseMethod caseMethod = constructor.newInstance("Lisa");

System.out.println(caseMethod);

}

}

class CaseMethod{

private String name;

public CaseMethod(String name){

this.name = name;

}

@Override

public String toString() {

return "CaseMethod{" +

"name='" + name + ''' +

'}';

}

}

輸出:

CaseMethod{name=‘Lisa’}

總結

Java獲得Class對象的引用的方法中,Class.forName() 方法會自動初始化Class對象,而 .class 方法不會,.class 的初始化被延遲到靜態(tài)方法或非常數靜態(tài)域的首次引用

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規(guī)問題,請聯系本站處理。 舉報投訴
  • 服務器
    +關注

    關注

    12

    文章

    9237

    瀏覽量

    85664
  • JAVA
    +關注

    關注

    19

    文章

    2972

    瀏覽量

    104865
  • 數據庫
    +關注

    關注

    7

    文章

    3827

    瀏覽量

    64515
收藏 人收藏

    評論

    相關推薦

    TLV320AIC3254內部中的ADC處理模塊和minidsp到底是什么關系?

    我想請問一下幾個問題: 1.3254內部中的ADC處理模塊和minidsp到底是什么關系,是并列的還是串行關系?還是ADC處理模塊就是minidsp特殊情況下的部分? 2.minidsp的抽取因子該怎么理解,到底怎么使用?
    發(fā)表于 10-31 06:02

    請問PCM2903C的溫度范圍到底是多少呢?

    如下圖,PCM2903C的溫度范圍到底是多少呢? 如果用在-25~85℃,是否會出問題?
    發(fā)表于 10-14 07:14

    放大器的共模輸入電壓到底是指什么?

    請問放大器的共模輸入電壓到底是指什么?
    發(fā)表于 09-19 07:17

    功放和運放到底是什么區(qū)別?

    想請問一下功放和運放到底是什么區(qū)別,感覺只要接一個小負載,運放的輸出電流也可以很大???到底有什么區(qū)別啊
    發(fā)表于 09-10 07:00

    請問LMV772到底是雙電源還是單電源?。?/a>

    請問LMV772到底是雙電源還是單電源啊?手冊前面寫的太模糊了。求指教
    發(fā)表于 09-09 07:10

    運放的輸入電容到底是什么?

    我想請問一下運放的輸入電容到底是什么?
    發(fā)表于 09-04 06:52

    LMH6502的輸入電壓到底是多少?

    LMH6502的輸入電壓到底是多少,我稍微給如大一點點的信號,放大不行還能接受,我衰減都失真,
    發(fā)表于 08-27 07:02

    運放旁路電容必須靠近芯片引腳的原因到底是什么呢?

    運放旁路電容必須靠近芯片引腳的原因到底是什么呢?有的說是怕走線的電感與旁路電容形成諧振,旁路電容靠近運放的時候走線的電感不應該更大了嗎(走線越長,走線的寄生電感也就越大)
    發(fā)表于 08-01 06:56

    華納云:java web和java什么區(qū)別java web和java什么區(qū)別

    Java Web和Java是兩個不同的概念,它們在功能、用途和實現方式上存在一些區(qū)別,下面將詳細介紹它們之間的區(qū)別。 1. 功能和用途: – Java是一種編程語言,它提供了一種用于開發(fā)各種應用程序
    的頭像 發(fā)表于 07-16 13:35 ?835次閱讀
    華納云:<b class='flag-5'>java</b> web和<b class='flag-5'>java</b><b class='flag-5'>有</b>什么區(qū)別<b class='flag-5'>java</b> web和<b class='flag-5'>java</b><b class='flag-5'>有</b>什么區(qū)別

    地址線/時鐘線/數據線上串聯的小電阻,到底有什么作用?

    在一些線路中會串聯電阻,那么這個電阻的作用到底是什么?什么時候需要串聯電阻?首先高速信號線中才考慮使用這樣的電阻。在低頻情況下,一般是直接連接。這個電阻兩個作用:第一是阻抗匹配。因為信號源的阻抗
    的頭像 發(fā)表于 06-06 08:10 ?1476次閱讀
    地址線/時鐘線/數據線上串聯的小電阻,<b class='flag-5'>到底有</b>什么<b class='flag-5'>作用</b>?

    對于STM8的固件庫,到底是怎么對文件進行配置的?

    對于STM8的固件庫,到底是怎么對文件進行配置的?
    發(fā)表于 05-17 15:59

    請問STM8L052R8的EEPROM到底是幾個block?

    哪位知道STM8L052R8的EEPROM到底是幾個block,手冊上寫的不清不楚,按FLASH說的話,052應該是高密度的,但是EEPROM只有256B,所以很亂,具體也不知道分為幾塊
    發(fā)表于 05-11 08:29

    共享單車到底是什么通信原理

    我們經常騎的共享單車到底是什么通信原理,有人了解過嗎? 一、智能車鎖 共享單車最核心的硬件是智能車鎖,主要用于實現控制和定位功能。
    發(fā)表于 04-09 10:33 ?873次閱讀
    共享單車<b class='flag-5'>到底是</b>什么通信原理

    共享單車到底是什么通信原理?

    我們經常騎的共享單車到底是什么通信原理,有人了解過嗎?下面寶藍小編就帶大家了解下。
    的頭像 發(fā)表于 02-25 10:32 ?1446次閱讀
    共享單車<b class='flag-5'>到底是</b>什么通信原理?

    請問M487KMCAN的SRAM到底是128KB還是160K?

    M487KMCAN的SRAM到底是128 KB 還是160K
    發(fā)表于 01-16 07:18
    主站蜘蛛池模板: 清朝荒淫牲艳史在线播放| 亚洲网站免费观看| 天天操夜夜爱| 在线观看国产三级| 4455vw亚洲毛片| 男人免费看片| 天天射天天色天天干| 午夜在线观看视频在线播放版| 午夜黄色一级片| 一本高清在线| 丁香婷婷社区| 国产三级日本三级美三级| 免费拍拍视频| 你懂的网址在线| 色综合天天综合网国产人| 日日操日日射| 精品三级内地国产在线观看| 爱我免费视频观看在线www| 夜夜操综合| 九九热在线视频观看| 欧美色穴| 91大神在线观看精品一区| 1024亚洲视频| 午夜欧美性欧美| 亚洲第一色视频| 婷婷丁香综合网| 天堂视频免费| 午夜免费福利片观看| 亚洲国产成+人+综合| 三级网址在线观看| 狠狠色丁香婷婷综合久久片| 狠狠五月婷婷| 午夜不卡影院| 无遮挡很污很爽很黄的网站| 欧美三级在线| 国产男女怕怕怕免费视频| 色视频在线网站| 拍拍拍成人免费高清视频| 狠狠综合| 免费大片av手机看片| 国产福利精品视频|