精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

解析Java finally的神秘面紗

開發 后端
可不能小看這個簡單的 finally,看似簡單的問題背后,卻隱藏了無數的玄機。接下來我就帶您一步一步的揭開這個 finally 的神秘面紗。

問題分析

首先來問大家一個問題:finally 語句塊一定會執行嗎?
很多人都認為 finally 語句塊是肯定要執行的,其中也包括一些很有經驗的 Java 程序員。可惜并不像大多人所認為的那樣,對于這個問題,答案當然是否定的,我們先來看下面這個例子。
清單 1.

  1. public class Test { 
  2. public static void main(String[] args) { 
  3. System.out 
  4. .println("return value of test(): " + test 
  5. ()); 
  6.  
  7. public static int test() { 
  8. int i = 1
  9. // if(i == 1) 
  10. // return 0; 
  11. System.out 
  12. .println("the previous statement of try block"); 
  13. i = i / 0
  14. try { 
  15.     System.out 
  16. .println("try block"); 
  17.       return i; 
  18.      }finally { 
  19.      System.out 
  20. .println("finally block"); 
  21. }  

清單 1 的執行結果如下:

the previous statement of try block
Exception in thread "main" java.lang.ArithmeticException: / by zero
at com.bj.charlie.Test.test(Test.java:15)
at com.bj.charlie.Test.main(Test.java:6) 

另外,如果去掉上例中被注釋的兩條語句前的注釋符,執行結果則是:

  1. return value of test(): 0  

在以上兩種情況下,finally 語句塊都沒有執行,說明什么問題呢?只有與 finally 相對應的 try 語句塊得到執行的情況下,finally 語句塊才會執行。以上兩種情況,都是在 try 語句塊之前返回(return)或者拋出異常,所以 try 對應的 finally 語句塊沒有執行。

那好,即使與 finally 相對應的 try 語句塊得到執行的情況下,finally 語句塊一定會執行嗎?不好意思,這次可能又讓大家失望了,答案仍然是否定的。請看下面這個例子(清單 2)。

清單 2.

  1. public class Test { 
  2. public static void main(String[] args) { 
  3. System.out 
  4. .println("return value of test(): " + test 
  5. ()); 
  6.  
  7. public static int test() { 
  8. int i = 1
  9. try { 
  10. System.out 
  11. .println("try block"); 
  12. System.exit 
  13. (0); 
  14. return i; 
  15. }finally { 
  16. System.out 
  17. .println("finally block"); 
  18. }  

清單 2 的執行結果如下:

try block 

finally 語句塊還是沒有執行,為什么呢?因為我們在 try 語句塊中執行了 System.exit (0) 語句,終止了 Java 虛擬機的運行。那有人說了,在一般的 Java 應用中基本上是不會調用這個 System.exit(0) 方法的。OK !沒有問題,我們不調用 System.exit(0) 這個方法,那么 finally 語句塊就一定會執行嗎?

再一次讓大家失望了,答案還是否定的。當一個線程在執行 try 語句塊或者 catch 語句塊時被打斷(interrupted)或者被終止(killed),與其相對應的 finally 語句塊可能不會執行。還有更極端的情況,就是在線程運行 try 語句塊或者 catch 語句塊時,突然死機或者斷電,finally 語句塊肯定不會執行了。可能有人認為死機、斷電這些理由有些強詞奪理,沒有關系,我們只是為了說明這個問題。

finally 語句剖析

說了這么多,還是讓我們拿出些有說服力的證據吧!還有什么證據比官方的文檔更具說服力呢?讓我們來看看官方網站上的《The Java Tutorials》中是怎樣來描述 finally 語句塊的吧!

以下位于 **** 之間的內容原封不動的摘自于《 The Java Tutorials 》文檔。

*******************************************************************************
The finally Block

The finally block always executes when the try block exits. This ensures that the finally block is executed even if an unexpected exception occurs. But finally is useful for more than just exception handling — it allows the programmer to avoid having cleanup code accidentally bypassed by a return, continue, or break. Putting cleanup code in a finally block is always a good practice, even when no exceptions are anticipated.

Note:  If the JVM exits while the try or catch code is being executed, then the finally block may not execute. Likewise, if the thread executing the try or catch code is interrupted or killed, the finally block may not execute even though the application as a whole continues.
*******************************************************************************

請仔細閱讀并認真體會一下以上兩段英文,當你真正的理解了這兩段英文的確切含義,你就可以非常自信的來回答“finally 語句塊是否一定會執行?”這樣的問題。看來,大多時候,并不是 Java 語言本身有多么高深,而是我們忽略了對基礎知識的深入理解。

接下來,我們看一下 finally 語句塊是怎樣執行的。在排除了以上 finally 語句塊不執行的情況后,finally 語句塊就得保證要執行,既然 finally 語句塊一定要執行,那么它和 try 語句塊與 catch 語句塊的執行順序又是怎樣的呢?還有,如果 try 語句塊中有 return 語句,那么 finally 語句塊是在 return 之前執行,還是在 return 之后執行呢?帶著這樣一些問題,我們還是以具體的案例來講解。

關于 try、catch、finally 的執行順序問題,我們還是來看看權威的論述吧!以下 **** 之間的內容摘自 Java 語言規范第四版(《 The Java™ Programming Language, Fourth Edition 》 )中對于 try,catch,和 finally 的描述。

*******************************************************************************
12.4. Try, catch, and finally

You catch exceptions by enclosing code in Try blocks. The basic syntax for a Try block is:

  1. try { 
  2. statements 
  3. catch (exception_type1 identifier1) { 
  4. statements 
  5. catch (exception_type2 identifier2) { 
  6. statements 
  7. ... 
  8. finally { 
  9. statements 


where either at least one catch clause, or the finally clause, must be present. The body of the try statement is executed until either an exception is thrown or the body finishes successfully. If an exception is thrown, each catch clause is examined in turn, from first to last, to see whether the type of the exception object is assignable to the type declared in the catch. When an assignable catch clause is found, its block is executed with its identifier set to reference the exception object. No other catch clause will be executed. Any number of catch clauses, including zero, can be associated with a particular TRy as long as each clause catches a different type of exception. If no appropriate catch is found, the exception percolates out of the try statement into any outer try that might have a catch clause to handle it.

If a finally clause is present with a try, its code is executed after all other processing in the try is complete. This happens no matter how completion was achieved, whether normally, through an exception, or through a control flow statement such as return or break .
*******************************************************************************

上面這段文字的大體意思是說,不管 try 語句塊正常結束還是異常結束,finally 語句塊是保證要執行的。如果 try 語句塊正常結束,那么在 try 語句塊中的語句都執行完之后,再執行 finally 語句塊。如果 try 中有控制轉移語句(return、break、continue)呢?那 finally 語句塊是在控制轉移語句之前執行,還是之后執行呢?似乎從上面的描述中我們還看不出任何端倪,不要著急,后面的講解中我們會分析這個問題。如果 try 語句塊異常結束,應該先去相應的 catch 塊做異常處理,然后執行 finally 語句塊。同樣的問題,如果 catch 語句塊中包含控制轉移語句呢? finally 語句塊是在這些控制轉移語句之前,還是之后執行呢?我們也會在后續討論中提到。

其實,關于 try,catch,finally 的執行流程遠非這么簡單,有興趣的讀者可以參考 Java 語言規范第三版(《 The Java™ Language Specification, Third Edition 》 )中對于 Execution of try-catch-finally 的描述,非常復雜的一個流程。限于篇幅的原因,本文不做摘錄,請感興趣的讀者自行閱讀。

finally 語句示例說明

下面,我們先來看一個簡單的例子(清單 3)。

清單 3.

  1. public class Test { 
  2. public static void main(String[] args) {  
  3. try {  
  4. System.out 
  5. .println("try block");  
  6. return ;  
  7. finally {  
  8. System.out 
  9. .println("finally block");  
  10. }  
  11. }  
  12. }  

清單 3 的執行結果為

try block
finally block 

清單 3 說明 finally 語句塊在 try 語句塊中的 return 語句之前執行。我們再來看另一個例子(清單 4)。

清單 4.

  1. public class Test { 
  2. public static void main(String[] args) {  
  3. System.out 
  4. .println("reture value of test() : " + test 
  5. ()); 
  6.  
  7. public static int test(){ 
  8. int i = 1
  9. try {  
  10. System.out 
  11. .println("try block");  
  12. i = 1 / 0
  13. return 1;  
  14. }catch (Exception e){ 
  15. System.out 
  16. .println("exception block"); 
  17. return 2
  18. }finally {  
  19. System.out 
  20. .println("finally block");  
  21. }  

清單 4 的執行結果為:

try block
exception block
finally block
reture value of test() : 2 

清單 4 說明了 finally 語句塊在 catch 語句塊中的 return 語句之前執行。

從上面的清單 3 和清單 4,我們可以看出,其實 finally 語句塊是在 try 或者 catch 中的 return 語句之前執行的。更加一般的說法是,finally 語句塊應該是在控制轉移語句之前執行,控制轉移語句除了 return 外,還有 break 和 continue。另外,throw 語句也屬于控制轉移語句。雖然 return、throw、break 和 continue 都是控制轉移語句,但是它們之間是有區別的。其中 return 和 throw 把程序控制權轉交給它們的調用者(invoker),而 break 和 continue 的控制權是在當前方法內轉移。請大家先記住它們的區別,在后續的分析中我們還會談到。

還是得來點有說服力的證據,下面這段摘自 Java 語言規范第四版(《 The Java™ Programming Language, Fourth Edition 》 ),請讀者自己體會一下其含義。

*******************************************************************************

A finally clause can also be used to clean up for break , continue , and return , which is one reason you will sometimes see a try clause with no catch clauses. When any control transfer statement is executed, all relevant finally clauses are executed. There is no way to leave a try block without executing its finally clause.

*******************************************************************************

好了,看到這里,是不是有人認為自己已經掌握了 finally 的用法了?先別忙著下結論,我們再來看兩個例子 – 清單 5 和清單 6。

清單 5.

  1. public class Test { 
  2. public static void main(String[] args) { 
  3.         System.out 
  4. .println("return value of getValue(): " + getValue 
  5. ()); 
  6.  
  7. public static int getValue() { 
  8.         try { 
  9.                  return 0
  10.         } finally { 
  11.                  return 1
  12.         } 


清單 5 的執行結果:

return value of getValue(): 1 


清單 6.

  1. public class Test { 
  2. public static void main(String[] args) { 
  3.         System.out 
  4. .println("return value of getValue(): " + getValue 
  5. ()); 
  6.  
  7. public static int getValue() { 
  8.         int i = 1
  9.         try { 
  10.                  return i; 
  11.         } finally { 
  12.                  i++; 
  13.         } 
  14. }  

清單 6 的執行結果:

return value of getValue(): 1 

利用我們上面分析得出的結論:finally 語句塊是在 try 或者 catch 中的 return 語句之前執行的。 由此,可以輕松的理解清單 5 的執行結果是 1。因為 finally 中的 return 1,語句要在 try 中的 return 0;語句之前執行,那么 finally 中的 return 1;語句執行后,把程序的控制權轉交給了它的調用者 main()函數,并且返回值為 1。那為什么清單 6 的返回值不是 2,而是 1 呢?按照清單 5 的分析邏輯,finally 中的 i++;語句應該在 try 中的 return i;之前執行啊? i 的初始值為 1,那么執行 i++;之后為 2,再執行 return i;那不就應該是 2 嗎?怎么變成 1 了呢?

關于 Java 虛擬機是如何編譯 finally 語句塊的問題,有興趣的讀者可以參考《 The JavaTM Virtual Machine Specification, Second Edition 》中 7.13 節 Compiling finally。那里詳細介紹了 Java 虛擬機是如何編譯 finally 語句塊。實際上,Java 虛擬機會把 finally 語句塊作為 subroutine(對于這個 subroutine 不知該如何翻譯為好,干脆就不翻譯了,免得產生歧義和誤解。)直接插入到 try 語句塊或者 catch 語句塊的控制轉移語句之前。但是,還有另外一個不可忽視的因素,那就是在執行 subroutine(也就是 finally 語句塊)之前,try 或者 catch 語句塊會保留其返回值到本地變量表(Local Variable Table)中。待 subroutine 執行完畢之后,再恢復保留的返回值到操作數棧中,然后通過 return 或者 throw 語句將其返回給該方法的調用者(invoker)。請注意,前文中我們曾經提到過 return、throw 和 break、continue 的區別,對于這條規則(保留返回值),只適用于 return 和 throw 語句,不適用于 break 和 continue 語句,因為它們根本就沒有返回值。

#p#

是不是不太好理解,那我們就用具體的例子來做形象的說明吧!

為了能夠解釋清單 6 的執行結果,我們來分析一下清單 6 的字節碼(byte-code):

Compiled from "Test.java"
public class Test extends java.lang.Object{
public Test();
  Code:
   0: aload_0
   1:invokespecial#1; //Method java/lang/Object."":()V    4: return    LineNumberTable:    line 1: 0  public static void main(java.lang.String[]);   Code:    0: getstatic #2; //Field java/lang/System.out:Ljava/io/PrintStream;    3: new #3; //class java/lang/StringBuilder    6: dup    7: invokespecial #4; //Method java/lang/StringBuilder."":()V    10: ldc #5; //String return value of getValue():    12: invokevirtual    #6; //Method java/lang/StringBuilder.append:(        Ljava/lang/String;)Ljava/lang/StringBuilder;    15: invokestatic #7; //Method getValue:()I    18: invokevirtual    #8; //Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;    21: invokevirtual    #9; //Method java/lang/StringBuilder.toString:()Ljava/lang/String;    24: invokevirtual #10; //Method java/io/PrintStream.println:(Ljava/lang/String;)V    27: return  public static int getValue();   Code:    0: iconst_1    1: istore_0    2: iload_0    3: istore_1    4: iinc 0, 1    7: iload_1    8: ireturn    9: astore_2    10: iinc 0, 1    13: aload_2    14: athrow   Exception table:    from   to  target type      2     4     9   any      9    10     9   any } 

對于 Test()構造方法與 main()方法,在這里,我們不做過多解釋。讓我們來分析一下 getValue()方法的執行。在這之前,先讓我把 getValue()中用到的虛擬機指令解釋一下,以便讀者能夠正確的理解該函數的執行。

1. iconst_
Description: Push the int constant  (-1, 0, 1, 2, 3, 4 or 5) onto the operand stack.
Forms: iconst_m1 = 2 (0x2)  iconst_0 = 3 (0x3)  iconst_1 = 4 (0x4) 
iconst_2 = 5 (0x5) iconst_3 = 6 (0x6)  iconst_4 = 7 (0x7)  iconst_5 = 8 (0x8) 
2. istore_
Description: Store int into local variable. The  must be an index into the
local variable array of the current frame.
Forms: istore_0 = 59 (0x3b)  istore_1 = 60 (0x3c)  istore_2 = 61 (0x3d) 
istore_3 = 62 (0x3e) 
3. iload_
Description: Load int from local variable. The  must be an index into the
local variable array of the current frame.
Forms: iload_0 = 26 (0x1a)  iload_1 = 27 (0x1b)  iload_2 = 28 (0x1c)  iload_3 = 29 (0x1d) 
4. iinc index, const
Description: Increment local variable by constant. The index is an unsigned byte that
must be an index into the local variable array of the current frame. The const is an
immediate signed byte. The local variable at index must contain an int. The value
const is first sign-extended to an int, and then the local variable at index is
incremented by that amount.
Forms:  iinc = 132 (0x84)

Format:
iinc
index
const 
5. ireturn
Description: Return int from method.
Forms:  ireturn = 172 (0xac) 
6. astore_
Description: Store reference into local variable. The  must be an index into the
local variable array of the current frame.
Forms: astore_0 = 75 (0x4b) astore_1 = 76 (0x4c) astore_2 =77 (0x4d) astore_3 =78 (0x4e) 
7. aload_
Description: Load reference from local variable. The  must be an index into the
local variable array of the current frame.
Forms: aload_0 = 42 (0x2a) aload_1 = 43 (0x2b) aload_2 = 44 (0x2c) aload_3 = 45 (0x2d) 
8. athrow
Description: Throw exception or error.
Forms: athrow = 191 (0xbf) 

有了以上的 Java 虛擬機指令,我們來分析一下其執行順序:分為正常執行(沒有 exception)和異常執行(有 exception)兩種情況。我們先來看一下正常執行的情況,如圖 1 所示:

圖 1. getValue()函數正常執行的情況
圖 1. getValue()函數正常執行的情況

由上圖,我們可以清晰的看出,在 finally 語句塊(iinc 0, 1)執行之前,getValue()方法保存了其返回值(1)到本地表量表中 1 的位置,完成這個任務的指令是 istore_1;然后執行 finally 語句塊(iinc 0, 1),finally 語句塊把位于 0 這個位置的本地變量表中的值加 1,變成 2;待 finally 語句塊執行完畢之后,把本地表量表中 1 的位置上值恢復到操作數棧(iload_1),***執行 ireturn 指令把當前操作數棧中的值(1)返回給其調用者(main)。這就是為什么清單 6 的執行結果是 1,而不是 2 的原因。

再讓我們來看看異常執行的情況。是不是有人會問,你的清單 6 中都沒有 catch 語句,哪來的異常處理呢?我覺得這是一個好問題,其實,即使沒有 catch 語句,Java 編譯器編譯出的字節碼中還是有默認的異常處理的,別忘了,除了需要捕獲的異常,還可能有不需捕獲的異常(如:RunTimeException 和 Error)。

從 getValue()方法的字節碼中,我們可以看到它的異常處理表(exception table), 如下:

Exception table:
from to target type
2 4 9 any 

它的意思是說:如果從 2 到 4 這段指令出現異常,則由從 9 開始的指令來處理。

圖 2. getValue()函數異常執行的情況
圖 2. getValue()函數異常執行的情況

先說明一點,上圖中的 exception 其實應該是 exception 對象的引用,為了方便說明,我直接把它寫成 exception 了。

由上圖(圖 2)可知,當從 2 到 4 這段指令出現異常時,將會產生一個 exception 對象,并且把它壓入當前操作數棧的棧頂。接下來是 astore_2 這條指令,它負責把 exception 對象保存到本地變量表中 2 的位置,然后執行 finally 語句塊,待 finally 語句塊執行完畢后,再由 aload_2 這條指令把預先存儲的 exception 對象恢復到操作數棧中,***由 athrow 指令將其返回給該方法的調用者(main)。

通過以上的分析,大家應該已經清楚 try-catch-finally 語句塊的執行流程了吧!

為了更具說服力,我們還是來引經據典吧!大家可以不相信我,難道還不相信“高司令”(Gosling)嗎?下面這段仍然摘自 Java 語言規范第四版 《 The Java™ Programming Language, Fourth Edition 》 ,請讀者自己體會吧!

*******************************************************************************
a finally clause is always entered with a reason. That reason may be that the try code finished normally, that it executed a control flow statement such as return, or that an exception was thrown in code executed in the Try block. The reason is remembered when the finally clause exits by falling out the bottom. However, if the finally block creates its own reason to leave by executing a control flow statement (such as break or return) or by throwing an exception, that reason supersedes the original one, and the original reason is forgotten. For example, consider the following code:
try {
// … do something …
return 1;
} finally {
return 2;
}
When the Try block executes its return, the finally block is entered with the “reason” of returning the value 1. However, inside the finally block the value 2 is returned, so the initial intention is forgotten. In fact, if any of the other code in the try block had thrown an exception, the result would still be to return 2. If the finally block did not return a value but simply fell out the bottom, the “return the value 1 ″ reason would be remembered and carried out.
*******************************************************************************
好了,有了以上的知識,讓我們再來看以下 3 個例子。

清單 7.

  1. public class Test { 
  2. public static void main(String[] args) { 
  3.         System.out 
  4. .println("return value of getValue(): " + getValue 
  5. ()); 
  6.  
  7. @SuppressWarnings("finally"
  8. public static int getValue() { 
  9.         int i = 1
  10.         try { 
  11.                  i = 4
  12.         } finally { 
  13.                  i++; 
  14.                  return i; 
  15.         } 
  16. }  

清單 7 的執行結果:

return value of getValue(): 5 

清單 8.

  1. public class Test { 
  2. public static void main(String[] args) { 
  3.         System.out 
  4. .println("return value of getValue(): " + getValue 
  5. ()); 
  6.  
  7. public static int getValue() { 
  8.         int i = 1
  9.         try { 
  10.                  i = 4
  11.         } finally { 
  12.                  i++; 
  13.         } 
  14.         return i; 
  15. }  

清單 8 的執行結果:

return value of getValue(): 5 

清單 7 和清單 8 應該還比較簡單吧!利用我們上面講解的知識,很容易分析出其結果。讓我們再來看一個稍微復雜一點的例子 – 清單 9。我建議大家***先不要看執行結果,運用學過的知識來分析一下,看是否能推斷出正確的結果。

清單 9.

  1. public class Test { 
  2. public static void main(String[] args) {  
  3. System.out 
  4. .println(test 
  5. ());  
  6. }  
  7.  
  8. public static String test() {  
  9. try {  
  10. System.out 
  11. .println("try block");  
  12. return test1 
  13. ();  
  14. finally {  
  15. System.out 
  16. .println("finally block");  
  17. }  
  18. }  
  19. public static String test1() {  
  20. System.out 
  21. .println("return statement");  
  22. return "after return";  
  23. }  
  24. }  

清單 9 的結果:

try block
return statement
finally block
after return 

你分析對了嗎?其實這個案例也不算很難,return test1(); 這條語句等同于 :

  1. String tmp = test1(); 
  2. return tmp;  

這樣,就應該清楚為什么是上面所示的執行結果了吧!

好了,就寫到這吧!希望大家看完這篇文章能夠有所收獲!

總結

沒想到吧!一個小小的、看似簡單的 finally 語句塊背后居然隱藏了這么多玄機。看來,我們平時還是應該認真的閱讀 Java 相關的基礎文檔,比如:Java 語言規范、Java 虛擬機規范等,很多棘手的問題都可以從中得到答案。只有真正的吃透了基礎知識,才能達到運用自如的境界!

原文鏈接:http://run-wang.iteye.com/blog/1262063

編輯推薦:

  1. JAVA設計模式:工廠模式之簡單工廠
  2. Java靜動態代理模式示例
  3. Java內存泄露的理解與解決
  4. Java開發框架Play框架快速入門
  5. 調用Java NIO提高文件讀寫速度
責任編輯:林師授 來源: run_wang的博客
相關推薦

2015-08-20 13:43:17

NFV網絡功能虛擬化

2014-03-12 11:11:39

Storage vMo虛擬機

2021-06-07 08:18:12

云計算云端阿里云

2010-05-17 09:13:35

2010-05-26 19:12:41

SVN沖突

2010-05-11 10:19:17

VMforceJava云計算

2018-03-01 09:33:05

軟件定義存儲

2009-06-01 09:04:44

Google WaveWeb

2009-09-15 15:34:33

Google Fast

2016-04-06 09:27:10

runtime解密學習

2023-04-10 11:00:00

注解Demo源碼

2011-06-22 09:43:01

C++

2023-11-02 09:55:40

2011-07-10 14:28:49

JAVAIO

2010-09-17 14:57:34

JAVA數據類型

2024-02-14 09:00:00

機器學習索引ChatGPT

2016-11-16 09:06:59

2025-01-07 15:07:13

2021-07-28 21:49:01

JVM對象內存

2021-09-17 15:54:41

深度學習機器學習人工智能
點贊
收藏

51CTO技術棧公眾號

欧美日韩在线一二三| 欧美精品一区二区三区国产精品| 成人午夜视频在线观看免费| 色av男人的天堂免费在线| 日韩精品视频网站| 久久精品91久久香蕉加勒比| 欧美做受高潮中文字幕| 亚洲第一会所001| 亚洲精品视频免费观看| 国产精品免费区二区三区观看| 日本午夜视频在线观看| 清纯唯美亚洲综合一区| 欧美一区二区三区在线看| 国产乱子伦农村叉叉叉| 国产在线激情| 国产欧美日韩久久| 成人自拍爱视频| 亚洲自拍偷拍另类| 亚洲三级影院| 另类专区欧美制服同性| 亚洲精品国产91| 国产欧美自拍一区| 91精品欧美久久久久久动漫| 99福利在线观看| 天堂va在线| 亚洲欧洲国产日韩| 日韩精品欧美专区| 桃花色综合影院| 国产成人在线色| 国产欧美久久久久久| 欧美啪啪小视频| 黄色亚洲在线| 精品中文字幕乱| 情侣偷拍对白清晰饥渴难耐| 九九在线精品| 亚洲另类图片色| 亚洲av永久无码精品| 91麻豆精品国产综合久久久| 欧美专区在线观看一区| 黄色片一级视频| 天堂av在线| 亚州成人在线电影| av女优在线播放| 欧美韩日亚洲| 亚洲国产视频一区二区| 51xx午夜影福利| 韩国中文字幕在线| 最近中文字幕一区二区三区| 中文字幕在线观看一区二区三区| av在线免费一区| 国产精品入口麻豆九色| 日韩一区二区电影在线观看| 国产综合视频一区二区三区免费| 久久这里都是精品| 欧洲久久久久久| 国产一区二区三区福利| 国产日韩欧美不卡| 在线电影看在线一区二区三区| av资源网站在线观看| 亚洲欧洲性图库| 免费久久久久久| 久草在线视频福利| 亚洲成人在线免费| 北条麻妃在线观看| av久久网站| 91精品国产乱码| 日本成人在线免费| 久久精品亚洲成在人线av网址| 亚洲激情 国产| 国产毛片久久久久久久| 日韩电影免费在线观看| 久久精品视频在线播放| 午夜写真片福利电影网| 亚洲国产黄色| 国产精品第3页| 国产伦精品一区二区三区免.费| 国产精品一区二区不卡| 国产伦理一区二区三区| 国产小视频福利在线| 国产精品国产a| 国产精品久久久久9999爆乳| 中文字幕在线直播| 欧美日韩一区二区三区免费看| 久久精品久久99| 久久这里只有精品一区二区| 国产一区二区黑人欧美xxxx| 国产又粗又硬又长又爽| 在线视频亚洲| 国产欧美在线看| 东京干手机福利视频| 91视频www| 强伦女教师2:伦理在线观看| 99thz桃花论族在线播放| 在线观看日韩av先锋影音电影院| 亚洲天堂伊人网| 麻豆视频一区| 久久精品91久久香蕉加勒比| 精品一区二区三区四| 日韩国产欧美在线播放| 91精品在线国产| 十九岁完整版在线观看好看云免费| 国产视频亚洲色图| 国产二区视频在线| 久久精品97| 亚洲国产精品va在线看黑人动漫| 日韩影视一区二区三区| 亚洲日产国产精品| 91影院在线免费观看视频| 日本福利片在线| 亚洲午夜三级在线| 超碰人人草人人| av一区二区高清| 韩日精品中文字幕| 精品久久久中文字幕人妻| 国产日韩欧美综合在线| 美女日批免费视频| 久久在线观看| www.日韩av.com| 懂色av蜜臀av粉嫩av分享吧最新章节| 国产宾馆实践打屁股91| 亚洲欧美日产图| 欧美www.| 亚洲精品色婷婷福利天堂| 青青草原免费观看| 狠狠色狠狠色综合| 亚洲午夜激情| 日韩va亚洲va欧美va久久| 在线成人激情黄色| 国产69精品久久久久久久久久| 国内不卡的二区三区中文字幕| 日本一区二区高清视频| 校园春色亚洲| 日韩美女av在线| 日韩精品在线不卡| 成人一区二区在线观看| 成年丰满熟妇午夜免费视频| 只有精品亚洲| 久久久国产精品免费| 丰满人妻一区二区三区四区| 久久亚洲精品国产精品紫薇| 国自产拍偷拍精品啪啪一区二区| 99精品在免费线中文字幕网站一区 | 久久久久久久久久一级| xfplay精品久久| 欧美日韩亚洲一| 欧美男人操女人视频| 97精品视频在线观看| 黄色av中文字幕| 亚洲成人1区2区| 欧美夫妇交换xxx| 国产午夜精品一区二区三区欧美| 国产一区二区三区奇米久涩| 91福利区在线观看| 亚洲国产成人久久综合| 国产精品99无码一区二区| 成人自拍视频在线观看| 日韩欧美视频网站| 猛男gaygay欧美视频| 情事1991在线| av影片在线看| 欧美一区二区免费视频| 国产精品日日夜夜| 久久日韩精品一区二区五区| 能看的毛片网站| 亚欧美无遮挡hd高清在线视频| 97av自拍| www成人免费观看| 亚洲国产黄色片| 波多野结衣在线观看视频| 国产精品乱人伦| 国产乱国产乱老熟300部视频| 韩国欧美一区| 欧美一区二区高清在线观看| 欧美高清免费| 久久99久久99精品中文字幕| 丝袜视频国产在线播放| 欧美色中文字幕| 欧美日韩国产精品一区二区三区| 99久久精品免费精品国产| 欧美自拍小视频| 欧美在线网址| 欧美资源一区| 色播一区二区| 国产成人精品免高潮在线观看| 日本在线播放| 亚洲精品91美女久久久久久久| 久久精品五月天| 一区二区三区视频在线看| 日本高清www| 美国一区二区三区在线播放 | 欧美高清精品3d| 可以免费看的av毛片| 国产精品传媒入口麻豆| 一级特级黄色片| 精品亚洲成a人在线观看| 日本手机在线视频| 日韩综合精品| 久久这里精品国产99丫e6| 一区二区三区日本视频| 欧美在线观看日本一区| 在线网址91| 一本色道久久88亚洲综合88| 亚洲欧美国产高清va在线播放| 欧美在线短视频| 伊人久久综合视频| 亚洲日本青草视频在线怡红院| 给我看免费高清在线观看| 国模大尺度一区二区三区| 久久久精品在线视频| 国产精品www994| 一区二区三区国产福利| 久久91麻豆精品一区| 国产精品免费一区二区三区| 欧美97人人模人人爽人人喊视频| 欧美亚洲国产日本| 国产乱码在线| 久久九九全国免费精品观看| 高h视频在线| 精品一区二区电影| 欧性猛交ⅹxxx乱大交| 欧美一区二区私人影院日本| 夜夜躁日日躁狠狠久久av| 精品国产91久久久| 久久精品国产亚洲av无码娇色| 成人欧美一区二区三区1314| 欧美日韩国产黄色| 国产日产欧美精品一区二区三区| 538国产视频| 99久久国产综合精品色伊| 亚洲无人区码一码二码三码| 国产麻豆精品在线| 999久久久精品视频| 久久精品国产**网站演员| 能在线观看的av网站| 噜噜噜91成人网| 欧美三级一级片| 亚洲理伦在线| 欧美亚洲一二三区| 国产模特精品视频久久久久| 欧美,日韩,国产在线| 亚洲人成免费| 欧美a v在线播放| 久久一区国产| 三级在线视频观看| 麻豆成人av在线| 三级性生活视频| 国产精品主播直播| 野花视频免费在线观看| 国产成人av福利| 亚洲美女精品视频| 99视频国产精品| mm131美女视频| 久久久欧美精品sm网站| 免费看裸体网站| 国产精品久久久久9999吃药| 可以免费看av的网址| 亚洲免费视频中文字幕| 免费在线一级片| 精品国产鲁一鲁一区二区张丽| 国产精品黄色网| 色素色在线综合| 又骚又黄的视频| 欧美一卡二卡三卡| 日本黄视频在线观看| 亚洲精品在线不卡| 在线看的av网站| 欧美日本黄视频| 碰碰在线视频| 国产欧美精品xxxx另类| 亚洲综合网狠久久| 久久精品国产第一区二区三区最新章节 | 日精品一区二区三区| 国产精品嫩草影院8vv8| 国产999精品久久久久久| 久久国产精品无码一级毛片 | 亚洲精品理论电影| 97视频在线观看网站| 欧美成年人视频网站| 川上优av中文字幕一区二区| 国产精品久久久久久久久久久久久| 亚洲aⅴ网站| 极品日韩久久| 国产精品久久久久久| 天堂8在线天堂资源bt| 久久久成人网| 男男受被啪到高潮自述| 久久综合久久久久88| 天天看天天摸天天操| 午夜av电影一区| 97在线视频人妻无码| 日韩电影中文 亚洲精品乱码| 四虎久久免费| 91成人精品网站| 九九九九九九精品任你躁 | 999成人网| 亚洲 欧美 日韩 国产综合 在线| 美女视频黄频大全不卡视频在线播放| 中文在线字幕观看| 中文字幕精品—区二区四季| 日韩av男人天堂| 91精品国产91久久久久久一区二区 | 精品亚洲国内自在自线福利| 五月婷婷综合在线观看| 最近日韩中文字幕| 日韩av免费播放| 国产美女诱惑一区二区| 国产视频观看一区| 国产毛片精品| 久久久一二三四| 日韩专区在线视频| 久久精品国产亚洲精品2020| 影音先锋在线视频| 国产精品久久久久福利| 美女av一区| 日韩精品免费一区| 精品一区二区三区在线观看 | 在线综合色站| 正在播放国产精品| 日本伊人色综合网| asian性开放少妇pics| 亚洲综合免费观看高清完整版在线 | 成人自拍爱视频| 午夜国产精品视频| www.国产福利| 亚洲日本va在线观看| 这里只有精品6| 一区二区成人精品| 偷拍中文亚洲欧美动漫| 国产一区福利视频| 亚洲高清免费| 日本性生活一级片| 亚洲午夜电影网| 丰满少妇在线观看bd| 色综合久久久888| 日韩精品一级| aaa免费在线观看| 国产精品自拍三区| 欧美日韩成人免费观看| 欧美成va人片在线观看| 怡红院在线播放| 91精品国产99久久久久久红楼 | 国产日韩影视精品| 国产精品午夜一区二区| 国产午夜精品美女视频明星a级| 在线观看欧美日韩电影| 欧美日韩一区二区视频在线观看| 久久都是精品| 亚洲ⅴ国产v天堂a无码二区| 欧美手机在线视频| 免费在线观看黄色| 亚洲japanese制服美女| 国色天香一区二区| 短视频在线观看| 欧美在线制服丝袜| 免费在线观看黄色网| 成人一区二区三区四区| 最新日韩欧美| 精品无码国产污污污免费网站| 欧美自拍偷拍一区| dj大片免费在线观看| 国产精品一 二 三| 久久精品一本| 欧美色视频一区二区三区在线观看| 91精品国产免费| 天堂√中文最新版在线| 天堂av一区二区| 国产一区二区在线视频| 久久9999久久免费精品国产| 日韩精品在线观| 国产成人精选| 菠萝蜜视频在线观看入口| 92国产精品观看| 一区二区小视频| 欧美高跟鞋交xxxxxhd| 亚洲+变态+欧美+另类+精品| 国产理论在线播放| 亚洲激情在线激情| 全色精品综合影院| 成人免费视频网址| 99re国产精品| av在线免费播放网址| 日韩精品最新网址| 美女100%一区| 亚洲小视频在线播放| 久久综合久色欧美综合狠狠| 国产乱淫a∨片免费观看| 欧美一区三区三区高中清蜜桃| 久久国产成人午夜av影院宅| 日本精品一二三区| 欧美色综合久久| 免费看男女www网站入口在线| 亚洲精品国产一区| 99久久免费精品高清特色大片| 中文字幕人妻丝袜乱一区三区| 欧美激情精品久久久久| 第一会所sis001亚洲| 中文字幕三级电影| 欧美高清视频在线高清观看mv色露露十八 | 中文字幕第一页久久| 日本高清视频在线|