Java9-Java11特性

為什么選擇Java11

  • 容器環(huán)境支持创肥,GC等領(lǐng)域的增強(qiáng)唠叛。
  • 進(jìn)行了瘦身绢慢,更輕量級灿渴,安裝包體積小。
  • JDK11 是一個(gè)長期支持版胰舆。

特性介紹

由于直接從Java8跨越到Java11骚露,所以特性介紹就把Java9-Java11的部分特性一起介紹一下。

Jshell @since 9

Jshell在Java9中就被提出來了缚窿,可以直接在終端寫Java程序荸百,回車就可以執(zhí)行。Jshell默認(rèn)會(huì)導(dǎo)入下面的一些包,所以在Jshell環(huán)境中這些包的內(nèi)容都是可以使用的滨攻。

import java.lang.*;
import java.io.*;
import java.math.*;
import java.net.*;
import java.nio.file.*;
import java.util.*;
import java.util.concurrent.*;
import java.util.function.*;
import java.util.prefs.*;
import java.util.regex.*;
import java.util.stream.*;

1.什么是Jshell?

Jshell是在 Java 9 中引入的。它提供了一個(gè)交互式 shell蓝翰,用于快速原型光绕、調(diào)試、學(xué)習(xí) Java 及 Java API畜份,所有這些都不需要 public static void main 方法诞帐,也不需要在執(zhí)行之前編譯代碼。

2.Jshell的使用

打開終端爆雹,鍵入jshell進(jìn)入jshell環(huán)境停蕉,然后輸入/help intro可以查看Jshell的介紹。

 lixiaoshuang@localhost  ~  jshell
|  歡迎使用 JShell -- 版本 11.0.2
|  要大致了解該版本, 請鍵入: /help intro

jshell> /help intro
|
|                                   intro
|                                   =====
|
|  使用 jshell 工具可以執(zhí)行 Java 代碼钙态,從而立即獲取結(jié)果慧起。
|  您可以輸入 Java 定義(變量、方法册倒、類等等)蚓挤,例如:int x = 8
|  或 Java 表達(dá)式,例如:x + x
|  或 Java 語句或?qū)搿?|  這些小塊的 Java 代碼稱為“片段”。
|
|  這些 jshell 工具命令還可以讓您了解和
|  控制您正在執(zhí)行的操作灿意,例如:/list
|
|  有關(guān)命令的列表估灿,請執(zhí)行:/help

jshell>

Jshell確實(shí)是一個(gè)好用的小工具,這里不做過多介紹缤剧,我就舉一個(gè)例子馅袁,剩下的大家自己體會(huì)。比如我們現(xiàn)在就想隨機(jī)生成一個(gè)UUID荒辕,以前需要這么做:

  • 創(chuàng)建一個(gè)類汗销。
  • 創(chuàng)建一個(gè)main方法。
  • 然后寫一個(gè)生成UUID的邏輯兄纺,執(zhí)行大溜。

現(xiàn)在只需要,進(jìn)入打開終端鍵入jshell,然后直接輸入var uuid = UUID.randomUUID()回車。就可以看到uuid的回顯估脆,這樣我們就得到了一個(gè)uuid钦奋。并不需要public static void main(String[] args);

 lixiaoshuang@localhost  ~  jshell
|  歡迎使用 JShell -- 版本 11.0.2
|  要大致了解該版本, 請鍵入: /help intro

jshell> var uuid = UUID.randomUUID();
 uuid ==> 9dac239e-c572-494f-b06d-84576212e012
jshell>

3.怎么退出Jshell?

在Jshell環(huán)境中鍵入/exit就可以退出疙赠。

 lixiaoshuang@localhost  ~ 
 lixiaoshuang@localhost  ~  jshell
|  歡迎使用 JShell -- 版本 11.0.2
|  要大致了解該版本, 請鍵入: /help intro

jshell> var uuid = UUID.randomUUID();
uuid ==> 9dac239e-c572-494f-b06d-84576212e012

jshell> /exit
|  再見
 lixiaoshuang@localhost  ~ 

模塊化(Module)@since 9

1.什么是模塊化付材?

模塊化就是增加了更高級別的聚合,是Package的封裝體圃阳。Package是一些類路徑名字的約定厌衔,而模塊是一個(gè)或多個(gè)Package組成的封裝體。

java9以前 :package => class/interface捍岳。

java9以后 :module => package => class/interface富寿。

那么JDK被拆為了哪些模塊呢?打開終端執(zhí)行java --list-modules查看锣夹。

lixiaoshuang@localhost  ~ java --list-modules
java.base@11.0.2
java.compiler@11.0.2
java.datatransfer@11.0.2
java.desktop@11.0.2
java.instrument@11.0.2
java.logging@11.0.2
java.management@11.0.2
java.management.rmi@11.0.2
java.naming@11.0.2
java.net.http@11.0.2
java.prefs@11.0.2
java.rmi@11.0.2
java.scripting@11.0.2
java.se@11.0.2
java.security.jgss@11.0.2
java.security.sasl@11.0.2
java.smartcardio@11.0.2
java.sql@11.0.2
java.sql.rowset@11.0.2
java.transaction.xa@11.0.2
java.xml@11.0.2
java.xml.crypto@11.0.2
jdk.accessibility@11.0.2
jdk.aot@11.0.2
jdk.attach@11.0.2
jdk.charsets@11.0.2
jdk.compiler@11.0.2
jdk.crypto.cryptoki@11.0.2
jdk.crypto.ec@11.0.2
jdk.dynalink@11.0.2
jdk.editpad@11.0.2
jdk.hotspot.agent@11.0.2
jdk.httpserver@11.0.2
jdk.internal.ed@11.0.2
jdk.internal.jvmstat@11.0.2
jdk.internal.le@11.0.2
jdk.internal.opt@11.0.2
jdk.internal.vm.ci@11.0.2
jdk.internal.vm.compiler@11.0.2
jdk.internal.vm.compiler.management@11.0.2
jdk.jartool@11.0.2
jdk.javadoc@11.0.2
jdk.jcmd@11.0.2
jdk.jconsole@11.0.2
jdk.jdeps@11.0.2
jdk.jdi@11.0.2
jdk.jdwp.agent@11.0.2
jdk.jfr@11.0.2
jdk.jlink@11.0.2
jdk.jshell@11.0.2
jdk.jsobject@11.0.2
jdk.jstatd@11.0.2
jdk.localedata@11.0.2
jdk.management@11.0.2
jdk.management.agent@11.0.2
jdk.management.jfr@11.0.2
jdk.naming.dns@11.0.2
jdk.naming.rmi@11.0.2
jdk.net@11.0.2
jdk.pack@11.0.2
jdk.rmic@11.0.2
jdk.scripting.nashorn@11.0.2
jdk.scripting.nashorn.shell@11.0.2
jdk.sctp@11.0.2
jdk.security.auth@11.0.2
jdk.security.jgss@11.0.2
jdk.unsupported@11.0.2
jdk.unsupported.desktop@11.0.2
jdk.xml.dom@11.0.2
jdk.zipfs@11.0.2

2.為什么這么做页徐?

大家都知道JRE中有一個(gè)超級大的rt.jar(60多M),tools.jar也有幾十兆银萍,以前運(yùn)行一個(gè)hello world也需要上百兆的環(huán)境变勇。

  • 讓Java SE程序更加容易輕量級部署。
  • 強(qiáng)大的封裝能力贴唇。
  • 改進(jìn)組件間的依賴管理搀绣,引入比jar粒度更大的Module。
  • 改進(jìn)性能和安全性戳气。
3.怎么定義模塊?

模塊的是通過module-info.java進(jìn)行定義链患,編譯后打包后,就成為一個(gè)模塊的實(shí)體物咳。下面來看下最簡單的模塊定義锣险。

image
image
4.模塊的關(guān)鍵字
  • open

    用來指定開放模塊,開放模塊的所有包都是公開的,public的可以直接引用使用,其他類型可以通過反射得到蹄皱。

    open module module.one {
        //導(dǎo)入日志包
       requires java.logging;
    
    }
    
    
  • opens

    opens 用來指定開放的包,其中public類型是可以直接訪問的,其他類型可以通過反射得到。

    module module.one {
    
        opens <package>;
    }
    
    
  • exports

    exports用于指定模塊下的哪些包可以被其他模塊訪問芯肤。

    module module.one {
    
        exports <package>;
    
        exports <package> to <module1>, <module2>...;
    }
    
    
  • requires

    該關(guān)鍵字聲明當(dāng)前模塊與另一個(gè)模塊的依賴關(guān)系巷折。

    module module.one {
    
        requires <package>;
    
    }
    
    
  • uses、provides…with…

    uses語句使用服務(wù)接口的名字,當(dāng)前模塊就會(huì)發(fā)現(xiàn)它,使用java.util.ServiceLoader類進(jìn)行加載,必須是本模塊中的,不能是其他模塊中的.其實(shí)現(xiàn)類可以由其他模塊提供崖咨。

    module module.one {
    
        //對外提供的接口服務(wù) ,下面指定的接口以及提供服務(wù)的impl锻拘,如果有多個(gè)實(shí)現(xiàn)類,用用逗號隔開
        uses <接口名>;
    
        provides <接口名> with <接口實(shí)現(xiàn)類>,<接口實(shí)現(xiàn)類>;
    
    }
    
    

var關(guān)鍵字 @since 10

1.var是什么击蹲?

var是Java10中新增的局部類型變量推斷署拟。它會(huì)根據(jù)后面的值來推斷變量的類型,所以var必須要初始化歌豺。

例:

var a;       ?
var a = 1;   ?

2.var使用示例
  • var定義局部變量

    var a = 1; 
    等于
    int a = 1;
    
    
  • var接收方法返回時(shí)

    var result = this.getResult();
    等于
    String result = this.getResult();
    
    
  • var循環(huán)中定義局部變量

    for (var i = 0; i < 5; i++) {
       System.out.println(i);
    }
    等于
    for (int i = 0; i < 5; i++) {
       System.out.println(i);
    }
    
    
  • var結(jié)合泛型

    var list1 = new ArrayList<String>();  //在<>中指定了list類型為String
    等于
    List<String> list1 = new ArrayList<>();
    
    var list2 = new ArrayList<>();        //<>里默認(rèn)會(huì)是Object
    
    
  • var在Lambda中使用(java11才可以使用)

    Consumer<String> Consumer = (var i) -> System.out.println(i);
    等于
    Consumer<String> Consumer = (String i) -> System.out.println(i);
    
    
3.var不能再哪里使用推穷?
  • 類成員變量類型。
  • 方法返回值類型类咧。
  • Java10中Lambda不能使用var馒铃,Java11中可以使用。

增強(qiáng)api

1.字符串增強(qiáng) @since 11
// 判斷字符串是否為空白
" ".isBlank();                     // true

// 去除首尾空格
" Hello Java11 ".strip();          // "Hello Java11"

// 去除尾部空格 
" Hello Java11 ".stripTrailing();  // " Hello Java11"

// 去除首部空格 
" Hello Java11 ".stripLeading();   // "Hello Java11 "

// 復(fù)制字符串
"Java11".repeat(3);                // "Java11Java11Java11"

// 行數(shù)統(tǒng)計(jì)
"A\nB\nC".lines().count();         // 3

2.集合增強(qiáng)

從Java 9 開始痕惋,jdk里面就為集合(List区宇、Set、Map)增加了of和copyOf方法值戳。它們用來創(chuàng)建不可變集合议谷。

  • of() @since 9
  • copyOf() @since 10

示例一:

        var list = List.of("Java", "Python", "C"); //不可變集合
        var copy = List.copyOf(list);         //copyOf判斷是否是不可變集合類型,如果是直接返回
        System.out.println(list == copy);    // true

        var list = new ArrayList<String>();  // 這里返回正常的集合
        var copy = List.copyOf(list);        // 這里返回一個(gè)不可變集合
        System.out.println(list == copy);    // false

示例二:

        var set = Set.of("Java", "Python", "C");
        var copy = Set.copyOf(set);
        System.out.println(set == copy);     // true

        var set1 = new HashSet<String>();
        var copy1 = List.copyOf(set1);
        System.out.println(set1 == copy1);   // false

示例三:

        var map = Map.of("Java", 1, "Python", 2, "C", 3);
        var copy = Map.copyOf(map);
        System.out.println(map == copy);     // true

        var map1 = new HashMap<String, Integer>();
        var copy1 = Map.copyOf(map1);
        System.out.println(map1 == copy1);   // false

注意:使用 of 和 copyOf 創(chuàng)建的集合為不可變集合堕虹,不能進(jìn)行添加卧晓、刪除、替換赴捞、排序等操作禀崖,不然會(huì)報(bào)java.lang.UnsupportedOperationException異常,使用Set.of()不能出現(xiàn)重復(fù)元素螟炫、Map.of()不能出現(xiàn)重復(fù)key,否則回報(bào)java.lang.IllegalArgumentException艺晴。昼钻。

3.Stream增強(qiáng) @since 9

Stream是Java 8 中的特性,在Java 9 中為其新增了4個(gè)方法:

  • ofNullable(T t)

    此方法可以接收null來創(chuàng)建一個(gè)空流

    以前
    Stream.of(null);  //報(bào)錯(cuò)
    現(xiàn)在
    Stream.ofNullable(null);
    
    
  • takeWhile(Predicate<? super T> predicate)

    此方法根據(jù)Predicate接口來判斷如果為true就 取出 來生成一個(gè)新的流,只要碰到false就終止封寞,不管后邊的元素是否符合條件然评。

            Stream<Integer> integerStream = Stream.of(6, 10, 11, 15, 20);
            Stream<Integer> takeWhile = integerStream.takeWhile(t -> t % 2 == 0);
            takeWhile.forEach(System.out::println);   // 6,10
    
    
  • dropWhile(Predicate<? super T> predicate)

    此方法根據(jù)Predicate接口來判斷如果為true就 丟棄 來生成一個(gè)新的流,只要碰到false就終止,不管后邊的元素是否符合條件狈究。

            Stream<Integer> integerStream = Stream.of(6, 10, 11, 15, 20);
            Stream<Integer> takeWhile = integerStream.dropWhile(t -> t % 2 == 0);
            takeWhile.forEach(System.out::println);  //11,15,20
    
    
  • iterate重載

    以前使用iterate方法生成無限流需要配合limit進(jìn)行截?cái)?/p>

            Stream<Integer> limit = Stream.iterate(1, i -> i + 1).limit(5);
            limit.forEach(System.out::println);   //1,2,3,4,5
    
    

    現(xiàn)在重載后這個(gè)方法增加了個(gè)判斷參數(shù)

            Stream<Integer> iterate = Stream.iterate(1, i -> i <= 5, i -> i + 1);
            iterate.forEach(System.out::println);  //1,2,3,4,5
    
    
4.Optional增強(qiáng) @since 9
  • stream()

    如果為空返回一個(gè)空流碗淌,如果不為空將Optional的值轉(zhuǎn)成一個(gè)流。

            //返回Optional值的流
            Stream<String> stream = Optional.of("Java 11").stream();
            stream.forEach(System.out::println);    // Java 11
    
            //返回空流
            Stream<Object> stream = Optional.ofNullable(null).stream();
            stream.forEach(System.out::println);    // 
    
    
  • ifPresentOrElse(Consumer<? super T> action, Runnable emptyAction)

    個(gè)人感覺這個(gè)方法就是結(jié)合isPresent()對Else的增強(qiáng),ifPresentOrElse 方法的用途是亿眠,如果一個(gè) Optional 包含值碎罚,則對其包含的值調(diào)用函數(shù) action,即 action.accept(value)纳像,這與 ifPresent 一致荆烈;與 ifPresent 方法的區(qū)別在于,ifPresentOrElse 還有第二個(gè)參數(shù) emptyAction —— 如果 Optional 不包含值竟趾,那么 ifPresentOrElse 便會(huì)調(diào)用 emptyAction憔购,即 emptyAction.run()。

            Optional<Integer> optional = Optional.of(1);
            optional.ifPresentOrElse( x -> System.out.println("Value: " + x),() ->
                    System.out.println("Not Present."));    //Value: 1
    
            optional = Optional.empty();
            optional.ifPresentOrElse( x -> System.out.println("Value: " + x),() ->
                    System.out.println("Not Present."));    //Not Present.
    
    
  • or(Supplier<? extends Optional<? extends T>> supplier)

        Optional<String> optional1 = Optional.of("Java");
        Supplier<Optional<String>> supplierString = () -> Optional.of("Not Present");
        optional1 = optional1.or( supplierString);
        optional1.ifPresent( x -> System.out.println("Value: " + x));  //Value: Java

        optional1 = Optional.empty();
        optional1 = optional1.or( supplierString);
        optional1.ifPresent( x -> System.out.println("Value: " + x)); //Value: Not Present

5.InputStream增強(qiáng) @since 9
        String lxs = "java";
        try (var inputStream = new ByteArrayInputStream(lxs.getBytes());
             var outputStream = new ByteArrayOutputStream()) {
            inputStream.transferTo(outputStream);
            System.out.println(outputStream);    //java
        }

HTTP Client API

改api支持同步和異步兩種方式岔帽,下面是兩種方式的示例:

        var request = HttpRequest.newBuilder()
                .uri(URI.create("https://www.baidu.com/"))
                .build();
        var client = HttpClient.newHttpClient();
        // 同步
        HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
        System.out.println(response.body());

        // 異步
        CompletableFuture<HttpResponse<String>> sendAsync = client.sendAsync(request, HttpResponse.BodyHandlers.ofString());
        //這里會(huì)阻塞
        HttpResponse<String> response1 = sendAsync.get();
        System.out.println(response1.body());

直接運(yùn)行java文件

我們都知道以前要運(yùn)行一個(gè).java文件玫鸟,首先要javac編譯成.class文件,然后在java執(zhí)行:

//編譯
javac Java11.java
//運(yùn)行
java Java11

在java11中犀勒,只需要通過java一個(gè)命令就可以搞定

java Java11.java

移除內(nèi)容

  • com.sun.awt.AWTUtilities屎飘。
  • sun.misc.Unsafe.defineClass 使用java.lang.invoke.MethodHandles.Lookup.defineClass來替代。
  • Thread.destroy() 以及 Thread.stop(Throwable) 方法账蓉。
  • sun.nio.ch.disableSystemWideOverlappingFileLockCheck 屬性枚碗。
  • sun.locale.formatasdefault 屬性。
  • jdk snmp 模塊铸本。
  • javafx肮雨,openjdk 是從java10版本就移除了,oracle java10還尚未移除javafx 箱玷,而java11版本將javafx也移除了怨规。
  • Java Mission Control,從JDK中移除之后锡足,需要自己單獨(dú)下載波丰。
  • Root Certificates :Baltimore Cybertrust Code Signing CA,SECOM 舶得,AOL and Swisscom掰烟。
  • 在java11中將java9標(biāo)記廢棄的Java EE及CORBA模塊移除掉。

完全支持Linux容器(包括docker)

許多運(yùn)行在Java虛擬機(jī)中的應(yīng)用程序(包括Apache Spark和Kafka等數(shù)據(jù)服務(wù)以及傳統(tǒng)的企業(yè)應(yīng)用程序)都可以在Docker容器中運(yùn)行沐批。但是在Docker容器中運(yùn)行Java應(yīng)用程序一直存在一個(gè)問題纫骑,那就是在容器中運(yùn)行JVM程序在設(shè)置內(nèi)存大小和CPU使用率后,會(huì)導(dǎo)致應(yīng)用程序的性能下降九孩。這是因?yàn)镴ava應(yīng)用程序沒有意識到它正在容器中運(yùn)行先馆。隨著Java 10的發(fā)布,這個(gè)問題總算得以解決躺彬,JVM現(xiàn)在可以識別由容器控制組(cgroups)設(shè)置的約束煤墙∶饭撸可以在容器中使用內(nèi)存和CPU約束來直接管理Java應(yīng)用程序,其中包括:

  • 遵守容器中設(shè)置的內(nèi)存限制
  • 在容器中設(shè)置可用的CPU
  • 在容器中設(shè)置CPU約束

Java 10的這個(gè)改進(jìn)在Docker for Mac仿野、Docker for Windows以及Docker Enterprise Edition等環(huán)境均有效铣减。

總結(jié)

原文鏈接:https://juejin.im/post/5dc0e1caf265da4d47042543

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市设预,隨后出現(xiàn)的幾起案子徙歼,更是在濱河造成了極大的恐慌,老刑警劉巖鳖枕,帶你破解...
    沈念sama閱讀 218,036評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件魄梯,死亡現(xiàn)場離奇詭異,居然都是意外死亡宾符,警方通過查閱死者的電腦和手機(jī)酿秸,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,046評論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來魏烫,“玉大人辣苏,你說我怎么就攤上這事『灏” “怎么了稀蟋?”我有些...
    開封第一講書人閱讀 164,411評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長呐赡。 經(jīng)常有香客問我退客,道長,這世上最難降的妖魔是什么链嘀? 我笑而不...
    開封第一講書人閱讀 58,622評論 1 293
  • 正文 為了忘掉前任萌狂,我火速辦了婚禮,結(jié)果婚禮上怀泊,老公的妹妹穿的比我還像新娘茫藏。我一直安慰自己,他們只是感情好霹琼,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,661評論 6 392
  • 文/花漫 我一把揭開白布务傲。 她就那樣靜靜地躺著,像睡著了一般枣申。 火紅的嫁衣襯著肌膚如雪树灶。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,521評論 1 304
  • 那天糯而,我揣著相機(jī)與錄音,去河邊找鬼泊窘。 笑死熄驼,一個(gè)胖子當(dāng)著我的面吹牛像寒,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播瓜贾,決...
    沈念sama閱讀 40,288評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼诺祸,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了普泡?” 一聲冷哼從身側(cè)響起钦睡,我...
    開封第一講書人閱讀 39,200評論 0 276
  • 序言:老撾萬榮一對情侶失蹤冯凹,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后胃夏,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,644評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡昌跌,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,837評論 3 336
  • 正文 我和宋清朗相戀三年仰禀,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片蚕愤。...
    茶點(diǎn)故事閱讀 39,953評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡答恶,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出萍诱,到底是詐尸還是另有隱情悬嗓,我是刑警寧澤,帶...
    沈念sama閱讀 35,673評論 5 346
  • 正文 年R本政府宣布裕坊,位于F島的核電站包竹,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏碍庵。R本人自食惡果不足惜映企,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,281評論 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望静浴。 院中可真熱鬧堰氓,春花似錦、人聲如沸苹享。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,889評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽得问。三九已至囤攀,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間宫纬,已是汗流浹背焚挠。 一陣腳步聲響...
    開封第一講書人閱讀 33,011評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留漓骚,地道東北人蝌衔。 一個(gè)月前我還...
    沈念sama閱讀 48,119評論 3 370
  • 正文 我出身青樓榛泛,卻偏偏與公主長得像,于是被迫代替她去往敵國和親噩斟。 傳聞我的和親對象是個(gè)殘疾皇子曹锨,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,901評論 2 355

推薦閱讀更多精彩內(nèi)容