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

深度探討Java字節代碼的操縱方法

開發 后端
本文為IBM工程師成富編寫的《Java深度歷險》的第一部分Java字節代碼的操縱,像這樣Java語言的深度理解和運用還沒有很多文章,我們把他奉獻給讀者,希望讀者們喜歡。

51CTO編者按:我們曾給大家介紹過Java字節碼文件操作技巧。Java作為業界應用最為廣泛的語言之一,深得眾多軟件廠商和開發者的推崇,更是被包括Oracle在內的眾多JCP成員積極地推動發展。但是對于Java語言的深度理解和運用,畢竟是很少會有人涉及的話題。本文為IBM工程師成富編寫的《Java深度歷險》的***部分Java字節代碼的操縱,希望讀者們喜歡。

在一般的Java應用開發過程中,開發人員使用Java的方式比較簡單。打開慣用的IDE,編寫Java源代碼,再利用IDE提供的功能直接運行Java 程序就可以了。這種開發模式背后的過程是:開發人員編寫的是Java源代碼文件(.java),IDE會負責調用Java的編譯器把Java源代碼編譯成平臺無關的字節代碼(byte code),以類文件的形式保存在磁盤上(.class)。Java虛擬機(JVM)會負責把Java字節代碼加載并執行。Java通過這種方式來實現其“編寫一次,到處運行(Write once, run anywhere)” 的目標。Java類文件中包含的字節代碼可以被不同平臺上的JVM所使用。Java字節代碼不僅可以以文件形式存在于磁盤上,也可以通過網絡方式來下載,還可以只存在于內存中。JVM中的類加載器會負責從包含字節代碼的字節數組(byte[])中定義出Java類。在某些情況下,可能會需要動態的生成 Java字節代碼,或是對已有的Java字節代碼進行修改。這個時候就需要用到本文中將要介紹的相關技術。首先介紹一下如何動態編譯Java源文件。

動態編譯Java源文件

在一般情況下,開發人員都是在程序運行之前就編寫完成了全部的Java源代碼并且成功編譯。對有些應用來說,Java源代碼的內容在運行時刻才能確定。這個時候就需要動態編譯源代碼來生成Java字節代碼,再由JVM來加載執行。典型的場景是很多算法競賽的在線評測系統(如PKU JudgeOnline),允許用戶上傳Java代碼,由系統在后臺編譯、運行并進行判定。在動態編譯Java源文件時,使用的做法是直接在程序中調用Java編譯器。

JSR 199引入了Java編譯器API。如果使用JDK 6的話,可以通過此API來動態編譯Java代碼。比如下面的代碼用來動態編譯最簡單的Hello World類。該Java類的代碼是保存在一個字符串中的。

 

  1. public class CompilerTest {  
  2.    public static void main(String[] args) throws Exception {        
  3.       String source = "public class Main { public static void main(String[] args) {System.out.println(\"Hello World!\");} }";  
  4.       JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();  
  5.       StandardJavaFileManager fileManager = compiler.getStandardFileManager(null, null, null);  
  6.       StringSourceJavaObject sourceObject = new CompilerTest.StringSourceJavaObject("Main", source);  
  7.       Iterable< extends JavaFileObject> fileObjects = Arrays.asList(sourceObject);  
  8.       CompilationTask task = compiler.getTask(null, fileManager, null, null, null, fileObjects);  
  9.       boolean result = task.call();  
  10.       if (result) {  
  11.          System.out.println("編譯成功。");  
  12.       }  
  13.    }  
  14.  
  15.    static class StringSourceJavaObject extends SimpleJavaFileObject {  
  16.  
  17.       private String content = null;  
  18.       public StringSourceJavaObject(String name, String content) ??throws URISyntaxException {  
  19.          super(URI.create("string:///" + name.replace('.','/') + Kind.SOURCE.extension), Kind.SOURCE);  
  20.          this.content = content;  
  21.       }  
  22.  
  23.       public CharSequence getCharContent(boolean ignoreEncodingErrors) ??throws IOException {  
  24.          return content;  
  25.       }  
  26.    }  
  27. }  
  28.  

如果不能使用JDK 6提供的Java編譯器API的話,可以使用JDK中的工具類com.sun.tools.javac.Main,不過該工具類只能編譯存放在磁盤上的文件,類似于直接使用javac命令。

另外一個可用的工具是Eclipse JDT Core提供的編譯器。這是Eclipse Java開發環境使用的增量式Java編譯器,支持運行和調試有錯誤的代碼。該編譯器也可以單獨使用。Play框架在內部使用了JDT的編譯器來動態編譯Java源代碼。在開發模式下,Play框架會定期掃描項目中的Java源代碼文件,一旦發現有修改,會自動編譯 Java源代碼。因此在修改代碼之后,刷新頁面就可以看到變化。使用這些動態編譯的方式的時候,需要確保JDK中的tools.jar在應用的 CLASSPATH中。

下面介紹一個例子,是關于如何在Java里面做四則運算,比如求出來(3+4)*7-10的值。一般的做法是分析輸入的運算表達式,自己來模擬計算過程。考慮到括號的存在和運算符的優先級等問題,這樣的計算過程會比較復雜,而且容易出錯。另外一種做法是可以用JSR 223引入的腳本語言支持,直接把輸入的表達式當做JavaScript或是JavaFX腳本來執行,得到結果。下面的代碼使用的做法是動態生成Java源代碼并編譯,接著加載Java類來執行并獲取結果。這種做法完全使用Java來實現。

  1. private static double calculate(String expr) throws CalculationException  {  
  2.    String className = "CalculatorMain";  
  3.    String methodName = "calculate";  
  4.    String source = "public class " + className   
  5.       + " { public static double " + methodName + "() { return " + expr + "; } }";  
  6.    //省略動態編譯Java源代碼的相關代碼,參見上一節  
  7.    boolean result = task.call();  
  8.    if (result) {  
  9.       ClassLoader loader = Calculator.class.getClassLoader();   
  10.       try {              
  11.          Class<?> clazz = loader.loadClass(className);  
  12.          Method method = clazz.getMethod(methodName, new Class<?>[] {});  
  13.          Object value = method.invoke(null, new Object[] {});  
  14.          return (Double) value;  
  15.       } catch (Exception e) {  
  16.          throw new CalculationException("內部錯誤。");          
  17.       }      
  18.    } else {  
  19.       throw new CalculationException("錯誤的表達式。");      
  20.    }  
  21. }  
  22.  

上面的代碼給出了使用動態生成的Java字節代碼的基本模式,即通過類加載器來加載字節代碼,創建Java類的對象的實例,再通過Java反射API來調用對象中的方法。

Java字節代碼增強

Java 字節代碼增強指的是在Java字節代碼生成之后,對其進行修改,增強其功能。這種做法相當于對應用程序的二進制文件進行修改。在很多Java框架中都可以見到這種實現方式。Java字節代碼增強通常與Java源文件中的注解(annotation)一塊使用。注解在Java源代碼中聲明了需要增強的行為及相關的元數據,由框架在運行時刻完成對字節代碼的增強。Java字節代碼增強應用的場景比較多,一般都集中在減少冗余代碼和對開發人員屏蔽底層的實現細節上。用過JavaBeans的人可能對其中那些必須添加的getter/setter方法感到很繁瑣,并且難以維護。而通過字節代碼增強,開發人員只需要聲明Bean中的屬性即可,getter/setter方法可以通過修改字節代碼來自動添加。用過JPA的人,在調試程序的時候,會發現實體類中被添加了一些額外的 域和方法。這些域和方法是在運行時刻由JPA的實現動態添加的。字節代碼增強在面向方面編程(AOP)的一些實現中也有使用。

在討論如何進行字節代碼增強之前,首先介紹一下表示一個Java類或接口的字節代碼的組織形式。

類文件

  1.  {  
  2.    0xCAFEBABE,小版本號,大版本號,常量池大小,常量池數組,  
  3.    訪問控制標記,當前類信息,父類信息,實現的接口個數,實現的接口信息數組,域個數,  
  4.    域信息數組,方法個數,方法信息數組,屬性個數,屬性信息數組  
  5. }  

如上所示,一個類或接口的字節代碼使用的是一種松散的組織結構,其中所包含的內容依次排列。對于可能包含多個條目的內容,如所實現的接口、域、方法和屬性等,是以數組來表示的。而在數組之前的是該數組中條目的個數。不同的內容類型,有其不同的內部結構。對于開發人員來說,直接操縱包含字節代碼的字節數組的話,開發效率比較低,而且容易出錯。已經有不少的開源庫可以對字節代碼進行修改或是從頭開始創建新的Java類的字節代碼內容。這些類庫包括ASM、cglib、serp和BCEL等。使用這些類庫可以在一定程度上降低增強字節代碼的復雜度。比如考慮下面一個簡單的需求,在一個Java類的所有方法執行之前輸出相應的日志。熟悉AOP的人都知道,可以用一個前增強(before advice)來解決這個問題。如果使用ASM的話,相關的代碼如下:

  1. ClassReader cr = new ClassReader(is);  
  2. ClassNode cn = new ClassNode();  
  3. cr.accept(cn, 0);  
  4. for (Object object : cn.methods) {      
  5.    MethodNode mn = (MethodNode) object;     
  6.    if ("<init>".equals(mn.name) || "<clinit>".equals(mn.name)) {          
  7.       continue;      
  8.    }      
  9.    InsnList insns = mn.instructions;      
  10.    InsnList il = new InsnList();     
  11.    il.add(new FieldInsnNode(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;"));      
  12.    il.add(new LdcInsnNode("Enter method -> " + mn.name));     
  13.    il.add(new MethodInsnNode(INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V"));      
  14.    insns.insert(il);  mn.maxStack += 3;  
  15. }  
  16. ClassWriter cw = new ClassWriter(0);  
  17. cn.accept(cw);  
  18. byte[] b = cw.toByteArray();  
  19.  

從ClassWriter就可以獲取到包含增強之后的字節代碼的字節數組,可以把字節代碼寫回磁盤或是由類加載器直接使用。上述示例中,增強部分的邏輯比較簡單,只是遍歷Java類中的所有方法并添加對System.out.println方法的調用。在字節代碼中,Java方法體是由一系列的指令組成的。而要做的是生成調用System.out.println方法的指令,并把這些指令插入到指令集合的最前面。ASM對這些指令做了抽象,不過熟悉全部的指令比較困難。ASM提供了一個工具類ASMifierClassVisitor,可以打印出Java類的字節代碼的結構信息。當需要增強某個類的時候,可以先在源代碼上做出修改,再通過此工具類來比較修改前后的字節代碼的差異,從而確定該如何編寫增強的代碼。

對類文件進行增強的時機是需要在Java源代碼編譯之后,在JVM執行之前。比較常見的做法有:

由IDE在完成編譯操作之后執行。如Google App Engine的Eclipse插件會在編譯之后運行DataNucleus來對實體類進行增強。

在構建過程中完成,比如通過Ant或Maven來執行相關的操作。

實現自己的Java類加載器。當獲取到Java類的字節代碼之后,先進行增強處理,再從修改過的字節代碼中定義出Java類。

通過JDK 5引入的java.lang.instrument包來完成。

  1. java.lang.instrument 

由于存在著大量對Java字節代碼進行修改的需求,JDK 5引入了java.lang.instrument包并在JDK 6中得到了進一步的增強?;镜乃悸肥窃贘VM啟動的時候添加一些代理(agent)。每個代理是一個jar包,其清單(manifest)文件中會指定一個代理類。這個類會包含一個premain方法。JVM在啟動的時候會首先執行代理類的premain方法,再執行Java程序本身的main方法。在 premain方法中就可以對程序本身的字節代碼進行修改。JDK 6中還允許在JVM啟動之后動態添加代理。java.lang.instrument包支持兩種修改的場景,一種是重定義一個Java類,即完全替換一個 Java類的字節代碼;另外一種是轉換已有的Java類,相當于前面提到的類字節代碼增強。還是以前面提到的輸出方法執行日志的場景為例,首先需要實現java.lang.instrument.ClassFileTransformer接口來完成對已有Java類的轉換。

  1. static class MethodEntryTransformer implements ClassFileTransformer {  
  2.    public byte[] transform(ClassLoader loader, String className,  
  3.      Class<?> classBeingRedefined, ?ProtectionDomain protectionDomain, byte[] classfileBuffer)   
  4.      throws  IllegalClassFormatException {  
  5.         try {  
  6.            ClassReader cr = new ClassReader(classfileBuffer);  
  7.            ClassNode cn = new ClassNode();              
  8.            //省略使用ASM進行字節代碼轉換的代碼              
  9.            ClassWriter cw = new ClassWriter(0);  
  10.            cn.accept(cw);   
  11.            return cw.toByteArray();         
  12.         } catch (Exception e){              
  13.            return null;  
  14.         }  
  15.    }  

有了這個轉換類之后,就可以在代理的premain方法中使用它。

  1. public static void premain(String args, Instrumentation inst) {      
  2.    inst.addTransformer(new MethodEntryTransformer());  

把該代理類打成一個jar包,并在jar包的清單文件中通過Premain-Class聲明代理類的名稱。運行Java程序的時候,添加JVM啟動參數-javaagent:myagent.jar。這樣的話,JVM會在加載Java類的字節代碼之前,完成相關的轉換操作。

總結

操縱Java字節代碼是一件很有趣的事情。通過它,可以很容易的對二進制分發的Java程序進行修改,非常適合于性能分析、調試跟蹤和日志記錄等任務。另外一個非常重要的作用是把開發人員從繁瑣的Java語法中解放出來。開發人員應該只需要負責編寫與業務邏輯相關的重要代碼。對于那些只是因為語法要求而添加的,或是模式固定的代碼,完全可以將其字節代碼動態生成出來。字節代碼增強和源代碼生成是不同的概念。源代碼生成之后,就已經成為了程序的一部分,開發人員需要去維護它:要么手工修改生成出來的源代碼,要么重新生成。而字節代碼的增強過程,對于開發人員是完全透明的。妥善使用Java字節代碼的操縱技術,可以更好的解決某一類開發問題。

【編輯推薦】

  1. Java的簡單數據類型
  2. Java字節碼文件操作技巧
  3. Java編譯過程與C/C++編譯過程有何不同
  4. Java代碼的靜態編譯和動態編譯中的問題比較
  5. 防止Java字節碼反編譯問題解決方案
責任編輯:佚名 來源: InfoQ
相關推薦

2011-03-15 14:16:20

JsonObject

2024-03-07 12:40:28

Python*args開發

2023-12-22 08:46:15

useEffectVueMobx

2009-11-05 09:01:41

WinForm

2010-05-24 17:13:34

Linux SNMP

2018-03-14 08:10:44

深度學習

2010-03-19 09:12:05

JRuby

2010-03-17 14:33:44

云計算

2024-03-15 09:00:00

2010-01-27 16:10:32

C++靜態構造函數

2016-10-14 13:46:26

2009-12-02 19:42:24

PHP頁面自動跳轉

2009-12-01 16:34:21

PHP表單

2009-12-15 13:59:42

Ruby對象操作

2010-03-17 15:54:42

Java線程控制權

2023-08-30 11:03:47

Java工具

2010-01-04 17:29:00

Silverlight

2010-02-03 10:50:33

C++多態

2021-06-15 09:10:41

漏洞網絡安全程序員

2017-06-09 15:58:23

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

51CTO技術棧公眾號

五月婷婷在线视频| 成人一级免费视频| 美女扒开腿让男人桶爽久久动漫| 婷婷开心激情综合| 亚洲午夜高清视频| 亚洲精品911| 老鸭窝毛片一区二区三区| 少妇高潮久久77777| 最新日本中文字幕| jvid一区二区三区| 性感美女久久精品| 午夜精品一区二区三区四区| 亚洲国产精品久久久久爰性色| 美女精品一区| 久久99热这里只有精品国产| 欧美高清性xxxx| 日本精品国产| 欧美伊人久久大香线蕉综合69| 成人av在线播放观看| 岛国视频免费在线观看| 不卡视频在线看| 91久久久久久久久久久久久| 东京热一区二区三区四区| 一个色综合网| 一区二区在线视频播放| 老司机免费视频| 日韩精品久久久久久久软件91| 91久久一区二区| 黄色片网址在线观看| av在线free| 一区在线观看免费| 天天综合狠狠精品| 天堂√在线中文官网在线| 国产成人自拍在线| 91中文在线观看| 亚洲图片欧美在线| 日韩不卡一二三区| 日韩av观看网址| 91香蕉在线视频| 国内自拍视频一区二区三区| 超碰97人人做人人爱少妇| 国产视频不卡在线| 欧美精品羞羞答答| 国产亚洲精品综合一区91| 国产精品1000部啪视频| 奇米影视777在线欧美电影观看| 日韩一区二区在线观看| 最新免费av网址| www.成人在线视频| 欧美体内she精视频| 宅男噜噜噜66国产免费观看| 成人美女黄网站| 日韩欧美亚洲一二三区| 久色视频在线播放| 阿v视频在线观看| 无吗不卡中文字幕| 女人天堂av手机在线| 老牛影视精品| 欧美午夜宅男影院在线观看| 亚洲自偷自拍熟女另类| 美女的胸无遮挡在线观看| 天天综合天天做天天综合| 91视频最新入口| av在线日韩| 欧美视频一区二区三区四区| 天天爽天天爽夜夜爽| 日本免费成人| 日韩视频免费观看高清完整版| 精产国品一区二区三区| 大陆精大陆国产国语精品| 亚洲精品久久久久中文字幕二区| 野外性满足hd| 精品国产午夜| 久热国产精品视频| 久久免费视频99| 国产伦理一区| 国产精品三级久久久久久电影| 依依成人在线视频| 国产福利电影一区二区三区| 91黄在线观看| 视频国产在线观看| 国产精品日韩精品欧美在线| 最近免费观看高清韩国日本大全| 大桥未久在线播放| 色又黄又爽网站www久久| 中文字幕av不卡在线| 国产精品一区二区三区四区在线观看 | 国产精品免费一区二区三区观看| 天天综合网在线| 中文字幕乱码日本亚洲一区二区 | 国产精品乱子乱xxxx| 日本五码在线| 亚洲人成网站精品片在线观看| 亚洲精品久久久久久久蜜桃臀| 欧美美女日韩| 日韩区在线观看| 六月婷婷七月丁香| 欧美久久一区| 国产精品h片在线播放| 国产精品久久久久久久免费| 99国产一区二区三精品乱码| 欧美 另类 交| 345成人影院| 日韩一区二区中文字幕| av手机在线播放| 黄色日韩精品| 成人做爰www免费看视频网站| 五月婷婷开心中文字幕| 亚洲色图欧洲色图婷婷| 麻豆av免费在线| 欧美一级大片在线视频| 亚洲视频在线播放| 亚欧视频在线观看| 国产成人av一区二区三区在线 | 日韩电影在线观看电影| 国产高清自拍99| 欧美日韩欧美| 欧洲一区二区av| 尤物网站在线观看| 亚洲精彩视频| 国产精品入口日韩视频大尺度| 五月色婷婷综合| 亚洲综合在线观看视频| 久久人人爽av| 日韩免费在线| 国产精品欧美风情| 深夜福利视频一区| 亚洲国产一区二区三区| 国产精品探花在线播放| 精品一区不卡| 国产精品久久久久久久久久尿| 天天色综合久久| 亚洲五码中文字幕| 国产免费无码一区二区| 中文字幕一区二区av | 久久久久久久色| 99热这里只有精| 亚洲视频图片小说| 天堂在线一区二区三区| 手机在线电影一区| 国产精品十八以下禁看| fc2在线中文字幕| 欧洲国产伦久久久久久久| 亚洲午夜久久久久久久久红桃| 一区视频在线| 国产亚洲欧美另类一区二区三区| 国产桃色电影在线播放| 亚洲成人久久久久| 日韩精品乱码久久久久久| 懂色av一区二区三区蜜臀| 无码熟妇人妻av在线电影| 99a精品视频在线观看| 久久久久亚洲精品| 日韩专区第一页| 精品久久久久久中文字幕| 三叶草欧洲码在线| 久久精品系列| 亚洲精美视频| 国产精品免费精品自在线观看| 久久久国产一区二区| 国产高清在线观看视频| 亚洲午夜精品网| 国产三级国产精品| 青青青伊人色综合久久| 在线观看日韩片| 视频一区中文字幕精品| 97香蕉超级碰碰久久免费软件| 日本福利在线观看| 欧美色图一区二区三区| 日韩精品一区二区三区在线视频| 国产成人高清在线| www.中文字幕在线| 色综合天天爱| 国产精品传媒毛片三区| 亚洲第一av| 日韩在线视频观看| 国产黄a三级三级看三级| 婷婷久久综合九色综合绿巨人| 性欧美一区二区| 国产一区久久久| 成人毛片一区二区| 久久中文视频| 国内精品久久国产| 91精品国产66| 国精产品一区一区三区有限在线| 日韩a在线观看| 在线综合亚洲欧美在线视频| 欧美精品色哟哟| 国产婷婷色一区二区三区在线| 日韩av片免费观看| 99国产精品99久久久久久粉嫩| 日本10禁啪啪无遮挡免费一区二区| 亚洲综合伊人| 日韩av观看网址| 日本动漫同人动漫在线观看| 在线免费观看羞羞视频一区二区| a级片免费视频| 在线观看视频一区二区 | 亚洲黄色毛片| 夜夜春亚洲嫩草影视日日摸夜夜添夜| eeuss国产一区二区三区四区| 国产精品久久久久久久久久东京| 俄罗斯一级**毛片在线播放| 在线观看日韩专区| 午夜激情小视频| 91精品国产色综合久久不卡电影| 日韩欧美成人一区二区三区| 亚洲精品免费播放| 久久久精品成人| 99精品在线免费| 亚洲欧美日韩网站| 青青草97国产精品免费观看 | 久久男人av资源站| 久久亚洲影音av资源网 | 欧美黄色成人网| 在线观看麻豆| 亚洲视频欧美视频| 特级丰满少妇一级aaaa爱毛片| 4438x成人网最大色成网站| 久久久久久久久久一级| 高跟丝袜一区二区三区| 国产亚洲精品久久777777| 中文字幕一区二区三区色视频| 97伦伦午夜电影理伦片| 懂色一区二区三区免费观看| 中文 日韩 欧美| 久久精品国产77777蜜臀| 北条麻妃在线一区| 亚洲综合国产| 奇米精品一区二区三区| 在线观看视频日韩| 成人区一区二区| 欧美激情综合色综合啪啪| 国产一二三四五| 欧美福利专区| 黄色一级大片免费| 中文字幕免费精品| 337p亚洲精品色噜噜狠狠p| 影音先锋日韩精品| 成人午夜免费剧场| 欧美一区91| 欧美一二三不卡| 亚洲三级电影在线观看| 草草视频在线免费观看| 日韩午夜一区| 久久国产亚洲精品无码| 亚洲欧美卡通另类91av| 国产精品亚洲αv天堂无码| 国产亚洲精品久久久久婷婷瑜伽| 久久久久久久久久久视频| 欧美一级一区| www日韩视频| 麻豆久久久久久久| 国产精品久久久久久久av福利| 狠狠色综合日日| 三大队在线观看| 成人av免费网站| 亚洲天堂资源在线| 久久九九影视网| 男人天堂av电影| 国产精品国产三级国产aⅴ无密码| 欧美手机在线观看| 亚洲一区二区三区精品在线| 国产午夜久久久| 在线观看日韩av先锋影音电影院| 怡春院在线视频| 精品欧美久久久| 全部免费毛片在线播放网站| 在线观看国产欧美| 色呦呦网站在线观看| 91av中文字幕| 日韩高清不卡| 97久久天天综合色天天综合色hd | 大桥未久一区二区| 黄色av日韩| 国产xxxxx视频| 国产激情精品久久久第一区二区| 中文字幕在线视频播放| 久久美女艺术照精彩视频福利播放| 国产三级在线观看完整版| 亚洲综合一区二区精品导航| 亚洲自拍一区在线观看| 91精品国产欧美一区二区18| 天堂av在线免费| 最新国产成人av网站网址麻豆| 日本性爱视频在线观看| 日本高清久久天堂| 国产一区二区三区国产精品| 国内成+人亚洲| 婷婷成人基地| 少妇高清精品毛片在线视频| 国产在线乱码一区二区三区| 国产偷人妻精品一区| 亚洲人亚洲人成电影网站色| www成人在线| 91精品国产色综合久久| 国产区视频在线| 久久久久久伊人| 欧美伊人亚洲伊人色综合动图| 精品日本一区二区三区| 久久精品久久久| 凹凸日日摸日日碰夜夜爽1| 国产成人福利片| 久久人妻无码aⅴ毛片a片app | 亚洲欧美色图小说| 免费黄色av片| 亚洲精品白浆高清久久久久久| 欧美性猛交xxx乱大交3蜜桃| 日本午夜人人精品| 免费看久久久| 日韩精品一区二区在线视频| 美国欧美日韩国产在线播放| av直播在线观看| 亚洲一区自拍偷拍| 国产日韩精品suv| 中文字幕欧美日韩精品| 二吊插入一穴一区二区| 国产一区高清视频| 午夜精品偷拍| 91视频免费入口| 亚洲色图在线播放| 国产精品无码一区| 亚洲视频国产视频| 日韩大片欧美大片| 看欧美日韩国产| 国产欧美一级| 99re久久精品国产| 亚洲1区2区3区视频| 精品区在线观看| 精品中文字幕视频| 无码国模国产在线观看| 艳母动漫在线观看| 国产最新精品免费| 顶级黑人搡bbw搡bbbb搡| 欧美日韩在线三区| avtt亚洲| 国产三级精品网站| 羞羞色午夜精品一区二区三区| 91国产精品视频在线观看| 国产亚洲精品7777| 日韩不卡高清视频| 亚洲性无码av在线| 中文.日本.精品| 五月天丁香综合久久国产| 日韩精品1区2区3区| 一区二区精品免费| 欧美在线不卡一区| 欧美极品视频| 91pron在线| 99在线精品免费视频九九视| 人妻无码中文久久久久专区| 欧美日韩裸体免费视频| 精品成人一区二区三区免费视频| 国产精品91免费在线| 日韩欧美综合| avtt中文字幕| 五月综合激情网| 国产在线91| 国产在线视频欧美| 欧美日韩国产欧| av直播在线观看| 欧美人动与zoxxxx乱| 最新超碰在线| 九色91在线视频| 免费高清在线一区| 农村黄色一级片| 亚洲第一视频网站| 裤袜国产欧美精品一区| 中文视频一区视频二区视频三区| 国产毛片精品一区| 亚洲天堂视频网站| 日韩天堂在线视频| 99re8这里有精品热视频8在线| 国产女女做受ⅹxx高潮| 国产精品电影一区二区| 午夜久久久久久久久久| 91超碰中文字幕久久精品| 日韩免费久久| 日韩av无码一区二区三区不卡 | 91av在线播放视频| 成人在线免费观看网站| 日本亚洲一区二区三区| 欧美日韩另类在线| а√天堂在线官网| 久久综合一区| 国产精品一区二区免费不卡 | 亚洲精品午夜久久久久久久| 亚洲人成在线观看| 欧美专区视频| 91香蕉视频污版| 亚洲国产精品久久一线不卡| 裸体xxxx视频在线| 99热在线播放| 日本伊人色综合网| 国产欧美日韩另类| 欧美超级免费视 在线| 亚洲人和日本人hd| 无套内谢丰满少妇中文字幕| 91成人国产精品| 啊啊啊久久久|