一区二区三区日韩精品-日韩经典一区二区三区-五月激情综合丁香婷婷-欧美精品中文字幕专区

分享

管理 Java 類路徑(UNIX 和 Mac OS X)

 iversion 2007-07-17

Elliotte Harold (elharo@metalab.unc.edu), 副教授, Polytechnic 大學

2007 年 1 月 04 日

類路徑是 Java? 平臺中最復雜也最令人頭痛的部分之一,但熟練掌握類路徑對成為一名專業(yè) Java 程序員來說卻又十分關鍵。在本文中,Elliotte Rusty Harold 為您闡述了類路徑和源路徑的復雜性,并向您展示了如何在 UNIX 和 Mac OS X 中熟練掌握它們。如果您使用的是 Windows,請參閱本文的 姊妹篇。

類路徑可以連接 Java 運行庫和文件系統(tǒng)。它定義編譯器和解釋器應該在何處查找要加載的 .class 文件。它的基本思想是:文件系統(tǒng)的層次結構反映了 Java 包的層次結構,而類路徑則定義了文件系統(tǒng)中的哪個目錄可以作為 Java 包層次結構的根。

遺憾的是,通常文件系統(tǒng)非常復雜并依賴于平臺,而且和 Java 包也不能很好地匹配。這樣一來,不論是新用戶還是資深 Java 程序員都深感類路徑的棘手。沒錯,它的確不是 Java 平臺好的一面,它讓您到了下班的時候還在忙于調(diào)試一個頑固的小問題。

當然采用 Eclipse 這樣的優(yōu)秀 IDE 可以減少管理類路徑的一些困難,但只能說是一些,而且前提還必須是一切都正常(但這不大可能,因為總會有一些意外出現(xiàn))。因此,每個 Java 程序員都必須要全面了解類路徑,惟有如此,才有希望調(diào)試類路徑中所出現(xiàn)的問題。

在本文中,我給出了您所需要了解的有關 UNIX、Linux 和 Mac OS X 中的 Java 類路徑(以及相關源路徑)的全部內(nèi)容。本文的 姊妹篇 則展示了 Windows 上的類似技術。文中列出的步驟可以作為指南,并能解決出現(xiàn)的大多數(shù)問題。

包結構

要掌握類路徑,首先應從其源代碼入手。每個類都屬于一個包,而此包必須 遵守標準的命名約定。簡單地說,包的名稱要由顛倒的兩級域名開始,比如 com.exampleedu.poly,之后是至少一個或多個單詞用于描述包的內(nèi)容。比方說,假設有一個域名為 elharo.com,如果要創(chuàng)建一個 Fraction 類,可以將其放入如下包中:

  • com.elharo.math
  • com.elharo.numbers
  • com.elharo.math.algebra.fields

在顛倒的域名之后,需要使用單一單詞的子包名。不要使用縮寫形式,并要保證拼寫正確。如果需要,可以使用拼寫檢查器。大部分與類路徑相關的問題都是由在源代碼中使用某個單詞而在文件系統(tǒng)中使用的卻是與之稍有不同的拼寫或縮寫而引起的。所以最好的做法就是總是使用拼寫正確且沒有縮寫的名稱。

整個包名稱應該是小寫的,即使該名稱是在別處常采取大寫形式的一些慣用名稱和縮寫詞。Windows 通常不區(qū)分文件名中的大小寫,但 Java 和一些 UNIX 文件系統(tǒng)卻區(qū)分。如果需要在不同的系統(tǒng)間移動文件,大小寫問題肯定會帶來一些麻煩。包名稱必須要全部由 ASCII 字符組成。一些編譯器也接受用 Hebrew、Cyrillic、Greek 或其他腳本編寫的包名稱,但大多數(shù)文件系統(tǒng)并不接受;您稍后就會看到,這樣的包名稱必須擔負充當目錄名這樣的雙重任務。Java 包和類名是 Unicode,但很多文件系統(tǒng)(包括 FAT)卻不能識別 Unicode。遺憾的是,F(xiàn)AT 系統(tǒng)非常之多。如果只簡單地用不同的默認編碼將文件復制到系統(tǒng)將會使編譯器和解釋器無法找到正確的類。

用完即棄的代碼

如果您在編寫一個只使用一次就丟掉的類 —— 比如測試一個 API 的類 —— 則無需將它放到包中。但需要多次使用的類必須要放到包中。

不要試圖在包名稱方面節(jié)約成本。長遠來看,這只會有百害而無一利。如果需要域名就買一個。如果名稱太長就買個短些的(我曾經(jīng)買到了 這樣一個域名,因而我的包前綴就只有 6 個字符)。不要將類放到默認包中(默認包是指如果未在類中包含一條包語句時系統(tǒng)默認給出的包)。如果包訪問不利于對象間的通信,就需要向類中添加更多的公共方法。需要多次使用的類必須要放到包中。

目錄結構

下一步要做的是組織源文件來匹配包結構。在某處創(chuàng)建一個干凈的空白目錄。本文中,我將其命名為 project。在這個目錄里,再創(chuàng)建兩個目錄:bin 和 src。(有些人更喜歡將其分別命名為 build 和 source。)

接下來,在 src 目錄,建一個與包層次結構相匹配的層次結構。例如,如果給定類名為 com.elharo.math.Fraction,我會將 com 目錄放到 src 目錄中,然后在 com 目錄中創(chuàng)建一個 elharo 目錄,再在 elharo 目錄內(nèi)放一個 math 目錄,最后在 math 目錄內(nèi)放上 Fraction.java,如圖 1 所示:



圖 1. 目錄結構符合包結構
目錄結構符合包結構

要點:不要在 src 目錄中放置除源代碼之外的任何內(nèi)容。通常這里放入的文件都是 .java 文件。在有些情況下,也可放置 .html 文件(用于 JavaDoc)或其他類型的源代碼。然而,決不能在此結構內(nèi)放置 .class 文件或任何其他編譯并生成的工件。這樣做只會帶來麻煩。遺憾的是,如果不夠謹慎,javac 編譯器就會 “明知故犯”。在下一節(jié),將介紹如何修復這一問題。







編譯

編譯 Java 代碼需要一些技巧,原因是必須要跟蹤如下幾方面相關但又有所不同的內(nèi)容:

  • 正在編譯的目標文件。
  • 編譯器在其中尋找目標文件導入 .java 文件的那個目錄。
  • 編譯器在其中尋找目標文件導入 .class 文件的那個目錄。
  • 編譯器在其中放置編譯輸出的目錄。

默認地,javac 編譯器將上述目錄都認為是當前目錄,而這并不是您所希望的。因此,需要在編譯時顯式地指定這些元素。

要編譯的文件

指定的第一個要編譯的文件是 .java 文件,以從當前目錄到該文件的整個路徑的形式給出。比如,假設當前所在目錄是 圖 1 所示的 project 目錄。該目錄包含 src 目錄。此 src 目錄包含 com 目錄,而 com 目錄又包含 example 目錄,example 目錄下是 Fraction.java 文件。如下命令行對它進行編譯:

$ javac src/com/elharo/math/Fraction.java

如果路徑不正確,就會給出這樣的錯誤消息:

error: cannot read: src/com/example/mtah/Fraction.java
                        

如果出現(xiàn)這樣的錯誤消息,就需要檢查路徑的各個部分,確保它們拼寫正確。然后再通過一個與下面類似的 ls 檢查該文件是否處于它應該出現(xiàn)的位置:

$ ls src/com/example/math
                        ls: src/com/example/math: No such file or directory
                        

出現(xiàn)問題的原因通常是因為路徑拼寫錯誤,但也可能是由于當前的目錄不對。在本例中,需要檢查當前的工作目錄是不是 project 目錄。pwd 命令在這里非常有用。例如,以下命令將告訴我,我實際上處于 project/src 而不是 project 目錄中:

$ pwd
                        /Users/elharo/documents/articles/classpath/project/src

在編譯之前,我需要執(zhí)行 cd ..。

輸出到哪里

假設沒有出現(xiàn)任何語法錯誤,javac 將編譯后的 .class 文件放到與之對應的.java 文件所在的相同目錄內(nèi)。這并不是您所想要的結果。將 .class 和 .java 文件混在一起常常會使清理編譯后的文件十分困難,因為很可能會意外刪除本應保留的 .java 文件。這常會使清理構建十分困難,而且還會導致版本問題。發(fā)布一個二進制時,只對編譯后的 .class 文件進行歸檔也會十分困難。因此,需要告知編譯器將編譯后的輸出放到一個完全不同的目錄內(nèi)。-d 開關用來指定輸出目錄(通常稱為 bin、build 或 class):

$ javac -d bin src/com/elharo/math/Fraction.java
                        

現(xiàn)在輸出如圖 2.所示,注意 javac 已建立了完整的目錄層次結構 com/elharo/math。不需要再手動建立。



圖 2. 并行源和編譯后的層次結構
并行源和編譯后的層次結構

源路徑

源路徑 就是 Java 在其中尋找源文件的那個目錄。具體到本例,就是 src 目錄。該目錄必須包含源文件的層次結構,這些源文件可以被放到它們自己的目錄中。因此它不是 com 目錄也不是 src/com/elharo/math 目錄。

很多項目都使用不止一個類和包。它們通過導入語句和完整的包限定類名連接起來。例如,假設您在 com.elharo.gui 包里面創(chuàng)建一個新的 MainFrame 類 如清單 1 所示:



清單 1. 一個包中的類可以導入另一個包中的類
                        package com.elharo.gui;
                        import com.elharo.math.*;
                        public class MainFrame {
                        public static void main(String[] args) {
                        Fraction f = new Fraction();
                        // ...
                        }
                        }

該類使用的是與 MainFrame 類所在的包不同的包中的 com.elharo.math.Fraction 類。源設置現(xiàn)在應該如圖 3 所示(我將編譯后的輸出從之前的步驟中刪除了。但這沒有關系,因為我總是能重新編譯它)。



圖 3. 幾個包的源結構
幾個包的源結構

現(xiàn)在來看一下試著像以前一樣編譯 MainFrame.java 會出現(xiàn)什么情況。



清單 2. 編譯 MainFrame.java
                        $ javac -d bin src/com/elharo/gui/MainFrame.java
                        src/com/elharo/gui/MainFrame.java:3: package com.elharo.math does not exist
                        import com.elharo.math.*;
                        ^
                        src/com/elharo/gui/MainFrame.java:7: cannot find symbol
                        symbol  : class Fraction
                        location: class com.elharo.gui.MainFrame
                        private Fraction f = new Fraction();
                        ^
                        src/com/elharo/gui/MainFrame.java:7: cannot find symbol
                        symbol  : class Fraction
                        location: class com.elharo.gui.MainFrame
                        private Fraction f = new Fraction();
                        ^
                        3 errors
                        

出現(xiàn)清單 2 中的錯誤的原因是,雖然 javac 知道到何處可以找到 MainFrame.java,但它卻并不知道到何處可以找到 Fraction.java(您可能覺得它應該具備足夠的智能來識別匹配的層次結構,但事實并非如此)。為了給它提供一些線索,必須指定源路徑。用源路徑指定編譯器應該到哪些目錄查找源文件的層次結構。在清單 2 中,源路徑是 src。所以我使用了 -sourcepath 選項,如下所示:

$ javac -d bin -sourcepath src src/com/elharo/gui/MainFrame.java
                        

現(xiàn)在再編譯程序,就不會出現(xiàn)錯誤,并會產(chǎn)生如圖 5 所示的輸出。請注意 javac 也編譯了文件 Fraction.java,F(xiàn)raction.java 被當前編譯的文件引用。



圖 4. 多類輸出
多類輸出

在源路徑中編譯多個目錄

在源路徑中可以有多個目錄,使用冒號分隔各目錄,但通常沒有必要這么做。例如,若我想包括本地的 src 目錄和用來存放另一個項目的源代碼的 /Users/elharo/Projects/XOM/src 目錄,我可以這樣進行編譯:

$ javac -d bin -sourcepath src:/Users/elharo/Projects/XOM/src
                        src/com/elharo/gui/MainFrame.java
                        

該命令并不編譯在這兩個層次結構中所找到的每個文件。它只編譯由單個的 .java 文件直接或間接引用的文件,而此 .java 文件必須被編譯。

更常見的情況是,為 .java 文件用一個單一的源目錄,為類或放置了預編譯的第三方庫的 JAR 歸檔文件用多個目錄。而這正是類路徑的作用所在。

設置類路徑

在大中型項目中,每次都要對每個文件進行重編譯會非常耗時。為減少這種編譯負擔,可以在不同的 bin 目錄分別編譯和存儲相同項目的獨立部分。這些目錄被添加到類路徑。

將類添加到類路徑有幾種方法可選。但您只能使用 -classpath 命令行開關。例如,假設我想從另一個之前已經(jīng)編譯到目錄 /Users/elharo/classes 的工程導入文件,那么我會向命令行添加 -classpath /Users/elharo/classes,如下所示:

$ javac -d bin -sourcepath src -classpath /Users/elharo/classes
                        src/com/elharo/gui/MainFrame.java
                        

現(xiàn)在假設需要添加兩個目錄,/Users/elharo/project1/classes 和 /Users/elharo/project2/classes。那么我將包含它們并使用冒號將它們分隔開,如下所示:

$ javac -d bin -sourcepath src
                        -classpath /Users/elharo/project1/classes:/Users/elharo/project2/classes
                        src/com/elharo/gui/MainFrame.java
                        

頂級目錄
請注意這里所說的頂級目錄是指所有包含包的層次結構的頂級目錄,包括 com/elharo/foo/bar 或 nu/xom/util 的層次結構。具有匹配包名稱(com、elharo、math 等)的目錄絕不會直接包括在源路徑或類路徑中。

當然,您也可以使用自己喜歡的各種相對路徑的格式。比如,如果 project1 和 project2 是當前工作目錄的同級目錄(即它們有相同的父目錄),那么我會這樣引用它們:

$ javac -d bin -sourcepath src
                        -classpath ../project1/classes:../project2/classes
                        src/com/elharo/gui/MainFrame.java
                        

到目前為止,我都一直假設程序完全獨立并且沒有使用任何單獨的編譯后的第三方庫。如果需要使用第三方庫,還必須將它們也添加到類路徑。庫通常是 JAR 文件的格式,比如 junit.jar 或 icu4j.jar。在本例中,需要向類路徑添加的只是 JAR 文件本身,而不是包含 JAR 文件的目錄(從實質(zhì)上講,JAR 文件可以充當包含編譯后的 .class 文件的一種目錄)。例如,如下命令會向類路徑添加三項內(nèi)容:/Users/elharo/classes 目錄,當前工作目錄里的 icu4j.jar 文件和 /Users/elharo/lib 下的 junit.jar 文件:

$ javac -d bin -sourcepath src
                        -classpath /Users/elharo/classes:icu4j.jar:/Users/elharo/lib/junit.jar
                        src/com/elharo/gui/MainFrame.java
                        

JAR 文件僅用于 .class 文件和其類路徑,不用于 .java 文件及其源路徑。







運行程序

現(xiàn)在您已經(jīng)成功地編譯了程序,可以運行它了。運行與編譯相似但更為簡單一些。當運行程序時,只需指定兩項內(nèi)容:

  • 類路徑。
  • 包含 main() 方法的類的完全限定包名。

無需指定源路徑。

通常這里的類路徑與編譯程序所使用的類路徑相同,只是多了一個放置編譯后的輸出的目錄。例如,如果編譯命令如下所示:

$ javac -d bin -sourcepath src
                        -classpath /Users/elharo/classes:/Users/elharo/lib/junit.jar
                        src/com/elharo/gui/MainFrame.java
                        

并且 main() 方法在 com.elharo.gui.Mainframe.java 類內(nèi),就可以像這樣運行此程序:

$ java
                        -classpath /Users/elharo/classes:/Users/elharo/lib/junit.jar
                        com.elharo.gui.MainFrame
                        

請務必注意命令行的最后一項是類名。它不是一個文件名,也不是 .java 或 .class。該類必須能夠在類路徑的某處找到。







可能存在類的其他地方

我強烈建議您在編譯和運行時總是顯式地指定類路徑。也可以將文件放到其他地方,以便它們可以被添加到類路徑中,并被 javac 編譯器和 java 解釋器找到。這種做法會節(jié)省一些鍵入操作,但當(注意不是如果)您無意間將一個舊版本的類放到類路徑中時,這卻會耗費大量的調(diào)試時間。

在本節(jié),將展示類常常隱匿其中的幾個地點,這些類很可能會出乎意料地冒到類路徑中并導致問題的出現(xiàn)。在不受您控制的機器上(比如服務器),這更為多見。

當前的工作目錄

編譯器總是將當前工作目錄 (.) 添加到類路徑,而不管您是否曾顯式地要求這樣做。您很容易忘記在和您所在的目錄相同的目錄中有和沒有的內(nèi)容。因此,請盡量避免將任何類或?qū)哟谓Y構放入 project 或 home 目錄。相反地,應該將 .java 文件和 .class 文件分別放入 src 目錄和 bin 目錄。

CLASSPATH

過一會,您就會發(fā)現(xiàn)向類路徑手工添加 bin 目錄和 JAR 歸檔文件太過繁瑣。這時您可能會想要使用 CLASSPATH 環(huán)境變量??梢灾幌?CLASSPATH 環(huán)境變量添加一次目錄和 JAR 歸檔文件,之后就不需要在每次運行 javac 或 java 時都要再鍵入這些路徑。

請務必抵制這種誘惑。這樣做,一旦加載了錯誤的類或錯誤版本的類,就會出問題。而且意外加載錯誤的類所帶來的調(diào)試時間常常會百倍于省下的那點鍵入時間。要避免輸入并自動處理類路徑有更好的方法。

jre/lib/ext

jre/lib/ext 目錄中的 JAR 歸檔文件會被添加到通過虛擬機運行的所有應用程序的類路徑。這看起來很方便,實際上它與向 CLASSPATH 環(huán)境變量添加目錄一樣,存在長遠的潛在問題。您遲早(通常很快)會在您想都想不到的地方加載類的一個錯誤版本的類并會為此付出大量的調(diào)試時間。

部署一個服務器端的應用程序時,問題就更為嚴峻。請確保部署到的服務器在其 jre/lib/ext 目錄沒有任何額外的 JAR。如果您不熟悉錯誤癥狀,也不知道該如何查找,那么由類路徑中的錯誤版本的 JAV 歸檔文件所帶來的問題可能會非常難于調(diào)試。為了避免這些問題的出現(xiàn),一些框架甚至編寫了自己的類加載器,用來繞過 Java 代碼通常的類加載機制。

jre/lib/endorsed

jre/lib/endorsed 目錄里的 JAR 文件 也被添加到了通過虛擬機運行的所有應用程序的類路徑。不同的是,這里的文件被實際放入了 bootclasspath 而不是通常的類路徑,并可以代替 JDK 附帶的標準類。這種方式對于在 VM 更新 XML 解析器和修復 bug 尤其有用。

但是,如前所述,這種方法看起來十分方便,但實際上也存在長期的潛在問題,原因也一樣。如果需要替換 JDK 類,可以在運行時使用 -Xbootclasspath/p 選項來避免意外地加載錯誤版本的類。

$ java -classpath /Users/elharo/classes
                        -Xbootclasspath/p:xercesImpl.jar com.elharo.gui.MainFrame
                        







自動管理類路徑

在想要使用電動射釘槍之前要先熟練使用錘子,與此相似,在試圖采用更強大的自動管理工具之前也要先能自如地手動管理這些類。如果您掌握了命令行工具集,就可以使用另外的工具來自動處理源路徑和類路徑所需的一些繁瑣過程。這些工具大部分也需要您像本文所介紹的那樣組織文件。

IDE

像 Eclipse 和 NetBeansMost 這樣的許多開發(fā)環(huán)境都能協(xié)助類路徑的自動管理。例如,當更改包的名稱時,Eclipse 能相應地移動對應的 .java 文件,如圖 5 所示:



圖 5. 在 Eclipse 中快速修復類路徑
移動 ‘Element.java’ 到 ‘nu.fox’ 包

請記住,這些 IDE 位于文件系統(tǒng)的頂部,必須正確設置,尤其是當需要與其他工具和其他 IDE 集成時就更應如此。這些工具最大的貢獻是用 GUI 對話框、樹視圖和選項卡代替了命令行開關參數(shù),但其基本的文件結構還是一樣的。

Ant

Ant 是自動化構建過程的事實上的標準工具。與將目錄放在 jre/lib/ext 或 CLASSPATH 環(huán)境變量的做法不同,Ant 真的可以讓您創(chuàng)建單步的構建過程。但您仍然需要在 Ant build.xml 設置類路徑并手動將源文件放到正確的目錄。但至少現(xiàn)在您無需在每次編譯都要重新進行指定。

Maven

Maven 在組織和自動化構建過程方面比 Ant 還要更進一步。Maven 提供一個合理的默認設置讓您可以通過添加少許幾行代碼并將源文件放到 Maven 能夠找到的位置即可構建簡單的項目。您仍然需要調(diào)整文件系統(tǒng)和包的層次結構。Maven 在管理第三方庫的依賴性方面也有上佳的表現(xiàn),雖然它不如 Ant 那么易于定制。







結束語

不管類路徑有多么棘手,您都可以通過一些簡單的規(guī)則對它加以管制,尤其是要記住如下的一些原則:

  • 將類放到包中。
  • 嚴格遵守包和類的命名約定和大小寫約定。
  • 確保包的層次結構與目錄的層次結構匹配。
  • 總是對 javac 應用 -d 選項。
  • 不要在 jre/lib/ext 內(nèi)放任何東西。
  • 不要在 jre/lib/endorsed 內(nèi)放任何東西。
  • 不要將 .java 文件與 .class 文件放在同一個目錄。
  • 不要將任何 .java 或 .class 文件放在當前的工作目錄。

最后一點提示:很多耗時的類路徑問題的起因大都是目錄名拼寫錯誤或從錯誤目錄進行了編譯。如果您不能找到問題的所在,可以問問周圍的朋友或同事。以我的經(jīng)驗,自己發(fā)現(xiàn)自己的錯誤總是困難的,但這些錯誤在別人看來卻顯而易見。所以尋求他人的幫助也是一種切實有效的調(diào)試技巧。

類路徑確實不是個簡單的問題,但總會有相應的應對方法,所以它是完全可管理的。些許的謹慎加上對本文所介紹的命名約定、命令行參數(shù)和目錄結構的注意,應該能夠使您在問題最少的情況下編譯和運行程序了。



參考資料

學習

獲得產(chǎn)品和技術
  • 下載 Ant:當前 Apache 的頂級項目。

  • 下載 Maven:Java 項目的 Apache 構建管理器。


討論


關于作者

Elliot Rusty Harold ??§???

Elliotte Rusty Harold 來自新奧爾良,現(xiàn)在他還定期回老家喝一碗美味的秋葵湯。不過目前,他和妻子 Beth 定居在紐約臨近布魯克林的 Prospect Heights,同住的還有他的貓咪 Charm(取自夸克)和 Marjorie(取自他岳母的名字)。他是 Polytechnic 大學計算機科學的副教授,他在該校講授 Java 和面向?qū)ο缶幊?。他?Web 站點 Cafe au Lait 已經(jīng)成為 Internet 上最流行的獨立 Java 站點之一,它的姊妹站點 Cafe con Leche 已經(jīng)成為最流行的 XML 站點之一。 他最近編著的一本書是 Java I/O, 2nd edition。他目前在從事處理 XML 的 XOM API、Jaxen XPath 引擎和 Jester 測試覆蓋率工具的開發(fā)工作。

    本站是提供個人知識管理的網(wǎng)絡存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權內(nèi)容,請點擊一鍵舉報。
    轉藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多

    亚洲成人久久精品国产| 人人妻人人澡人人夜夜| 亚洲熟妇熟女久久精品 | 午夜亚洲精品理论片在线观看| 亚洲精品国产精品日韩| 在线观看日韩欧美综合黄片| 欧美韩日在线观看一区| 亚洲香艳网久久五月婷婷| 国产熟女高清一区二区| 亚洲丁香婷婷久久一区| 亚洲av熟女一区二区三区蜜桃| 91后入中出内射在线| 久久大香蕉一区二区三区| 欧美国产在线观看精品| 国产精品久久香蕉国产线| 成人午夜视频在线播放| 97人妻精品一区二区三区免| 四季av一区二区播放| 日韩中文字幕在线不卡一区| 国产一区二区三区四区免费| 欧美一级特黄特色大色大片| 亚洲欧美日本成人在线| 日本不卡一本二本三区| 日韩中文无线码在线视频 | 日本高清二区视频久二区| 九九热九九热九九热九九热| 欧美日韩国产成人高潮| 欧美大胆美女a级视频| 91亚洲国产—区=区a| 亚洲丁香婷婷久久一区| 亚洲精选91福利在线观看 | 欧美国产在线观看精品| 欧美色欧美亚洲日在线| 日韩精品免费一区二区三区| 国产精品一区二区不卡中文| 欧美日韩精品人妻二区三区| 中文字幕有码视频熟女| 国产成人精品一区二三区在线观看| 国产亚洲系列91精品| 插进她的身体里在线观看骚| 欧美日韩高清不卡在线播放|