<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          Java枚舉深度解讀,看這篇就夠了

          共 12222字,需瀏覽 25分鐘

           ·

          2020-09-18 14:08

          點(diǎn)擊上方藍(lán)色字體,選擇“標(biāo)星公眾號”

          優(yōu)質(zhì)文章,第一時間送達(dá)

          ? 作者?|??濤GuoGuo的跟屁蟲丶博Ke?

          來源 |? urlify.cn/aaamQf

          66套java從入門到精通實(shí)戰(zhàn)課程分享

          Java枚舉

          1、枚舉類概念的理解與定義

          • 一個類的對象是有限個,確定的,我們稱此為枚舉類。

          • 當(dāng)需要定義和維護(hù)一組常量時,強(qiáng)烈建議使用枚舉類。

          • 如果一個枚舉類中只有一個對象,則可以作為單例模式的實(shí)現(xiàn)方式。

          通俗的說:一個類被設(shè)計為包含固定實(shí)例數(shù)量的特殊類,我們給他的定義是枚舉類。

          注意:
          1.枚舉類不能被 new 出來,枚舉類因?yàn)槟J(rèn)的類修飾符為 final 所以也不能被派生(繼承),同理枚舉類也不能為當(dāng)作實(shí)現(xiàn)。
          2.枚舉類自身可以實(shí)現(xiàn)接口,既可以進(jìn)行統(tǒng)一實(shí)現(xiàn)重寫接口抽象方法,也可以按照枚舉類型單個實(shí)現(xiàn)重寫。


          2、枚舉類的定義

          關(guān)于枚舉類的定義,這塊主要想和大家分享兩種方式

          1. jdk 5.0之前,自定義枚舉類方式

          2. jdk 5.0之后,Enum關(guān)鍵字方式定義


          3、實(shí)踐

          (一)、準(zhǔn)備工作

          我們新建一個 Java Project ,并創(chuàng)建一個包,以及一個測試類

          (二)、自定義枚舉的三種方式(jdk 5.0 之前)

          1. 定義一個抽象類,在抽象類中定義常量進(jìn)行維護(hù),我們接下來以 Java 類庫中的 Calendar 類示例來進(jìn)行說明

          新建一個類 EnumDemo01.java 代碼如下:

          package?org.taoguoguo;
          import?java.util.Calendar;

          /**
          ?*?@author?taoGG
          ?*?@description?jdk?5.0?之前?抽象類枚舉方案Demo
          ?*?@create?2020-09-13?14:20
          ?*/
          public?class?EnumDemo01?{
          ????public?static?void?main(String[]?args)?{
          ????????Calendar?calendar?=?Calendar.getInstance();
          ????????System.out.println(calendar.get(1));
          ????}
          }

          Console 結(jié)果輸出:

          2020
          Process?finished?with?exit?code?0

          如果熟悉?Calendar API?的小伙伴 應(yīng)該馬上能反應(yīng)過來,這個是獲取當(dāng)前的年份,類似的值還有

          3?-?一年中的第幾個星期
          4?-?一年中的第幾個月
          5?-?當(dāng)前的日期?
          ......

          但是這么多值,我們怎么能記得住呢?萬一我輸入錯誤,隨便取了一個范圍怎么辦?

          沒錯,這是 jdk 5.0之前的痛點(diǎn),為了解決實(shí)例數(shù)量固定,便于維護(hù)這些問題,在jdk 5.0之后更新Enum枚舉類解決了這個問題。那在jdk 5.0之前官方是怎么做的呢?難道需要我們一個個去記住?Calendar?的數(shù)字?

          實(shí)際上官方本身,采用的就是我們現(xiàn)在說的第一種方式,在抽象類中定義常量進(jìn)行維護(hù)

          現(xiàn)在我們將代碼做些修改:

          package?org.taoguoguo;
          import?java.util.Calendar;

          /**
          ?*?@author?taoGG
          ?*?@description?jdk?5.0?之前?抽象類枚舉方案Demo
          ?*?@create?2020-09-13?14:20
          ?*/
          public?class?EnumDemo01?{
          ????public?static?void?main(String[]?args)?{
          ????????Calendar?calendar?=?Calendar.getInstance();
          ????????System.out.println(calendar.get(Calendar.YEAR));
          ????}
          }

          我們運(yùn)行進(jìn)行輸出:

          2020
          Process?finished?with?exit?code?0

          結(jié)果與之前一致,這時我們就清楚,在開發(fā)過程中作為開發(fā)者我們肯定愿意使用?Calendar.YEAR?這種寫法,一來方便記憶,二來可讀性高。那么官方的做法時怎樣的呢?我們點(diǎn)進(jìn)去源碼看一下

          1. 首先?Calendar?本身是一個抽象類,實(shí)現(xiàn)了序列化、克隆、以及比較排序接口,這邊和我們枚舉沒有太大關(guān)系,我們繼續(xù)往下看

          2. 在抽象類中,定義了很多個靜態(tài)常量進(jìn)行維護(hù),而當(dāng)我們需要使用時,直接調(diào)用,這樣就比我們寫一個個的具體值要方便和易用了。

          2. 定義一個接口,在接口中定義常量維護(hù)枚舉值

          我們新建一個interface CustomerInf.java

          package?org.taoguoguo;

          /**
          ?*?@author?taoGG
          ?*?@description?接口常量維護(hù)枚舉值
          ?*?@create?2020-09-13?15:47
          ?*/
          public?interface?CustomerInf?{
          ???int?RED?=?1;
          ???int?GREEN?=?2;
          ???int?BLUE?=?3;
          }

          在?EnumTest?進(jìn)行測試

          package?org.taoguoguo;

          /**
          ?*?@author?taoGG
          ?*?@description?Java枚舉測試類
          ?*?@create?2020-09-13?14:54
          ?*
          ?*/
          public?class?EnumTest?{
          ????public?static?void?main(String[]?args)?{
          ????????System.out.println(CustomerInf.RED);
          ????}
          }

          測試結(jié)果:

          1
          Process?finished?with?exit?code?0

          這種做法我們達(dá)到了和在抽象類中維護(hù)常量相同的目的。上面這兩種做法都非常的簡單易用,但也有弊端。比如我們只知道一個狀態(tài)值,當(dāng)我們要獲取狀態(tài)的屬性或者相關(guān)的內(nèi)容時,我們該怎么做呢?

          下面我們使用第三種方式,自定義枚舉類,這種基本上達(dá)到和 Enum 關(guān)鍵字相同的作用,但有一點(diǎn)不足就是會較為復(fù)雜

          3.自定義枚舉類,通過為類私有化構(gòu)造器和固定實(shí)例對象進(jìn)行枚舉維護(hù)

          新建一個class SeasonEnum.java,代碼如下:

          package?org.taoguoguo;

          /**
          ?*?@author?taoGG
          ?*?@description
          ?*?@create?2020-09-13?15:58
          ?*/
          public?class?SeasonEnum?{
          ????//1.聲明枚舉對象的屬性
          ????private?final?String?seasonName;
          ????private?final?int?code;

          ????//2.私有化類的構(gòu)造器
          ????private?SeasonEnum(String?seasonName,int?code){
          ????????this.seasonName?=?seasonName;
          ????????this.code?=?code;
          ????}

          ????//3.提供當(dāng)前枚舉類的多個對象?public?static?final
          ????public?static?final?SeasonEnum?SPRING?=?new?SeasonEnum("春天",100);
          ????public?static?final?SeasonEnum?SUMMER?=?new?SeasonEnum("夏天",200);
          ????public?static?final?SeasonEnum?AUTUMN?=?new?SeasonEnum("秋天",300);
          ????public?static?final?SeasonEnum?WINTER?=?new?SeasonEnum("冬天",400);

          ????//4.為類提供獲取屬性的方法
          ????public?String?getSeasonName()?{
          ????????return?seasonName;
          ????}
          ????public?int?getCode()?{
          ????????return?code;
          ????}
          ????//5.重寫toString方法
          ????@Override
          ????public?String?toString()?{
          ????????return?"SeasonEnum{"?+
          ????????????????"seasonName='"?+?seasonName?+?'\''?+
          ????????????????",?code="?+?code?+
          ????????????????'
          }';
          ????}
          }

          新建一個class SeasonEnumTest 進(jìn)行測試,當(dāng)我們通過自定義枚舉類引用實(shí)例對象時,如下圖可以看到,我們已經(jīng)可以獲取到我們的枚舉對象了。

          獲取到枚舉對象,我們當(dāng)然也可以獲取到對應(yīng)的屬性及方法,這種可用性就提高了很多,我們在開發(fā)程序進(jìn)行判斷,可以根據(jù)各種枚舉值的指定屬性來進(jìn)行,提高了代碼的可維護(hù)性。

          SeasonEnumTest 測試代碼

          package?org.taoguoguo;

          /**
          ?*?@author?taoGG
          ?*?@description
          ?*?@create?2020-09-13?16:04
          ?*/
          public?class?SeasonEnumTest?{
          ????public?static?void?main(String[]?args)?{
          ????????SeasonEnum?spring?=?SeasonEnum.SPRING;
          ????????System.out.println("自定義枚舉類對象:"?+?spring);
          ????????System.out.println("自定義枚舉類屬性:"?+?spring.getSeasonName());
          ????????System.out.println("自定義枚舉類屬性:"?+?spring.getCode());
          ????}
          }


          根據(jù)我們上面的自定義枚舉類方式,我們基本已經(jīng)實(shí)現(xiàn)了枚舉的功能了,但是就像上面說到的,如果開發(fā)中枚舉類型較多,開發(fā)多個這樣的自定義枚舉類會非常的耗時,所以 jdk 5.0 之后,推出了 Enum 關(guān)鍵字定義枚舉類

          (三)Enum 關(guān)鍵字定義枚舉類(jdk 5.0之后)

          enum?全稱為?enumeration,是jdk 5.0 中引入的新特性,在Java 中被?enum?關(guān)鍵字修飾的類型就是枚舉類型

          我們通過代碼來示例來講解和理解?enum?的用法,還是用我們剛剛自定以枚舉類的例子,看看使用enum如何來寫

          新建一個Java class ,Kind?類型選擇?enum?如圖:

          枚舉類創(chuàng)建注意:

          • 枚舉實(shí)例必須在?enum關(guān)鍵字聲明的類中顯式的指定(首行開始的以第一個分號結(jié)束)

          • 枚舉不允許使用new,clone,反射,序列化手動創(chuàng)建枚舉實(shí)例

          package?org.taoguoguo;

          /**
          ?*?@author?taoGG
          ?*?@description
          ?*?@create?2020-09-13?16:23
          ?*/
          public?enum?Season?{
          ????SPRING("春天",100),
          ????SUMMER("夏天",200),
          ????AUTUMN("秋天",300),
          ????WINTER("冬天",400);

          ????private?final?String?seasonName;
          ????private?final?int?code;

          ????Season(String?seasonName,?int?code){
          ????????this.seasonName?=?seasonName;
          ????????this.code?=?code;
          ????}

          ????public?String?getSeasonName()?{
          ????????return?seasonName;
          ????}
          ????public?int?getCode()?{
          ????????return?code;
          ????}
          }

          使用?SeasonTest?測試類進(jìn)行測試:

          package?org.taoguoguo;

          /**
          ?*?@author?taoGG
          ?*?@description
          ?*?@create?2020-09-13?16:27
          ?*/
          public?class?SeasonTest?{
          ????public?static?void?main(String[]?args)?{
          ????????Season?spring?=?Season.SPRING;
          ????????System.out.println(spring);
          ????}
          }


          輸出結(jié)果:

          SPRING
          Process?finished?with?exit?code?0

          注意,在enmu 枚舉類中如果沒有重寫 toString方法,會默認(rèn)使用Enum類本身提供的 toString 方法,返回枚舉類名稱,因?yàn)槎x的枚舉類默認(rèn)隱式繼承于java.lang.Enum

          1.枚舉類主要方法介紹


          • values()??:該方法可以返回當(dāng)前枚舉類型的對象數(shù)組,可以很方便的遍歷所有枚舉值。一般我們可以根據(jù)枚舉類的相關(guān)屬性通過此方法遍歷獲取對應(yīng)的枚舉對象及枚舉值

          • valueOf(String str)?: 根據(jù)枚舉類名稱獲取枚舉類對象

          • toString(): 默認(rèn)使用 java.lang.Enum的 toString方法,返回當(dāng)前對象常量的名稱,枚舉類推薦重寫返回自定義友好描述

          • name(): 返回當(dāng)前枚舉對象名稱,和toString作用上類似,當(dāng)時toString支持重寫,name方法是不能重寫的,在本質(zhì)上 toString 也是調(diào)用的 name方法,枚舉定義 name 方法就是為了返回枚舉對象名稱,而 toString 應(yīng)該根據(jù)需要進(jìn)行重寫

          • ordinal(): 返回當(dāng)前枚舉對象的序號, 實(shí)現(xiàn)了 Comparable 接口,表明它是支持排序的 可以通過?Collections.sort?進(jìn)行自動排序比較此枚舉與指定對象的順序

          • compareTo(): 基于ordinal進(jìn)行序號大小比較

          方式演示代碼,小伙伴們可以自行運(yùn)行輸出一下,看看各個方法的作用,熟悉一下相關(guān)的方法api

          package?org.taoguoguo;

          /**
          ?*?@author?taoGG
          ?*?@description
          ?*?@create?2020-09-13?16:27
          ?*/
          public?class?SeasonTest?{
          ????public?static?void?main(String[]?args)?{
          ????????System.out.println("========values()方法=======");
          ????????for?(Season?season?:?Season.values())?{
          ????????????System.out.println(season);
          ????????}
          ????????System.out.println("===========================");
          ?
          ????????System.out.println("========valueOf方法========");
          ????????Season?spring?=?Season.valueOf("SPRING");
          ????????System.out.println(spring);
          ????????System.out.println("===========================");

          ????????System.out.println("========toString方法========");
          ????????System.out.println(spring.toString());
          ????????System.out.println("===========================");

          ????????System.out.println("========name方法========");
          ????????System.out.println(spring.name());
          ????????System.out.println("===========================");

          ????????System.out.println("========ordinal方法========");
          ????????System.out.println(spring.ordinal());
          ????????System.out.println("===========================");

          ????????System.out.println("========compareTo方法========");
          ????????System.out.println(spring.compareTo(Season.WINTER));
          ????????System.out.println("===========================");
          ????}
          }

          2.枚舉類對接口的實(shí)現(xiàn)方式

          準(zhǔn)備工作

          新建一個EnumInf?接口,定義一個抽象方法

          package?org.taoguoguo;

          /**
          ?*?@author?taoGG
          ?*?@description
          ?*?@create?2020-09-13?17:25
          ?*/
          public?interface?EnumInf?{
          ????void?show();
          }

          1.實(shí)現(xiàn)接口,在enum中統(tǒng)一實(shí)現(xiàn)抽象方法

          新建一個EnumInf?接口,定義抽象方法?show()

          package?org.taoguoguo;

          /**
          ?*?@author?taoGG
          ?*?@description
          ?*?@create?2020-09-13?17:25
          ?*/
          public?interface?EnumInf?{
          ????void?show();
          }


          新建一個OrderStatus?枚舉類 實(shí)現(xiàn)?EnumInf?接口

          package?org.taoguoguo;

          /**
          ?*?@author?taoGG
          ?*?@description
          ?*?@create?2020-09-13?17:27
          ?*/
          public?enum?OrderStatus?implements?EnumInf{

          ????SUCCESS(200,"交易成功"),
          ????Fail(500,"交易失敗");

          ????private?final?int?code;
          ????private?final?String?desc;

          ????OrderStatus(int?code,?String?desc){
          ????????this.code?=?code;
          ????????this.desc?=?desc;
          ????}

          ????public?int?getCode()?{
          ????????return?code;
          ????}
          ????public?String?getDesc()?{
          ????????return?desc;
          ????}

          ????/**
          ?????*?第一種方式,枚舉統(tǒng)一重寫接口抽象方法
          ?????*/
          ????@Override
          ????public?void?show()?{
          ????????System.out.println("訂單枚舉對象");
          ????}
          }

          進(jìn)行測試

          package?org.taoguoguo;

          /**
          ?*?@author?taoGG
          ?*?@description
          ?*?@create?2020-09-13?17:32
          ?*/
          public?class?OrderStatusTest?{
          ????public?static?void?main(String[]?args)?{
          ????????OrderStatus?success?=?OrderStatus.SUCCESS;
          ????????success.show();
          ????}
          }


          輸出結(jié)果

          訂單枚舉對象

          Process?finished?with?exit?code?0

          跟我們常用類實(shí)現(xiàn)沒有什么區(qū)別,枚舉也是可以統(tǒng)一實(shí)現(xiàn)的,那如果想針對不同的枚舉對象進(jìn)行不同狀態(tài)的實(shí)現(xiàn)怎么辦呢?比如我們的OA系統(tǒng)、或者電商系統(tǒng)中,根據(jù)不同狀態(tài) 我們需要回寫對應(yīng)的數(shù)據(jù),下面我們就來看看如何實(shí)現(xiàn)。

          2.枚舉對象分別實(shí)現(xiàn)接口中的抽象方法

          案例跟接口統(tǒng)一實(shí)現(xiàn)一致,我們這邊修改一下OrderStatus?枚舉類,代碼如下

          package?org.taoguoguo;

          /**
          ?*?@author?taoGG
          ?*?@description
          ?*?@create?2020-09-13?17:27
          ?*/
          public?enum?OrderStatus?implements?EnumInf{

          ????SUCCESS(200,"交易成功")?{
          ????????@Override
          ????????public?void?show()?{
          ????????????System.out.println("回寫交易成功狀態(tài)");
          ????????}
          ????},
          ????Fail(500,"交易失敗")?{
          ????????@Override
          ????????public?void?show()?{
          ????????????System.out.println("回寫交易失敗狀態(tài)");
          ????????}
          ????};

          ????private?final?int?code;
          ????private?final?String?desc;

          ????OrderStatus(int?code,?String?desc){
          ????????this.code?=?code;
          ????????this.desc?=?desc;
          ????}

          ????public?int?getCode()?{
          ????????return?code;
          ????}
          ????public?String?getDesc()?{
          ????????return?desc;
          ????}

          }

          我們再修改下測試類代碼:

          package?org.taoguoguo;

          /**
          ?*?@author?taoGG
          ?*?@description
          ?*?@create?2020-09-13?17:32
          ?*/
          public?class?OrderStatusTest?{
          ????public?static?void?main(String[]?args)?{
          ????????OrderStatus?success?=?OrderStatus.SUCCESS;
          ????????success.show();
          ????????OrderStatus?fail?=?OrderStatus.Fail;
          ????????fail.show();
          ????}
          }

          輸出結(jié)果

          回寫交易成功狀態(tài)
          回寫交易失敗狀態(tài)

          Process?finished?with?exit?code?0

          通過這種方式就可以輕而易舉地定義每個枚舉實(shí)例不同的行為方式,也達(dá)到了我們預(yù)期的效果,其實(shí)在開發(fā)過程中根據(jù)枚舉的設(shè)計和設(shè)計模式的鋪墊可以極大的簡化我們的業(yè)務(wù)代碼。

          3.Enum枚舉類的工具類及應(yīng)用場景

          1.EnumSet 和 EnumMap

          Java 中提供了兩個方便操作enum的工具類——EnumSet 和 EnumMap。

          EnumSet?是枚舉類型的高性能?Set?實(shí)現(xiàn)。它要求放入它的枚舉常量必須屬于同一枚舉類型。

          //?EnumSet的使用
          System.out.println("EnumSet展示");
          EnumSet?errSet?=?EnumSet.allOf(OrderStatus.class);
          for?(OrderStatus?e?:?errSet)?{
          ????System.out.println(e.name()?+?"?:?"?+?e.ordinal());
          }

          EnumMap?是專門為枚舉類型量身定做的?Map?實(shí)現(xiàn)。雖然使用其它的 Map 實(shí)現(xiàn)(如HashMap)也能完成枚舉類型實(shí)例到值得映射,但是使用 EnumMap 會更加高效:它只能接收同一枚舉類型的實(shí)例作為鍵值,并且由于枚舉類型實(shí)例的數(shù)量相對固定并且有限,所以 EnumMap 使用數(shù)組來存放與枚舉類型對應(yīng)的值。(計算機(jī)處理連續(xù)的資源使用局部內(nèi)存效率更高)這使得 EnumMap 的效率非常高。

          //?EnumMap的使用
          System.out.println("EnumMap展示");
          EnumMap?errMap?=?new?EnumMap(StateMachine.Signal.class);
          errMap.put(StateMachine.Signal.RED,?"紅燈");
          errMap.put(StateMachine.Signal.YELLOW,?"黃燈");
          errMap.put(StateMachine.Signal.GREEN,?"綠燈");
          for?(Iterator>?iter?=errMap.entrySet().iterator();?iter.hasNext();)?{
          ????Map.Entry?entry?=?iter.next();
          ????System.out.println(entry.getKey().name()?+?"?:?"?+?entry.getValue());
          }

          2.枚舉類與 Switch 的配合使用

          關(guān)于枚舉與switch是個比較簡單的話題,使用switch進(jìn)行條件判斷時,條件參數(shù)一般只能是整型,字符型。而枚舉型確實(shí)也被switch所支持,在java 1.7后switch也對字符串進(jìn)行了支持。

          實(shí)踐

          新建一個?BizEnum?的java class,代碼如下

          package?org.taoguoguo;

          /**
          ?*?@author?taoGG
          ?*?@description?企業(yè)類型枚舉
          ?*?@create?2020-09-13?21:24
          ?*/
          public?enum?BizEnum?{

          ????COUNTRIES(101,"國有企業(yè)"),

          ????PRIVETE(102,"私營企業(yè)"),

          ????SOHO(103,"個體單位");

          ????private?final?int?code;
          ????private?final?String?desc;

          ????BizEnum(int?code,?String?desc){
          ????????this.code?=?code;
          ????????this.desc?=?desc;
          ????}

          ????public?int?getCode()?{
          ????????return?code;
          ????}
          ????public?String?getDesc()?{
          ????????return?desc;
          ????}

          ????//根據(jù)編碼獲取當(dāng)前枚舉對象的方法
          ????public?static?BizEnum?getBizTypeByCode(int?code){
          ????????for?(BizEnum?bizEnum?:?BizEnum.values())?{
          ????????????if(code?==?bizEnum.getCode()){
          ????????????????return?bizEnum;
          ????????????}
          ????????}
          ????????return?null;
          ????}
          }

          結(jié)合Switch進(jìn)行測試

          package?org.taoguoguo;

          /**
          ?*?@author?taoGG
          ?*?@description
          ?*?@create?2020-09-13?21:31
          ?*/
          public?class?BizTest?{
          ????public?static?void?main(String[]?args)?{
          ????????BizEnum?bizType?=?BizEnum.getBizTypeByCode(101);
          ????????switch?(bizType){
          ????????????case?COUNTRIES:
          ????????????????System.out.println("國有企業(yè)");
          ????????????????break;
          ????????????case?PRIVETE:
          ????????????????System.out.println("私營企業(yè)");
          ????????????????break;
          ????????????case?SOHO:
          ????????????????System.out.println("個體單位");
          ????????????????break;
          ????????????default:
          ????????????????System.out.println("創(chuàng)業(yè)中");
          ????????}
          ????}
          }

          輸出結(jié)果:

          國有企業(yè)

          Process?finished?with?exit?code?0

          總結(jié)

          1. jdk 5.0之前我們可以自定義枚舉類,jdk 5.0之后使用enum關(guān)鍵字定義枚舉類,枚舉類默認(rèn)繼承自java.lang.Enum,使用枚舉類將常量組織起來,便于統(tǒng)一管理。例如錯誤碼狀態(tài)機(jī)等場景中,較為合適使用枚舉類。

          2. 枚舉類常用方法介紹及枚舉類實(shí)現(xiàn)抽象類、接口等抽象方法的兩種方式。

          3. 枚舉常用的工具類及與switch使用的場景。




          粉絲福利:108本java從入門到大神精選電子書領(lǐng)取

          ???

          ?長按上方鋒哥微信二維碼?2 秒
          備注「1234」即可獲取資料以及
          可以進(jìn)入java1234官方微信群



          感謝點(diǎn)贊支持下哈?

          瀏覽 85
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  小电影在线观看黄.999 | 欧美中文字幕免费在线观看 | 青青草自拍偷拍在线视频 | 大香蕉伊人成人电影 | 韩日三级黄色视频 |