<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                # Java 數據類型 II 原文:http://zetcode.com/lang/java/datatypes2/ 在 Java 教程的這一部分中,我們將繼續介紹 Java 的數據類型。 我們介紹了包裝器類,裝箱和拆箱,默認值,轉換和促銷。 ## Java 包裝器類 包裝器類是原始數據類型的對象表示。 需要`Object`時,包裝器類用于表示原始值。 例如,Java 集合僅適用于對象。 它們不能采用原始類型。 包裝器類還包括一些有用的方法。 例如,它們包括進行數據類型轉換的方法。 將原始類型放入包裝器類稱為`boxing`。 反向過程稱為`unboxing`。 通常,在有某種理由的情況下,我們使用包裝器類。 否則,我們使用原始類型。 包裝器類是不可變的。 創建它們后,就無法更改它們。 基本類型比裝箱類型更快。 在科學計算和其他大規模數字處理中,包裝類可能會嚴重影響性能。 | 原始類型 | 包裝類 | 構造器參數 | | --- | --- | --- | | `byte` | `Byte` | `byte`或`String` | | `short` | `Short` | `short`或`String` | | `int` | `Integer` | `int`或`String` | | `long` | `Long` | `long`或`String` | | `float` | `Float` | `float`,`double`或`String` | | `double` | `Double` | `double`或`String` | | `char` | `Char` | `char` | | `boolean` | `Boolean` | `boolean`或`String` | Table: Primitive types and their wrapper class equivalents `Integer`類將原始類型`int`的值包裝在對象中。 它包含在處理`int`時有用的常量和方法。 `com/zetcode/IntegerWrapper.java` ```java package com.zetcode; public class IntegerWrapper { public static void main(String[] args) { int a = 55; Integer b = new Integer(a); int c = b.intValue(); float d = b.floatValue(); String bin = Integer.toBinaryString(a); String hex = Integer.toHexString(a); String oct = Integer.toOctalString(a); System.out.println(a); System.out.println(b); System.out.println(c); System.out.println(d); System.out.println(bin); System.out.println(hex); System.out.println(oct); } } ``` 本示例適用于`Integer`包裝器類。 ```java int a = 55; ``` 該行創建一個整數原始數據類型。 ```java Integer b = new Integer(a); ``` `Integer`包裝器類是從原始`int`類型創建的。 ```java int c = b.intValue(); float d = b.floatValue(); ``` `intValue()`方法將`Integer`轉換為`int`。 同樣,`floatValue()`返回`float`數據類型。 ```java String bin = Integer.toBinaryString(a); String hex = Integer.toHexString(a); String oct = Integer.toOctalString(a); ``` 這三種方法返回整數的二進制,十六進制和八進制表示形式。 ```java $ java IntegerWrapper.java 55 55 55 55.0 110111 37 67 ``` 這是程序輸出。 集合是用于處理對象組的強大工具。 原始數據類型不能放入 Java 集合中。 將原始值裝箱后,可以將它們放入集合中。 `com/zetcode/Numbers.java` ```java package com.zetcode; import java.util.ArrayList; import java.util.List; public class Numbers { public static void main(String[] args) { List<Number> ls = new ArrayList<>(); ls.add(1342341); ls.add(new Float(34.56)); ls.add(235.242); ls.add(new Byte("102")); ls.add(new Short("1245")); for (Number n : ls) { System.out.println(n.getClass()); System.out.println(n); } } } ``` 在示例中,我們將各種數字放入`ArrayList`中。 `ArrayList`是動態的,可調整大小的數組。 ```java List<Number> ls = new ArrayList<>(); ``` 創建一個`ArrayList`實例。 在尖括號中,我們指定容器將容納的類型。 `Number`是 Java 中所有五個數字基本類型的抽象基類。 ```java ls.add(1342341); ls.add(new Float(34.56)); ls.add(235.242); ls.add(new Byte("102")); ls.add(new Short("1245")); ``` 我們將五個數字添加到集合中。 請注意,整數和雙精度值未裝箱; 這是因為對于整數和雙精度類型,編譯器將執行自動裝箱。 ```java for (Number n : ls) { System.out.println(n.getClass()); System.out.println(n); } ``` 我們遍歷容器并打印類名稱及其每個元素的值。 ```java $ java Numbers.java class java.lang.Integer 1342341 class java.lang.Float 34.56 class java.lang.Double 235.242 class java.lang.Byte 102 class java.lang.Short 1245 ``` `com.zetcode.Numbers`程序給出該輸出。 請注意,這兩個數字是由編譯器自動裝箱的。 ## Java 裝箱 從原始類型轉換為對象類型稱為`boxing`。 `Unboxing`是相反的操作。 它正在將對象類型轉換回原始類型。 `com/zetcode/BoxingUnboxing.java` ```java package com.zetcode; public class BoxingUnboxing { public static void main(String[] args) { long a = 124235L; Long b = new Long(a); long c = b.longValue(); System.out.println(c); } } ``` 在代碼示例中,我們將`long`值放入`Long`對象中,反之亦然。 ```java Long b = new Long(a); ``` 該行執行拳擊。 ```java long c = b.longValue(); ``` 在這一行,我們進行拆箱。 ## Java 自動裝箱 Java 5 引入了自動裝箱。 `Autoboxing`是原始類型及其對應的對象包裝器類之間的自動轉換。 自動裝箱使編程更加容易。 程序員不需要手動進行轉換。 當一個值是原始類型而另一個值是包裝器類時,將執行自動裝箱和拆箱: * 賦值 * 將參數傳遞給方法 * 從方法返回值 * 比較操作 * 算術運算 ```java Integer i = new Integer(50); if (i < 100) { ... } ``` 在`if`表達式的方括號內,將`Integer`與`int`進行比較。 `Integer`對象被轉換為原始`int`類型,并與 100 值進行比較。 自動取消裝箱。 `com/zetcode/Autoboxing.java` ```java package com.zetcode; public class Autoboxing { private static int cube(int x) { return x * x * x; } public static void main(String[] args) { Integer i = 10; int j = i; System.out.println(i); System.out.println(j); Integer a = cube(i); System.out.println(a); } } ``` 此代碼示例演示了自動裝箱和自動拆箱。 ```java Integer i = 10; ``` Java 編譯器在此代碼行中執行自動裝箱。 將`int`值裝箱為`Integer`類型。 ```java int j = i; ``` 在這里會自動開箱。 ```java Integer a = cube(i); ``` 當我們將`Integer`傳遞給`cube()`方法時,便完成了自動拆箱。 當我們返回計算值時,將執行自動裝箱,因為`int`轉換回了`Integer`。 Java 語言不支持運算符重載。 當我們對包裝類應用算術運算時,自動裝箱由編譯器完成。 `com/zetcode/Autoboxing2.java` ```java package com.zetcode; public class Autoboxing2 { public static void main(String[] args) { Integer a = new Integer(5); Integer b = new Integer(7); Integer add = a + b; Integer mul = a * b; System.out.println(add); System.out.println(mul); } } ``` 我們有兩個`Integer`值。 我們對這兩個值執行加法和乘法運算。 ```java Integer add = a + b; Integer mul = a * b; ``` 與 Ruby,C# ,Python,D 或 C++ 等語言不同,Java 沒有實現運算符重載。 在這兩行中,編譯器調用`intValue()`方法,并將包裝器類轉換為`int`,然后通過調用`valueOf()`方法將結果包裝回`Integer`。 ## Java 自動裝箱和對象內化 `Object intering`僅存儲每個不同對象的一個??副本。 該對象必須是不可變的。 不同的對象存儲在內部池中。 在 Java 中,當將原始值裝箱到包裝對象中時,將插入某些值(任何布爾值,任何字節,0 到 127 之間的任何`char`以及 -128 和 127 之間的任何`short`或`int`),以及這兩個值之一的任意裝箱轉換可以確保得到相同的對象。 根據 Java 語言規范,這些是最小范圍。 因此,行為取決于實現。 對象交互可以節省時間和空間。 從字面值,自動裝箱和`Integer.valueOf()`中獲得的對象是內部對象,而使用`new`運算符構造的對象始終是不同的對象。 比較包裝類時,對象交互會產生一些重要的后果。 `==`運算符比較對象的引用標識,而`equals()`方法比較值。 `com/zetcode/Autoboxing3.java` ```java package com.zetcode; public class Autoboxing3 { public static void main(String[] args) { Integer a = 5; // new Integer(5); Integer b = 5; // new Integer(5); System.out.println(a == b); System.out.println(a.equals(b)); System.out.println(a.compareTo(b)); Integer c = 155; Integer d = 155; System.out.println(c == d); System.out.println(c.equals(d)); System.out.println(c.compareTo(d)); } } ``` 該示例比較了一些`Integer`對象。 ```java Integer a = 5; // new Integer(5); Integer b = 5; // new Integer(5); ``` 兩個整數裝在`Integer`包裝器類中。 ```java System.out.println(a == b); System.out.println(a.equals(b)); System.out.println(a.compareTo(b)); ``` 使用三種不同的方法比較這些值。 `==`運算符比較兩種盒裝類型的引用標識。 由于對象的嵌入,該運算結果為`true`。 如果使用`new`運算符,則將創建兩個不同的對象,并且`==`運算符將返回`false`。 `equals()`方法在數值上比較兩個`Integer`對象。 它返回布爾值`true`或`false`(在我們的例子中為`true`)。 最后,`compareTo()`方法還對兩個對象進行了數值比較。 如果此`Integer`等于參數`Integer`,則返回值 0; 如果此`Integer`在數值上小于參數`Integer`,則該值小于 0; 如果此`Integer`在數值上大于自變量`Integer`,則該值大于 0。 ```java Integer c = 155; Integer d = 155; ``` 我們還有兩種盒裝類型。 但是,這些值大于內化的最大值(127); 因此,創建了兩個不同的對象。 這次`==`運算符產生`false`。 ```java $ java Autoboxing3.java true true 0 false true 0 ``` 這是程序的輸出。 ## Java 空類型 Java 具有特殊的`null`類型。 類型沒有名稱。 結果,不可能聲明`null`類型的變量或將其強制轉換為`null`類型。 `null`表示一個空引用,不引用任何對象。 `null`是引用類型變量的默認值。 不能為原始類型分配`null`字面值。 在不同的上下文中,`null`表示不存在對象,未知值或未初始化狀態。 `com/zetcode/NullType.java` ```java package com.zetcode; import java.util.Random; public class NullType { private static String getName() { Random r = new Random(); boolean n = r.nextBoolean(); if (n == true) { return "John"; } else { return null; } } public static void main(String[] args) { String name = getName(); System.out.println(name); System.out.println(null == null); if ("John".equals(name)) { System.out.println("His name is John"); } } } ``` 我們在程序中使用`null`值。 ```java private static String getName() { Random r = new Random(); boolean n = r.nextBoolean(); if (n == true) { return "John"; } else { return null; } } ``` 在`getName()`方法中,我們模擬了一種方法有時可以返回`null`值的情況。 ```java System.out.println(null == null); ``` 我們比較兩個空值。 表達式返回`true`。 ```java if ("John".equals(name)) { System.out.println("His name is John"); } ``` 我們將名稱變量與`"John"`字符串進行比較。 注意,我們在`"John"`字符串上調用了`equals()`方法。 這是因為如果名稱變量等于`null`,則調用該方法將導致`NullPointerException`。 ```java $ java NullType.java null true $ java NullType.java null true $ java NullType.java John true His name is John ``` 我們執行該程序三次。 ## Java 默認值 編譯器會為未初始化的字段提供默認值。 最終字段和局部變量必須由開發者初始化。 下表顯示了不同類型的默認值。 | 數據類型 | 默認值 | | --- | --- | | `byte` | `0` | | `char` | `'\u0000'` | | `short` | `0` | | `int` | `0` | | `long` | `0L` | | `float` | `0f` | | `double` | `0d` | | `Object` | `null` | | `boolean` | `false` | Table: Default values for uninitialized instance variables 下一個示例將打印未初始化的實例變量的默認值。 實例變量是在類中定義的變量,該類的每個實例化對象都具有一個單獨的副本。 `com/zetcode/DefaultValues.java` ```java package com.zetcode; public class DefaultValues { static byte b; static char c; static short s; static int i; static float f; static double d; static String str; static Object o; public static void main(String[] args) { System.out.println(b); System.out.println(c); System.out.println(s); System.out.println(i); System.out.println(f); System.out.println(d); System.out.println(str); System.out.println(o); } } ``` 在示例中,我們聲明了八個成員字段。 它們未初始化。 編譯器將為每個字段設置默認值。 ```java static byte b; static char c; static short s; static int i; ... ``` 這些是實例變量; 它們在任何方法外聲明。 這些字段被聲明為`static`,因為它們是通過`static` `main()`方法訪問的。 (在本教程的后面,我們將更多地討論靜態變量和實例變量。) ```java $ java DefaultValues.java 0 0 0 0.0 0.0 null null ``` This is the output of the program. ## Java 類型轉換 我們經常一次處理多種數據類型。 將一種數據類型轉換為另一種數據類型是編程中的常見工作。 術語類型轉換是指將一種數據類型的實體更改為另一種。 在本節中,我們將處理原始數據類型的轉換。 引用類型的轉換將在本章后面提到。 轉換規則很復雜; 它們在 Java 語言規范的第 5 章中指定。 轉換有兩種類型:隱式轉換和顯式轉換。 隱式類型轉換,也稱為強制,是編譯器自動進行的類型轉換。 在顯式轉換中,程序員直接在一對圓括號內指定轉換類型。 顯式轉換稱為類型轉換。 轉換發生在不同的上下文中:賦值,表達式或方法調用。 ```java int x = 456; long y = 34523L; float z = 3.455f; double w = 6354.3425d; ``` 在這四個分配中,沒有轉換發生。 每個變量都被分配了預期類型的??字面值。 ```java int x = 345; long y = x; float m = 22.3354f; double n = m; ``` 在此代碼中,Java 編譯器隱式執行了兩次轉換。 將較小類型的變量分配給較大類型的變量是合法的。 該轉換被認為是安全的,因為不會損失任何精度。 這種轉換稱為隱式加寬轉換。 ```java long x = 345; int y = (int) x; double m = 22.3354d; float n = (float) m; ``` 在 Java 中,將較大類型的變量分配給較小類型是不合法的。 即使值本身適合較小類型的范圍。 在這種情況下,可能會降低精度。 為了允許這種分配,我們必須使用類型轉換操作。 這樣,程序員說他是故意這樣做的,并且他意識到可能會丟失一些精度這一事實。 這種轉換稱為顯式變窄轉換。 ```java byte a = 123; short b = 23532; ``` 在這種情況下,我們處理一種特定類型的分配轉換。 123 和 23532 是整數字面值,`a`,`b`變量為`byte`和`short`類型。 可以使用鑄造操作,但不是必需的。 字面值可以在賦值左側的變量中表示。 我們處理隱式變窄轉換。 ```java private static byte calc(byte x) { ... } byte b = calc((byte) 5); ``` 以上規則僅適用于分配。 當我們將整數字面值傳遞給需要一個字節的方法時,我們必須執行強制轉換操作。 ## Java 數字提升 數值提升是隱式類型轉換的特定類型。 它發生在算術表達式中。 數字提升用于將數字運算符的操作數轉換為通用類型,以便可以執行操作。 ```java int x = 3; double y = 2.5; double z = x + y; ``` 第三行中有一個加法表達式。 `x`操作數為`int`,`y`操作數為`double`。 編譯器將整數轉換為雙精度值,然后將兩個數字相加。 結果是兩倍。 這是隱式擴展原始類型轉換的情況。 ```java byte a = 120; a = a + 1; // compilation error ``` 此代碼導致編譯時錯誤。 在第二行的右側,我們有一個字節變量`a`和一個整數字面值 1。該變量將轉換為整數并添加值。 結果是一個整數。 以后,編譯器嘗試將值分配給`a`變量。 沒有顯式的強制轉換運算符,就不可能將較大的類型分配給較小的類型。 因此,我們收到一個編譯時錯誤。 ```java byte a = 120; a = (byte) (a + 1); ``` 此代碼可以編譯。 請注意`a + 1`表達式中使用圓括號。 `(byte)`強制轉換運算符的優先級高于加法運算符。 如果要對整個表達式應用轉換,則必須使用圓括號。 ```java byte a = 120; a += 5; ``` 復合運算符自動執行隱式轉換。 ```java short r = 21; short s = (short) -r; ``` 將`+`或`-`一元運算符應用于變量,即可執行一元數提升。 `short`類型升級為`int`類型。 因此,必須使用強制轉換運算符來使分配通過。 ```java byte u = 100; byte v = u++; ``` 如果是一元遞增`++`或遞減`--`運算符,則不會進行任何轉換。 不需要鑄造。 ## Java 裝箱,拆箱轉換 裝箱轉換將原始類型的表達式轉換為包裝器類型的對應表達式。 拆箱轉換將包裝器類型的表達式轉換為原始類型的相應表達式。 從`boolean`到`Boolean`或從字節到`Byte`的轉換是裝箱轉換的示例。 反向轉換,例如從`Boolean`到`boolean`或從`Byte`到`byte`的翻譯是取消裝箱轉換的示例。 ```java Byte b = 124; byte c = b; ``` 在第一行代碼中,自動裝箱轉換由 Java 編譯器執行。 在第二行中,完成了拆箱轉換。 ```java private static String checkAge(Short age) { ... } String r = checkAge((short) 5); ``` 在這里,我們在方法調用的上下文中進行裝箱轉換。 我們將`short`類型傳遞給需要`Short`包裝類型的方法。 該值已裝箱。 ```java Boolean gameOver = new Boolean("true"); if (gameOver) { System.out.println("The game is over"); } ``` 這是拆箱轉換的示例。 在`if`表達式內部,調用`booleanValue()`方法。 該方法返回`Boolean`對象的值作為`boolean`原語。 ## 對象引用轉換 對象,接口和數組是引用數據類型。 任何引用都可以轉換為`Object`。 對象類型確定在運行時使用哪種方法。 引用類型確定在編譯時將使用哪種重載方法。 接口類型只能轉換為接口類型或`Object`。 如果新類型是接口,則它必須是舊類型的超級接口。 可以將類類型轉換為類類型或接口類型。 如果要轉換為類類型,則新類型必須是舊類型的超類。 如果要轉換為接口類型,則舊類必須實現該接口。 數組可以轉換為類`Object`,接口`Cloneable`或`Serializable`或數組。 引用變量轉換有兩種類型:下播和上播。 正在向上轉換(泛型或擴展)正在從子類型轉換為父類型。 我們正在將單個類型轉換為通用類型。 向下轉換(專業化或縮小)正在從父類型轉換為子類型。 我們正在將通用類型轉換為單個類型。 向上轉換縮小了對象可用的方法和屬性的列表,向下轉換可以擴展它。 向上轉換是安全的,但是向下轉換涉及類型檢查,并且可能拋出`ClassCastException`。 `com/zetcode/ReferenceTypeConverion.java` ```java package com.zetcode; import java.util.Random; class Animal {} class Mammal extends Animal {} class Dog extends Animal {} class Cat extends Animal {} public class ReferenceTypeConversion { public static void main(String[] args) { // upcasting Animal animal = new Dog(); System.out.println(animal); // ClassCastException // Mammal mammal = (Mammal) new Animal(); var returned = getRandomAnimal(); if (returned instanceof Cat) { Cat cat = (Cat) returned; System.out.println(cat); } else if (returned instanceof Dog) { Dog dog = (Dog) returned; System.out.println(dog); } else if (returned instanceof Mammal) { Mammal mammal = (Mammal) returned; System.out.println(mammal); } else { Animal animal2 = returned; System.out.println(animal2); } } private static Animal getRandomAnimal() { int val = new Random().nextInt(4) + 1; Animal anim = switch (val) { case 2 -> new Mammal(); case 3 -> new Dog(); case 4 -> new Cat(); default -> new Animal(); }; return anim; } } ``` 該示例執行引用類型轉換。 ```java // upcasting Animal animal = new Dog(); System.out.println(animal); ``` 我們從子類型`Dog`轉換為父類型`Animal`。 這是不安全的,并且始終是安全的。 ```java // ClassCastException // Mammal mammal = (Mammal) new Animal(); ``` 從`Animal`向下廣播到`Mammal`會導致`ClassCastException`。 ```java var returned = getRandomAnimal(); if (returned instanceof Cat) { Cat cat = (Cat) returned; System.out.println(cat); } else if (returned instanceof Dog) { Dog dog = (Dog) returned; System.out.println(dog); } else if (returned instanceof Mammal) { Mammal mammal = (Mammal) returned; System.out.println(mammal); } else { Animal animal2 = returned; System.out.println(animal2); } ``` 為了執行合法的向下轉換,我們需要首先使用`instanceof`運算符檢查對象的類型。 ```java private static Animal getRandomAnimal() { int val = new Random().nextInt(4) + 1; Animal anim = switch (val) { case 2 -> new Mammal(); case 3 -> new Dog(); case 4 -> new Cat(); default -> new Animal(); }; return anim; } ``` `getRandomAnimal()`使用 Java 的`switch`表達式返回隨機動物。 ## Java 字符串轉換 在數字和字符串之間執行字符串轉換在編程中非常常見。 不允許進行強制轉換操作,因為字符串和基本類型在根本上是不同的類型。 有幾種執行字符串轉換的方法。 `+`運算符還具有自動字符串轉換功能。 本教程的“字符串”一章將介紹有關字符串轉換的更多信息。 ```java String s = (String) 15; // compilation error int i = (int) "25"; // compilation error ``` 不能在數字和字符串之間進行強制轉換。 相反,我們有各種方法可以在數字和字符串之間進行轉換。 ```java short age = Short.parseShort("35"); int salary = Integer.parseInt("2400"); float height = Float.parseFloat("172.34"); double weight = Double.parseDouble("55.6"); ``` 包裝類的`parse`方法將字符串轉換為原始類型。 ```java Short age = Short.valueOf("35"); Integer salary = Integer.valueOf("2400"); Float height = Float.valueOf("172.34"); Double weight = Double.valueOf("55.6"); ``` `valueOf()`方法從原始類型返回包裝器類。 ```java int age = 17; double weight = 55.3; String v1 = String.valueOf(age); String v2 = String.valueOf(weight); ``` `String`類具有用于將各種類型轉換為字符串的`valueOf()`方法。 當使用`+`運算符并且一個運算符是一個字符串,另一個運算符不是一個字符串時,會自動進行字符串轉換。 `+`的非字符串操作數將轉換為字符串。 `com/zetcode/AutomaticStringConversion.java` ```java package com.zetcode; public class AutomaticStringConversion { public static void main(String[] args) { String name = "Jane"; short age = 17; System.out.println(name + " is " + age + " years old.\n"); } } ``` 在示例中,我們有`String`數據類型和`short`數據類型。 使用`+`運算符將這兩種類型連接成一個句子。 ```java System.out.println(name + " is " + age + " years old."); ``` 在表達式中,`age`變量被轉換為`String`類型。 ```java $ java AutomaticStringConversion.java Jane is 17 years old. ``` 這是示例輸出。 在 Java 教程的這一部分中,我們介紹了包裝器類,裝箱和拆箱,默認值,轉換和促銷。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看