欧美日韩亚-欧美日韩亚州在线-欧美日韩亚洲-欧美日韩亚洲第一区-欧美日韩亚洲二区在线-欧美日韩亚洲高清精品

金喜正规买球

深度剖析Java中的Lambda表達式

原創|行業資訊|編輯:郝浩|2017-08-11 17:52:08.000|閱讀 1090 次

概述:本文將從字節碼(Bytecode)的級別研究Lambda表達式是如何工作的,以及如何將它與getter、setter和其它技巧組合起來的。

# 界面/圖表報表/文檔/IDE等千款熱門軟控件火熱銷售中 >>

在本文中,我們將介紹Java 8中Lambda表達式的一些鮮為人知的技巧及其局限性,其主要受眾包括中高級Java開發人員、研究人員和工具編寫者。在這里我們將只使用公共Java API而不使用com.sun和其它的內部類,因此代碼可以在不同的JVM中實現。

快速介紹


Lambda表達式在Java 8中被引入,作為一種實現匿名函數的方法,在某些情況下,可作為匿名類的替代方案。在字節碼(Bytecode)的級別中,Lambda表達式用invokedynamic指令替代,該指令能夠簡化JVM上動態類型語言的編譯器和運行時系統的實現。其delegates類能夠調用Lambda主體內所定義的代碼的實例。

例如,我們有以下代碼:

void printElements(List<String> strings){
    strings.forEach(item -> System.out.println("Item = %s", item));
}

這段代碼由Java編譯器編譯后成為這樣:

private static void lambda_forEach(String item) { //generated by Java compiler
    System.out.println("Item = %s", item);
}
private static CallSite bootstrapLambda(Lookup lookup, String name, MethodType type) { //
    //lookup = provided by VM
    //name = "lambda_forEach", provided by VM
    //type = String -> void
    MethodHandle lambdaImplementation = lookup.findStatic(lookup.lookupClass(), name, type);
    return LambdaMetafactory.metafactory(lookup,
        "accept",
        MethodType.methodType(Consumer.class), //signature of lambda factory
        MethodType.methodType(void.class, Object.class), //signature of method Consumer.accept after type erasure  
        lambdaImplementation, //reference to method with lambda body
        type);
}
void printElements(List < String > strings) {
    Consumer < String > lambda = invokedynamic# bootstrapLambda, #lambda_forEach
    strings.forEach(lambda);
}

invokedynamic指令可以將其粗略地表達為以下代碼:

private static CallSite cs;
void printElements(List < String > strings) {
    Consumer < String > lambda;
    //begin invokedynamic
    if (cs == null)
        cs = bootstrapLambda(MethodHandles.lookup(), "lambda_forEach", MethodType.methodType(void.class, String.class));
    lambda = (Consumer < String > ) cs.getTarget().invokeExact();
    //end invokedynamic
    strings.forEach(lambda);
}

正如你所看到的,LambdaMetafactory用于生成某個目標函數(匿名類)在工廠模式下的調用點(call site)。而工廠模式會返回這個函數接口在使用invokeExact的實現結果。如果Lambda附加了變量,那么invokeExact將會把這些變量作為實際參數。

在Oracle JRE 8中,metafactory會使用,通過實現函數接口的方式,動態生成一個Java類。如果Lambda表達式包含外部變量,則可以在生成類中添加附加字段。這種方法類似于Java語言中的匿名類,但有以下的不同點:

  • 匿名類是由Java編譯器在編譯時生成的。
  • 而Lambda實現的類是由JVM在運行時生成的。

注意:metafactory的實現依賴于JVM供應商和版本

invokedynamic指令并不只用于Java中的Lambda表達式,該指令的引入主要是為了JVM之上動態語言的運行。Nashorn,Java開箱即用的下一代JavaScript引擎中大量地使用了這個指令。

在本文的后面部分,我們將重點討論LambdaMetafactory類及其功能。本文的下一節是基于假設你完全理解了metafactory方法的工作原理和方法。

關于Lambda的技巧


在本節中我們將介紹如何在日常任務中使用Lambda的動態構建。

Lambda與受檢查異常(Checked Exception

并不是Java提供的所有函數接口都支持受檢查異常。是否支持受檢查異常在Java世界中是一場古老的圣戰。

如果為了結合使用Java Stream,你需要lambda中含有受檢查異常的代碼,那該怎么做?比如,我們需要將字符串列表轉換成這樣的url列表:

Arrays.asList("//localhost/", "//github.com")
.stream()
.map(URL::new)
.collect(Collectors.toList())

在throws中已聲明了受檢查異常,因此,它不能在中直接作為函數引用。

你可能會說:“這沒問題啊,我可以這么干。”

public static <T> T uncheckCall(Callable<T> callable) {
  try { return callable.call(); }
  catch (Exception e) { return sneakyThrow(e); }
}
private static <E extends Throwable, T> T sneakyThrow0(Throwable t) throws E { throw (E)t; }
public static <T> T sneakyThrow(Throwable e) {
  return Util.<RuntimeException, T>sneakyThrow0(e);
}
// Usage sample
//return s.filter(a -> uncheckCall(a::isActive))
//        .map(Account::getNumber)
//        .collect(toSet());

這個做法并不高明,原因如下:

  • 使用了try-catch語句。
  • 重新拋出了異常。
  • 使用了Java的類型擦除。

上述行為所想要解決的問題我們可以更“規范”的作如下表達:

  • 受檢查異常只能由Java語言的編譯器來識別。
  • 在JVM級別上,throws的異常只是無語義函數的元數據。
  • 在字節碼和JVM級別,受檢查異常和非受檢查異常不易區分。

解決方法是在函數中包裹Callable.call的調用,而不引入throws的部分:

static <V> V callUnchecked(Callable<V> callable){
    return callable.call();
}

這段代碼不會被Java編譯器所編譯,因為Callable.call的throws部分包含受檢查異常。但是我們可以使用動態構建的lambda表達式來刪除這個部分。

首先,我們應當聲明一個沒有throws部分但能夠委托調用Callable.call的函數接口:

@FunctionalInterface
interface SilentInvoker {
    MethodType SIGNATURE = MethodType.methodType(Object.class, Callable.class);//signature of method INVOKE
    <V> V invoke(final Callable<V> callable);
}

第二步是使用LambdaMetafactory創建這個接口的實現,并委托SilentInvoker.invoke調用Callable.call。如前所述,在字節碼級別,throws部分被忽略了,因此,SilentInvoker.invoke可以在不聲明受檢查異常的情況下調用Callable.call。

private static final SilentInvoker SILENT_INVOKER;
final MethodHandles.Lookup lookup = MethodHandles.lookup();
final CallSite site = LambdaMetafactory.metafactory(lookup,
                    "invoke",
                    MethodType.methodType(SilentInvoker.class),
                    SilentInvoker.SIGNATURE,
                    lookup.findVirtual(Callable.class, "call", MethodType.methodType(Object.class)),
                    SilentInvoker.SIGNATURE);
SILENT_INVOKER = (SilentInvoker) site.getTarget().invokeExact();

第三步編寫在不需要聲明受檢查異常的情況下調用Callable.call的函數。

public static <V> V callUnchecked(final Callable<V> callable) /*no throws*/ {
    return SILENT_INVOKER.invoke(callable);
}

現在,我們可以毫無問題的使用檢查異常重寫stream。

Arrays.asList("//localhost/", "//dzone.com")
.stream()
.map(url -> callUnchecked(() -> new URL(url)))
.collect(Collectors.toList());

這段代碼會被成功編譯,因為callUnchecked沒有聲明受檢查異常。此外,由于JVM中只有一個類來實現接口SilentInvoker,因此調用此方法可能會使用單態內聯緩存。

如果Callable.call在運行時拋出了一些異常,它將會通過調用來進行捕捉,而不會出現任何問題:

try{
    callUnchecked(() -> new URL("Invalid URL"));
} catch (final Exception e){
    System.out.println(e);
}

盡管有這樣的方法來實現功能,但我還是強烈推薦以下的用法:

只有當調用代碼保證了無異常產生的情況下才使用callUnchecked隱藏受檢查異常。

下面的示例演示了這種方法:

callUnchecked(() -> new URL("//dzone.com")); //this URL is always valid and the constructor never throws MalformedURLException

這個方法的可在開源項目中找到。

與Getters和Setters的協同工作

這一節對于編寫JSON、Thrift等不同格式的序列化/反序列化的程序員很有幫助。另外,如果你的代碼嚴重依賴于用于JavaBean的getter和setter的Java反射,那么它將讓你收益良多。

JavaBean中聲明的getter,命名為getXXX,是無參數和非void返回類型的函數,JavaBean中聲明的setter,命名為setXXX,是帶有單個參數和返回類型為void的函數。它們可以表示為這樣的函數接口:

  • getter可以表示為一個函數參數由this引用的 。
  • setter可以表示為一個第一參數由this引用,第二參數為傳遞給setter的。

現在我們創建兩個可將任意getter或setter轉換成這些函數接口的方法。這兩個函數接口是否為泛型并不重要。在類型消除之后,實際的類型等于對象。自動選擇返回類型和參數可以由LambdaMetafactory完成。此外,有助于緩存有相同getter或setter的lambda。

首先,有必要為getter和setter聲明一個緩存,來自Reflection API的代表了當前getter或setter,并作為一個key使用。緩存中的值表示特定getter或setter的動態構造函數接口。

private static final Cache<Method, Function> GETTERS = CacheBuilder.newBuilder().weakValues().build();
private static final Cache<Method, BiConsumer> SETTERS = CacheBuilder.newBuilder().weakValues().build();

其次,創建工廠方法,通過從方法句柄中指向getter或setter來創建函數接口的實例: 

private static Function createGetter(final MethodHandles.Lookup lookup,
                                         final MethodHandle getter) throws Exception{
        final CallSite site = LambdaMetafactory.metafactory(lookup, "apply",
                MethodType.methodType(Function.class),
                MethodType.methodType(Object.class, Object.class), //signature of method Function.apply after type erasure
                getter,
                getter.type()); //actual signature of getter
        try {
            return (Function) site.getTarget().invokeExact();
        } catch (final Exception e) {
            throw e;
        } catch (final Throwable e) {
            throw new Error(e);
        }
}
private static BiConsumer createSetter(final MethodHandles.Lookup lookup,
                                           final MethodHandle setter) throws Exception {
        final CallSite site = LambdaMetafactory.metafactory(lookup,
                "accept",
                MethodType.methodType(BiConsumer.class),
                MethodType.methodType(void.class, Object.class, Object.class), //signature of method BiConsumer.accept after type erasure
                setter,
                setter.type()); //actual signature of setter
        try {
            return (BiConsumer) site.getTarget().invokeExact();
        } catch (final Exception e) {
            throw e;
        } catch (final Throwable e) {
            throw new Error(e);
        }

}

通過對samMethodType和instantiatedMethodType(分別對應metafactory的第三個和第五個參數)之間的區分,可以實現類型擦除后的函數接口中基于對象的參數和實際參數類型之間的自動轉換并以getter或setter作為返回類型。實例化方法類型是提供lambda實現的特殊方法。

然后,在緩存的支持下,為這些工廠創建一個外觀:

public static Function reflectGetter(final MethodHandles.Lookup lookup, final Method getter) throws ReflectiveOperationException {
        try {
            return GETTERS.get(getter, () -> createGetter(lookup, lookup.unreflect(getter)));
        } catch (final ExecutionException e) {
            throw new ReflectiveOperationException(e.getCause());
        }
}
public static BiConsumer reflectSetter(final MethodHandles.Lookup lookup, final Method setter) throws ReflectiveOperationException {
        try {
            return SETTERS.get(setter, () -> createSetter(lookup, lookup.unreflect(setter)));
        } catch (final ExecutionException e) {
            throw new ReflectiveOperationException(e.getCause());
        }
}

作為使用 Java 反射 API 的 Method 實例,獲取的方法信息可以輕松地轉換為 MethodHandle。考慮到實例方法總是有隱藏的第一個參數用于將其傳遞給方法。靜態方法沒有這些隱藏的參數。例如,方法具有 int intValue 的實際簽名(Integer this)。這個技巧用于實現 getter 和 setter 的功能包裝器。

現在是時候測試代碼了:

final Date d = new Date();
final BiConsumer<Date, Long> timeSetter = reflectSetter(MethodHandles.lookup(), Date.class.getDeclaredMethod("setTime", long.class));
timeSetter.accept(d, 42L); //the same as d.setTime(42L);
final Function<Date, Long> timeGetter = reflectGetter(MethodHandles.lookup(), Date.class.getDeclaredMethod("getTime"));
System.out.println(timeGetter.apply(d)); //the same as d.getTime()
//output is 42

這種緩存getter和setter的方法可以有效地用于序列化和反序列化期間,使用getter和setter的序列化/反序列化庫(如Jackson)。

使用LambdaMetafactory動態生成的實現調用函數接口比通過Java Reflection API的調用要。

你可以在開源項目中找到。

限制和缺陷

在本節中,我們將給出在 Java 編譯器和 JVM 中與 lambdas 相關的一些錯誤和限制。 所有這些限制都可以在 OpenJDK 和 Oracle JDK 上重現,它們適用于 Windows 和 Linux 的 javac 1.8.0_131。

從方法句柄構建 Lambdas

如你所知,可以使用 LambdaMetafactory 動態構建 lambda。要實現這一點,你應該指定一個 MethodHandle,其中包含一個由函數接口聲明的單個方法的實現。我們來看看這個簡單的例子:

final class TestClass {
            String value = "";
            public String getValue() {
                return value;
            }
            public void setValue(final String value) {
                this.value = value;
            }
        }
final TestClass obj = new TestClass();
obj.setValue("Hello, world!");
final MethodHandles.Lookup lookup = MethodHandles.lookup();
final CallSite site = LambdaMetafactory.metafactory(lookup,
                "get",
                MethodType.methodType(Supplier.class, TestClass.class),
                MethodType.methodType(Object.class),
                lookup.findVirtual(TestClass.class, "getValue", MethodType.methodType(String.class)),
                MethodType.methodType(String.class));
final Supplier<String> getter = (Supplier<String>) site.getTarget().invokeExact(obj);
System.out.println(getter.get());

上面的代碼等價于:

final TestClass obj = new TestClass();
obj.setValue("Hello, world!");
final Supplier<String> elementGetter = () -> obj.getValue();
System.out.println(elementGetter.get());

但如果我們用一個可以表示一個字段獲取方法的方法處理器來替換指向 getValue 的方法處理器的話,情況會如何呢:

final CallSite site = LambdaMetafactory.metafactory(lookup,
                "get",
                MethodType.methodType(Supplier.class, TestClass.class),
                MethodType.methodType(Object.class),
                lookup.findGetter(TestClass.class, "value", String.class), //field getter instead of method handle to getValue
                MethodType.methodType(String.class));

該代碼應該是可以按照預期來運行的,因為 findGetter 會返回一個指向字段獲取方法、并且具備有效簽名的方法處理器。 但是如果你運行了代碼,就會看到如下異常:

java.lang.invoke.LambdaConversionException: Unsupported MethodHandle kind: getField

有趣的是,如果我們使用 ,字段獲取方法卻可以運行得很好:

final Supplier<String> getter = MethodHandleProxies
                                       .asInterfaceInstance(Supplier.class, lookup.findGetter(TestClass.class, "value", String.class)
                                       .bindTo(obj));

要注意 MethodHandleProxies 并非動態創建 lambda 表達式的理想方法,因為這個類只是把 MethodHandle 封裝到一個代理類里面,然后把對的調用指派給了 方法。 這種方法使得 Java 反射機制運行起來非常的慢。

如前所述,并不是所有的方法句柄都可以在運行時用于構建 lambdas。

只有幾種與方法相關的方法句柄可以用于 lambda 表達式的動態構造

這包括:

  • REF_invokeInterface: 對于接口方法可通過 來構建
  • REF_invokeVirtual: 對于由類提供的虛方法可以通過 Lookup.findVirtual 來構建
  • REF_invokeStatic: 對于靜態方法可通過 構建
  • REF_newInvokeSpecial: 對于構造函數可通過 構建
  • REF_invokeSpecial: 對于私有方法和由類提供的早綁定的虛方法可通過構建

其他方法的句柄將會觸發 LambdaConversionException 異常。

泛型異常

這個 bug 與 Java 編譯器以及在 throws 部分聲明泛型異常的能力有關。下面的示例代碼演示了這種行為:

interface ExtendedCallable<V, E extends Exception> extends Callable<V>{
        @Override
        V call() throws E;
}
final ExtendedCallable<URL, MalformedURLException> urlFactory = () -> new URL("//localhost");
urlFactory.call();

這段代碼應該編譯成功因為 URL 構造器拋出 MalformedURLException。但事實并非如此。編譯器產生以下錯誤消息:


Error:(46, 73) java: call() in <.anonymous Test$CODEgt; cannot implement call() in ExtendedCallable
overridden method does not throw java.lang.Exception

但如果我們用一個匿名類替換 lambda 表達式,那么代碼就編譯成功了:

final ExtendedCallable<URL, MalformedURLException> urlFactory = new ExtendedCallable<URL, MalformedURLException>() {
            @Override
            public URL call() throws MalformedURLException {
                return new URL("//localhost");
            }
        };
urlFactory.call();

結論很簡單:

當與lambda表達式配合使用時,泛型異常的類型推斷不能正確工作。

泛型邊界

一個帶有多個邊界的泛型可以用 & 號構造:<T extends A & B & C & ... Z>。這種泛型參數定義很少被使用,但由于其局限性,它對 Java 中的 lambda 表達式有某些影響:

  • 每一個邊界,除了第一個邊界,都必須是一個接口。
  • 具有這種泛型的類的原始版本只考慮了約束中的第一個邊界。

第二個局限性使 Java 編譯器在編譯時和 JVM 在運行時產生不同的行為,當 Lambda 表達式的聯動發生時。可以使用以下代碼重現此行為:

final class MutableInteger extends Number implements IntSupplier, IntConsumer { //mutable container of int value
    private int value;
    public MutableInteger(final int v) {
        value = v;
    }
    @Override
    public int intValue() {
        return value;
    }
    @Override
    public long longValue() {
        return value;
    }
    @Override
    public float floatValue() {
        return value;
    }
    @Override
    public double doubleValue() {
        return value;
    }
    @Override
    public int getAsInt() {
        return intValue();
    }
    @Override
    public void accept(final int value) {
        this.value = value;
    }
}
static < T extends Number & IntSupplier > OptionalInt findMinValue(final Collection < T > values) {
    return values.stream().mapToInt(IntSupplier::getAsInt).min();
}
final List < MutableInteger > values = Arrays.asList(new MutableInteger(10), new MutableInteger(20));
final int mv = findMinValue(values).orElse(Integer.MIN_VALUE);
System.out.println(mv);

這段代碼絕對沒錯,而且用 Java 編譯器編譯也會成功。MutableInteger 這個類可以滿足泛型 T 的多個類型綁定約束:

  • MutableInteger 是從 Number 繼承的
  • MutableInteger 實現了 IntSupplier

但是在運行的時候會拋出異常:

java.lang.BootstrapMethodError: call site initialization exception
    at java.lang.invoke.CallSite.makeSite(CallSite.java:341)
    at java.lang.invoke.MethodHandleNatives.linkCallSiteImpl(MethodHandleNatives.java:307)
    at java.lang.invoke.MethodHandleNatives.linkCallSite(MethodHandleNatives.java:297)
    at Test.minValue(Test.java:77)
Caused by: java.lang.invoke.LambdaConversionException: Invalid receiver type class java.lang.Number; not a subtype of implementation type interface java.util.function.IntSupplier
    at java.lang.invoke.AbstractValidatingLambdaMetafactory.validateMetafactoryArgs(AbstractValidatingLambdaMetafactory.java:233)
    at java.lang.invoke.LambdaMetafactory.metafactory(LambdaMetafactory.java:303)
    at java.lang.invoke.CallSite.makeSite(CallSite.java:302)

之所以會這樣是因為 Java Stream 的管道只捕獲到了一個原始類型,它是一個 Number 類。Number 類本身并沒有實現 IntSupplier 接口。 要修復此問題,可以在一個作為方法引用的單獨方法中明確定義一個參數類型:

private static int getInt(final IntSupplier i){
    return i.getAsInt();
}
private static <T extends Number & IntSupplier> OptionalInt findMinValue(final Collection<T> values){
    return values.stream().mapToInt(UtilsTest::getInt).min();
}

這個示例就演示了 Java 編譯器和運行時所進行的一次不正確的類型推斷。

在 Java 中的編譯時和運行時處理與 lambdas 結合的多個類型綁定會導致不兼容。

 

本文翻譯自


標簽:Java

本站文章除注明轉載外,均為本站原創或翻譯。歡迎任何形式的轉載,但請務必注明出處、不得修改原文相關鏈接,如果存在內容上的異議請郵件反饋至chenjj@fc6vip.cn


為你推薦

  • 推薦視頻
  • 推薦活動
  • 推薦產品
  • 推薦文章
  • 慧都慧問
掃碼咨詢


添加微信 立即咨詢

電話咨詢

客服熱線
023-68661681

TOP
三级国产短视频在线观看 | 电视剧大全免费全集观看。 | 欧美日韩国产另类不卡在线 | 国产69公社在线视频 | 欧美日韩国产无线码无毒 | 国产精品一区不卡在线观看 | 亚洲中文在线精品国产 | 国产欧美精品一区二区三区pp | 韩国三级私人教练 | 国产在线观 | 精品aⅴ老 | 国产精品白丝 | 欧美日韩国产在线人成 | 亚洲欧美日韩综合在线丁香 | 欧美午夜视频一区 | 国产精品精品 | 国产精偷伦视频在线观看 | 在线日韩不 | 日韩一区二区三区免费播放 | 国产高清国产精品国产专区 | 日产学生妹在线观看 | 亚洲视频一区二区 | 2025国产精品www网站 | 国产精品宾馆在线精品酒店 | 区二区欧| 国产高清一区二区三 | 免费高清在线电影院 | 欧美阿v高 | 日本日本乱码伦视频在线观看 | 日本中文字幕乱码aa高清电影 | 欧美综合在线观看 | 日韩中文字幕在线免费观看 | 精品无人 | 国产日韩欧美在线观看一区二区 | 女被男啪到哭的视频网站 | 国产乱码一区二区三 | 最好看中文字幕国语电影 | 日本一区二区在线观看精品 | 午夜视频在线观看国产 | 在线观看国产精选免费 | 亚洲日韩中文字幕 | 国产最新进 | 日本精品99 | 精品一区二区三区视频免费 | 欧美一区二区激情视频在线播放 | 亚洲日本欧美日韩精品 | 午夜男女羞羞爽爽爽视频 | 亚洲mv大片欧洲mv大片入口 | 亚洲欧美中文高清在线专区 | 亚洲欧美中文字幕在线观看 | 欧美特黄一免在线观看 | 国产真实强奷网站在线播放 | 一区二区三区免费高清视频 | 亚洲国产精品ⅴa在线观看 最新亚洲人 | 国产精品一二三区视频网站 | 亚洲高清国产一区二区三区电影 | 老司机亚洲精品影院 | 99久热只有精品视频免费看 | 丰满的女房东在线观看6 | 国产欧美精品一区二区三区四 | 中文字幕99| 午夜三级a三级三点在线观看 | 国产精品美女一区二区三区 | 国产中文字幕在线 | 国产一进一出又大又粗爽视频 | 色综合视频一区二区三区 | 精品一卡2卡三卡4卡三卡 | 国产又粗又爽视频 | 国产亚洲一区二区三区在线 | 在线观看国产亚洲自拍 | 国产特级婬片免费看 | 自拍偷拍亚洲 | 国产激情免费播放 | 国产足控脚交在线观看 | 男女直接做无 | 91电影成人天堂 | 欧美一卡2卡3卡4卡新区 | 中文字幕不卡精 | 亚洲欧美综合另类 | 91精品国 | 亚洲精品欧美精品日韩精品 | 日本韩国偷拍视频对白不卡高清精 | bt在线天堂中文最新版 | 国产91精选在线观看导航 | 日韩在线电影大全免费观看 | 国产精品三级在 | 国产精品自在线 | 亚洲精品一品区二品区 | 亚洲第一页在线视频 | 成年免费国产大片 | 成人夜间视频 | 热播电视剧免费在线观看 | 欧美日韩变态另类在线观看 | 在线观看亚洲欧美日本 | 我们高清观看免费中国片 | h视频在线观看免费 | 国产在线精品国自产 | 91大神大战丝袜美女在线观看 | 三年片免费观看大全 | 国产精选视频 | 最近中文字幕在线中文视频 | 亚洲永久精品一二三网址永久导航 | 国产第一区 | a视频乱| 视频在线看免费观看 | 手机免费安装推荐 | 人成综合网络 | 国产又粗又硬又大爽黄老大爷视频 | 国产欧美视频一区二区三区 | 欧美三级一区二区 | 国产人成在线观 | 日本免码v?| 国产一级a毛一级a看免费视频 | 成人性欧美| 欧美亚洲另 | 日产a一a区二区www | 欧美成妇人吹潮在线播放 | 亚洲国产欧美日韩一区 | 一本大道东 | 欧美日韩在线视频专区免费 | 国产第一福利精品导航 | 日韩免费一区二区三区高清 | 国产精品极品美女自在线观看 | 亚洲影视日本欧美 | 日本高清在线中字视频 | 日本大片视频 | 亚洲国产成a人v在线观看 | 欧美精产国品一二三类产品特点 | 国产偷伦视频片免费视频 | 99精品热这里只有精品 | 日韩免费的视频在线观看香蕉 | 日韩精品欧美激情国产一区 | 日本韩国偷拍视频对白不卡高清精 | 国产在线不卡一区二区三区 | 一区二区三区免费观看 | 国产精选在线视频 | 在线日本一区二区免费观看 | 国产精品自产拍在线观看一 | 国产视频99kai | 国内精品美女a在线播放 | 免费人成视频在线观看播放网站 | 黑人巨茎 | 亚洲伊人精品国产91综合 | 最新国产精品拍自在线播放 | 亚洲日韩天堂在线 | 亚洲欧美极品 | 二区三区在线播放 | 国产精品高清在线观看93 | 午夜福利试看120秒体验区 | 免费人成在线观看网站免费观看 | 亚洲精品日韩一区 | 99视频有精品视频在线观看 | 在线观看人 | 91短视频在线观看 | 字在线观看一二区 | 人人干美女 | 国产亚洲精 | 一区二区三区四区在线观看视频 | 91精品啪在线观看国产色 | 亚洲经典一区二区三区 | 在线亚洲精品专区 | 亚洲人成日韩中文字幕不卡 | 亚洲va在线va天堂va在线 | 国产网友愉拍精品视频手机 | 青青手机国产在线视频 | 国产精品第一偷怕自怕1区 7799天天综合 | 天天色天天色 | 国产精品自拍视频首页 | 国产初高中系列视频在线 | aa级亚洲电影 | 国产自产21区最新资源 | 成人拍拍拍免费视频网站 | 免费观看日本在线 | 成人污污污www网站免费丝瓜 | 国产操片 | 亚洲综合一区二区三区四区五区 | 五月婷婷综合在线视频 | 在线a亚洲视频播 | 91九色蝌蚪在线 | 电影在线观看不卡 | 国产精品妇 | 国产一区二区影视 | 中文亚洲成a人片在线播放 人成视频在线观看国产 | 伦理电影在线观看 | 欧美亚洲喷水视 | 日韩一区二区三区视频在线观看 | 国产探花在线播放 | 无人视频在线观看播放免费 | 国产亚洲视频在线播放香蕉 | 国产草莓社区在线观看 | 国产91免费视频 | 亚洲成?v人片在线观看翻墙网站 | 中文字幕久热精品 | 91精品全国免费观看青青 | 国产一区二区三区在线观看免费 | 亚洲欧美另类视频小说专区 | 日本免费亚洲视频 | 一区二区三区美女图片 | 中文字幕亚洲 | 日韩精品专区在线影院重磅 | 黄动漫在| 成人拍拍拍免费视频网站 | 99在线视频 | 国产清纯91天堂在线观看 | 精品aⅴ老司机天堂网站 | 18以下勿进色禁网站免费看 | 国产成年女人特黄特色大片免 | 国产精品成人自拍在线观看 | 亚洲国产精品日韩在线 | 精品国精品自拍自在线 | 福利一区福利二区福利三区 | 96福利国产在线 | 国产91尤物中文在线 | 又污又爽又黄的网站 | 国产v亚洲v天堂宗合 | 日韩一区高清在线观看 | 三区免费高清视 | 给我免费播放片国语电影 | 成小说网站色在线 | 国产尹人香蕉在线观看 | 亚洲国产区男人本色vr | 欧美国产日韩a视频在线不卡 | 欧美精品一区二区男同专区 | 性xxxx视频播放 | 伦子系列| 无人在线观看高清视频 | 一本之道在线观看不卡 | 噼里啪啦 | 日韩精品中文字幕一区 | 日本午夜 | 不卡视频一区二区三区免费观看 | 亚洲精品欧美精品日韩精品 | 国产一级特黄a大片99 | 尤物国产精品福利三区 | 国产精品成人一区二区三区电影 | 亚洲午夜国产精 | 国产日本欧美一本在线观看 | 老汉色影院首页 | 成人免费视频软件网站 | 在线点播亚洲日韩国产欧美 | 欧美日韩国产码高清 | 国产精品202 | 热播电视剧在线观 | 成人一区专区在 | 无线资源国产资源好片欧美 | 日本高清免费不卡视频 | 国产真实露脸乱子伦 | 一女被多男玩喷潮视频免费看 | 成人一区免费观看 | 999电影网| 国产亚洲日韩网爆欧美 | 国产午夜在| 最近最新中文字幕 | 品一二三产区 | 成人aⅴ综合视频国产 | 成视人a免费观看视频 | 欧美一区二区制服在线 | 91大神精品网 | 亚洲精品国产精品国自产观看 | 亚洲一区二区三区在线观看网站 | 后进极品翘臀在线播放 | 亚洲国产精品日韩在线 | 日韩欧美一区 | 日韩一区二区手机免费观看 | 91大神在线资源观看无广告 | 国产精品美女 | 三年片免费观看大全 | 国产精品长腿丝袜第一页 | 国产国产人在线成免费视频69 | 成人人免费夜夜视频观看 | 亚洲精品乱无伦国产 | 亚洲骚熟女性视频 | 中文字幕第一页亚洲 | 国产午夜亚洲精品理论片八戒 | 国产精品视频一区二区噜噜 | a级粗大硬长爽猛视频免费 视频二区日韩 | 欧美日韩国产在线观看 | 国产女人喷潮免费视频 | 欧美一级成人免费大片 | 国产电影一区二区三区 | 蜂鸟影院大全免费观看 | 国产v综合v亚洲欧美大 | 国产+成+人+亚洲欧洲自线 | 99在线精品国产不卡在线观看 | 亚洲日本韩国 | 国产又粗又大又黄的视频 | 韩国精品福利一区二区 | 免费人成在线观看vr网站 | 日韩男女性生活视频在线观看 | 国产免费中文综合 | 亚洲精品国产一级高清在线观看 | 亚洲日韩天堂网中文字幕 | 免费人成视在线观看不卡 | 国产在线观看www | 国产精品喷水 | 国产高清视频一区免费观看 | 婷庭九月天综合水蜜桃 | 精品国产一区二区三区免费91 | 午夜影视污 | 一区二区三区精品视频免费播放 | 五月综合激情婷婷六月色窝 | 日韩欧美在线综合网高清 | 日韩在线视频www色 午夜福利在线观看亚洲一区二区 | 亚洲熟女综合 | 日本中文字幕a∨在线观看 欧美日韩亚洲国产高清 | 国产亚洲欧美日韩在线看片 | 无色码中文字幕亚洲精品 | 欧美精品一区二区三区不卡网 | 二品国精品69xx | 二区三区爱欲九九 | 亚洲国产精品专区 | 成人α片免费视频在线观看 | 一本一道日韩一二三四区免费 | 国产日韩欧美亚洲 | 国产欧美日韩96 | 亚洲日韩一区精品射精 | 精品国产久九九 | 亚洲欧美日韩中文字幕在线不卡 | 青草青草久热精 | 色与欲影视天天影视 | 偷拍视频一区二区三区 | 中文韩国午夜理伦三级好看 | 午夜福利试看120秒体验区 | 野花影视 | 国产精品国语自产拍在线观看 | 欧美日韩国产网站 | 日本高清视频在线免费观看 | 18欧美乱大| 日韩电影免费在线观看中文字幕 | 国产99视 | 日本免费精品 | 中文字幕日本 | 亚洲精品高清国产 | 津渝完整视频线上观看 | 欧美在线色 | 色无极影院亚洲专区 | 国产欧美亚洲一级a在线观看 | 寡妇被折腾的死去活来 | 亚洲欧美国产日韩精品在线 | 中文字幕久 | 亚洲欧美日韩国产一区二区三区 | 久青草视频97国内免费影视 | 日韩一区精品视频一区二区 | 神马影院午夜电影 | 国产一区免费在线观看 | 国产精品va在线播放我和闺蜜 | 91精品福利自产拍在线 | 亚洲愉拍自拍另类 | 亚洲欧美精品中文字幕 | 亚洲色大成网站www永久男同 | 干天堂在 | 国产亚洲精品成人a在线 | 成人涩涩涩视频在线观看 | 真人做爰欧美aaaaa | 一区二区日韩激情在线观看视频 | 五十路熟女俱乐部 | 欧美一级特黄aa大片 | 欧美又粗又 | 国产在线观看免费人成视频 | 自拍偷自拍亚洲精品偷一 | 国产亚洲人成a在线v网站 | 亚洲欧美国产人成在线 | 成视人a| 欧美又粗又 | 好看热播经典影视视频 | 欧美精品黄页在 | 精品国产自在现线 | 99精品在线视频观看 | 日产精品| 精品国产福利第一区二区三区 | 少女频道在线观看高清 | 日韩欧美国产精品 | 激情97综合亚洲 | 给我免费的视频在 | 精品国产9| 国产精品高清自在线 | 亚洲男人第一αv网站 | 91大神是啥 | 97精品国产一区二区三区 | 色就是色亚洲视频 | 人人草人人 | 三级国产4国语三级在线 | 亚洲欧美综合另类中字 | 国产在线精品国自产拍影院午夜 | 国产不卡在线观看视频 | 人人天天综合影院 | 欧美一区| 日本国产欧美日韩三区四区 | 欧美一区视频在线 | 日韩欧美综 | 亚洲成a人片在线观看高清 在线观看www成人影院 | 日韩精品免费一线在线观看 | 亚洲精品中文字幕不卡在线 | 91青青国产在线观看免费 | 免费国产午夜激情片 | 香蕉五月天一综合网 | 日产精品一线二线三线芒果 | 欧美大棒插白人 | 成人福利国产精品视频 | 国产一区二区三区正品 | 日本亚洲国产一区二区三区 | 欧美人与动性行为网站免费 | 最近免费中文字幕视频高清在线看 | 一区二区三区精品视频免费播放 | 在线观看日韩 | 国产初高中生视 | 91视频精品全国免费观看 | 青青青国产精品一区二区 | 91人成在线观看网站 | 国产精品广西柳州 | 免费动漫成本人视频网站 | 露脸对白不带套在线播放 | 亚洲无线码一区二区三区 | 日本视频在线观看不卡高清免费 | 国产高清 | 免费国产人做人视频在线观看 | 国产精品v亚洲精品v日韩精品 | 中文字幕在线观看亚洲 | 国产一区二区高清 | 国产精品永久在线 | 精品福利 | xxxx野外性| 欧美a级情欲片手机在线播放 | 欧美日韩国产一区 | 欧美日韩国产这里只有精品 | 91福利在线视频 | 91香蕉高清国产线观看免费 | 午夜视频在线观看一区二区 | 国产亚洲视频在线观看 | 97日日 | 黄一色片一网站一 | 日本.欧美一区二区三区 | 日本人乱亲伦视频 | 国产aⅴ视频免费观看国语 91大神在线视频免费观看 | 欧美性色欧美a在线在线播放 | 91福利国产在线观一区二区 | 中国字幕在线看韩国电影 | 国产精品三 | 国产肥熟老胖女在线看 | 99精品视频在线观看婷婷 | 国产精品自在拍一区二区不卡 | 亚洲日本va午夜在线影院 | 国产福利一区二区三区在线观看 | 一本久道综合在线 | 国产精品欧美日韩视频一区 | 国产在线观看精品 | 午夜性影院在线观看视频播放 | 人妖和人妖互交性xxxx视频 | 国产人免费视频成69 | 最新电视剧免费观看 | 日本一区二区三区四区在线 | 小蜜被两老头 | 亚洲精品911在线永久观看 | 国产三区免费在线观看 | 欧美一级毛卡片免费2025 | 欧一美一性一交一乱一性一 | 91九色精品国产免费 | 亚洲欧洲国产日产综合综合 | 亚洲综合专区 | 亚洲欧洲国产精品香蕉网 | 永久免费精品性爱网站 | 亚洲色自偷自拍另类小说 | 国产精品午夜看片 | 日韩专区在线观看 | 在线视频一区二区三区三区不卡 | 欧美激情一区二区三区在线播放 | 2025高清免费热播电视剧电影 | 亚洲中国中文字幕免费 | 国产视频美女精品福利社 | 热门事件黑料不打烊吃瓜 | 偷拍激情视频一区二区三区 | 国产一级a爱片 | 蜂鸟影院大全免费观看 | 最近伦中文字 | 中文字幕在 | 在线精品亚洲一区二区绿巨人 | 欧美日韩成人 | 午夜视频在线播放 | 中文字幕亚洲精品 | 亚洲日本国产一区二区精品成人 | 国产欧美日韩综合精品二区 | 国产综合成人一区二区三区电影院 | 福利片一区二区 | 亚洲男人夜夜精品电影 | 成年女性特黄午夜视频免费看 | 国产乱码卡二卡三卡4 | 九九中文字幕国产 | 成人黃色一級片 | 国产中文成人精品小说 | 亚洲欧洲日韩 | 欧美女视频网站大全在线观看 | 中文日本| 亚洲区小说区激情区图片区 | 天天射天天爱天天射干 | 十九岁在线观看免费完整版 | 日韩欧美视频一区二区 | 最近播放中文版在线观看免费 | 欧美国产精品不卡在线观看 | 免费国产自在线拍 | 亚洲国产精品va在线看黑人 | 精品一区二区在线视 | 911国产自产精品a | 国产日韩欧美视频在线观看 | 亚洲一区二区三区影院 | 国产成本人片免费v | 色哟哟精 | 中文字幕在线观看日本 | 产免费一区二区三区视频 | 精品一区二区三区中文字幕 | 亚洲经典 | 日韩美女网站在线看 | 亚洲精品园精 | 亚洲日本欧美日韩精品 | 日本中文字幕网址 | 国产精品第一偷怕自怕1区 7799天天综合 | 亚洲第一综合天堂另类专 | 永久免费4k观影站 | 亚洲欧美日韩在线一区天天看 | 99热国产在线手 | 国产亚洲欧美视频 | 亚洲午夜私人影院 | 久爱成疾在线视频播放 | 极品美女在线观看国产一区 | 午夜理论片精品国产 | 国产亚洲精品成 | 欧美色欧美亚洲高清在线观看 | 99re热这里只| 欧洲女人牲| 色两性午夜视频免费观看 | 日韩精品一区二区最新 | 国产自产亚洲 | 国产精品福利自产拍在线观看 | 白虎视频污 | 达达兔欧美午夜国产亚洲 | 米奇欧美777四色影视在线 | 午夜嘿嘿嘿在线观看 | 爱情岛论坛 | 午夜男女爽爽影院在线 | 综合乱伦自拍影视 | 一本精品一区二区在线观看 | 国内精品99亚洲免费高清 | 国产乱子 | 微拍福利88 | 欧美午夜理伦三级在线 | 亚洲人成电影福利在线播放 | 国产精品熟女视频一区二区 | 免费午夜一级高清免费看 | 欧美日韩在线播放一区二区三区 | 国产视频第一页bt天堂 | 九九免费福利精品视频 | 日本高清视频网址 | 亚洲自偷自拍另类第1页 | 男人操女人视频 | 亚洲熟女乱色一区二区三区 | 成年人24小时在线免费观看视频 | 国产精品全网免费在线播放 | 日韩欧美视频一区二区三区 | 亚洲成aⅴ人 | 一区二区视频在线观看入口 | 国产在线精品一区不卡 | 午夜三级三级三点在线 | 国产乱子伦精品免费视频 | 亚洲老女人精品老妇女 | 亚洲成a人片在线v观看 | 欧美日韩一区免费观看 | 美女视频黄的网站全免弗 | 2025年最新高清电影 | 韩国三级香港三 | 午夜一区二区三区在线 | 日本另类αv欧美另类aⅴ | 成a人v在线观看 | 精品中文字幕一区在线 | 久99精 | 91老司机精品福利在线 | 日韩一二区 | 亚洲精品偷拍区 | 日韩一区二 | 日本国产一区二区三区在线观看 | 欧美女同小视频在线网站 | 91牛牛国产在线无弹窗 | 综合国产日本 | 欧美专区亚洲专区 | 草莓视频在线免费看 | 日本午夜专区一 | 国产精品日本一区二区不卡视频 | 国产亚洲精品国产福利 | 一区二区欧美 | 国产福利免费视频 | 日韩国产一级一区精品 | 国产福利在线观看片 | 蜜臀98精品国产免费观看 | 韩国日本高清免费电影 | 国产啪亚洲国产 | 97色精品视频在 | 国产一区二区高清在线国产综合 | 国产免费高清69式视频在线观看 | 国产一级二级三级经典在线 | 国产精品v欧美精品v日韩精品 | 在线一区二区三区中文字幕 | 国产精品一区福利在线观看 | 亚洲精品综合色区二区 | 乱伦三级高清精 | 国产精品区二区三区日本 | 俄罗斯性爱视频一区二区 | 欧美女同小视频在线网站 | 国产女主播在线观看 | 国产精品美女 | h视频在线观看免费 | 精品国产高清自在线看 | 国色天香天天影院综合网 | 91精选国产大片 | 亚洲美女又黄又爽在线观看 | 日韩欧美激情视频 | 亚洲国产欧美一区二区三区 | 国产福利免费视频 | 精品亚洲成a人在线 | 亚洲日韩一区二区三区四区高清 | 好吊妞无缓冲不卡在线视频 | 成人专区一区二区三区四区 | 三级综合精品乱伦 | 国产日产免费高清欧美一区 | 国产高清免费在线观看 | 丰满的女房东在线观看6 | 亚洲熟女乱色一区二区三区 | 国产痴汉系列在线播放 | 99玖玖爱在线精品免费观看 | 国产免费人成视频在线观看 | 一区二区三区高清视频 | 国产中文成人精品小说 | 啦啦啦免费高清视频 | 亚洲欧美韩 | 欧美日韩色黄大片在线视频 | 女性女同性aⅴ免费观看 | 精品国产国产综合精品 | 中文字幕午夜福利片午夜福利片 | 香港特级 | 欧美色aⅴ欧美综合色 | 欧美精品v日韩精品v韩国精品v | 日韩精品专区在线影院重磅 | 中文字幕不卡 | 在线精品亚洲一 | 杨幂在日本一区二区视频 | 国产亚洲午夜高清国产拍精品 | 国产精品h片在线播放 | 91最新精品视频在线 | 给我免费观看片在线观看中国 | 国产精品1区2区 | 欧美日韩综合在线播放 | 极品一区二区三 | 亚洲+变态+欧美+另类+精品 | 亚洲资源最新版在线观看 | 重口视频二区在线观看 | 免费国外性视频网站 | 国产大片51精品免费观看 | 午夜网站免费 | 最新精品在线视频 | 在线看片免费人成视久网 | 99精品国产自产在线观看 | 欧美精品1区国新欲乱视频 国产一区二区精品免费播放 | 91视频国产大片 | 一区二区三区高清视频一 | 亚洲一区二区经典在线播放 | a∨中文字幕另类 | 精品视频91 | 国产乱女乱子视频在线播放 | 91热精品| 91中文字 | 国产福利深夜视频在线观看 | 欧美日韩精品专区在线 | 婷婷综合尤物精品国产 | 欧美日韩一区二区三区在线视频 | 亚洲中文字幕乱码熟女在线 | 婷婷亚洲综 | 色豆豆永| 变态另类清纯唯美中文 | 成人自拍电影在线观看 | 视频国产精品丝袜第一页 | 成人国产综合三级 | 精品国产高清免费在线观看 | 区三区在线播放 | 天天影视色香 | 好吊色欧美一区二区三区视频 | 国产精品视频每日更新播放 | 一区二区三区在线观看 | 国产日本欧美三区 | 51精品免费视频国 | 精品免费看一区二区三区 | 在线欧美日韩亚洲国产一区 | 欧美精品一区在线观看 | 91精品啪在线观看国产线免费 | 最好免费观看高清视频大全 | 欧美无极品在线观看 | 国产日韩在线欧美视频 | 91啪国自产在线高清观看 | 99在线视频| 亚洲aⅴ| 高清欧美性xxxx成熟 | 99精品在 | 国产欧美自拍偷怕日韩亚洲 | 国产香蕉尹人综合在线观看 | 国产欧美日韩综合精品二区 | 亚洲一卡2卡3卡4 | 日本汚视频在线观 | 人人天天综合影院 | 亚洲丰满 | 免费a级毛 | 国产在线欧美观看 | 日本精品在线播放 | 强开女学生的小嫩苞 | 更新日韩 | 国产免费福 | 九九热精品在线视频观看 | 欧美精品日韩精品一卡 | 自产视频在线观看 | 国产欧美在线免费观看 | 国产欧美国产精品第一区 | 好看的电视剧免费在线观看 | 国产在线一区二区三区不卡在线 | 国产精品青青青高清在线 | 亚洲激情 | 在线看免费看国产精品视频 | 亚洲欧洲日韩一区二区日本 | 国产日韩欧美日韩欧美 | 欧美日韩一区二区三区视频网站 | 国产美女在线精品免费观看 | 国产精品欧美激情一区二区亚洲 | 亚洲中国中文字幕免费 | 一区二区三区免费在线观看 | 亚洲人护士毛茸茸 | 在线观看日韩欧美一区二区 | 天天射天 | 亚洲一区在线免费 | 91成人精品爽啪在 | 97超视频在线观看视频在线 | 天天天天香蕉线视频国产 | 日本中文字幕在线视频站 | 亚洲国产精品色一区二区 | 亚洲欧洲自拍拍偷午夜色 | 国产免费202 | 99视频精品全部国产盗摄 | 精品国产不 | a在线视频观看 | 一区二区三区视频 | 亚洲日韩一区二区一 | 国产激情影视综合 | 国产又粗又猛又爽又黄 | 国产又粗又猛又爽又黄的视频吉 | 最近最新中文字幕 | a在线视频播放观看免费观看 | 欧美午夜在线视频 | 精品一区二区三区在线 | 国产精品人成电影在线观看 | 天天天天躁天天爱天天碰2025 | 性夜夜夜夜夜夜爽 | 亚洲成aⅴ人片久青草影院 国产91精品系列在线观看 | 日本高清xxxx视频 | 日本欧美一区二区三区在线 | 国产a在亚洲线播放 | 国产亚洲精品九九久在线观看 | 污网站在线观看视频平台 | 国产精品亚洲欧韩在线 | 亚洲伦理一区二 | 国产一区二区在线视频 | 日韩欧洲在线精品一区 | 亚洲欧美另类偷窥自拍 | 国产精品中文久 | 黑人巨大videos极度另类 | 999二区在线| 精品国产福利在线观看91啪 | 最新国产精品拍自在线观看 | 亚洲成v人片在线观看 | 日本精品高清一区二区 | 精品国产aⅴ一区二区三区四川人 | 色依依亚洲一区在线观看 | 中文字幕一区二区三区 | 亚洲自拍中文另类 | 国产欧美精品一区二区三区pp | 欧美精品一区二区电影 | 国产日韩欧美福利 | 成年网站免费视 | 日本欧美一区二区三区不卡 | 特种兵的又 | 亚洲精品日韩精品一区 | 国产精品不卡在线观看的a站 | 国产福利观看 | 全国男人的天堂亚洲 | 亚洲骚熟女性视频 | 日本在线播放 | 欧美v亚洲v综合 | 日韩在线一区二区三区观看 | 日本成年人黄a大片 | 亚洲综合v在线在 | 99国产在线观看 | 日韩亚洲人成在线综合日本 | 亚洲视频偷拍视频2亚 | 欧美乱伦国产精品 | 成年人免费视频软件 | 国产女人喷潮视频免费 | 欧美精品欧美***欧美激情 |