亚洲免费在线-亚洲免费在线播放-亚洲免费在线观看-亚洲免费在线观看视频-亚洲免费在线看-亚洲免费在线视频

JAVA面試題解惑系列(二)——到底創(chuàng)建了幾個(gè)St

系統(tǒng) 1917 0

好東西分享

我們首先來(lái)看一段代碼:

Java代碼 復(fù)制代碼
  1. String?str= new ?String( "abc" );??
    String str=new String("abc");

  


緊接著這段代碼之后的往往是這個(gè)問(wèn)題,那就是這行代碼究竟創(chuàng)建了幾個(gè)String對(duì)象呢?相信大家對(duì)這道題并不陌生,答案也是眾所周知的,2個(gè)。接下來(lái)我們就從這道題展開(kāi),一起回顧一下與創(chuàng)建String對(duì)象相關(guān)的一些JAVA知識(shí)。

我們可以把上面這行代碼分成String str、=、"abc"和new String()四部分來(lái)看待。String str只是定義了一個(gè)名為str的String類(lèi)型的變量,因此它并沒(méi)有創(chuàng)建對(duì)象;=是對(duì)變量str進(jìn)行初始化,將某個(gè)對(duì)象的引用(或者叫句柄)賦值給它,顯然也沒(méi)有創(chuàng)建對(duì)象;現(xiàn)在只剩下new String("abc")了。那么,new String("abc")為什么又能被看成"abc"和new String()呢?我們來(lái)看一下被我們調(diào)用了的String的構(gòu)造器:

Java代碼 復(fù)制代碼
  1. public ?String(String?original)?{ ??
  2. ???? //other?code?... ??
  3. }??
    public String(String original) {
	//other code ...
}

  


大家都知道,我們常用的創(chuàng)建一個(gè)類(lèi)的實(shí)例(對(duì)象)的方法有以下兩種:

  1. 使用new創(chuàng)建對(duì)象。
  2. 調(diào)用Class類(lèi)的newInstance方法,利用反射機(jī)制創(chuàng)建對(duì)象。


我們正是使用new調(diào)用了String類(lèi)的上面那個(gè)構(gòu)造器方法創(chuàng)建了一個(gè)對(duì)象,并將它的引用賦值給了str變量。同時(shí)我們注意到,被調(diào)用的構(gòu)造器方法接受的參數(shù)也是一個(gè)String對(duì)象,這個(gè)對(duì)象正是"abc"。由此我們又要引入另外一種創(chuàng)建String對(duì)象的方式的討論——引號(hào)內(nèi)包含文本。

這種方式是String特有的,并且它與new的方式存在很大區(qū)別。

Java代碼 復(fù)制代碼
  1. String?str= "abc" ;??
    String str="abc";

  


毫無(wú)疑問(wèn),這行代碼創(chuàng)建了一個(gè)String對(duì)象。

Java代碼 復(fù)制代碼
  1. String?a= "abc" ; ??
  2. String?b= "abc" ;??
    String a="abc";
String b="abc";

  


那這里呢?答案還是一個(gè)。

Java代碼 復(fù)制代碼
  1. String?a= "ab" + "cd" ;??
    String a="ab"+"cd";

  


再看看這里呢?答案仍是一個(gè)。有點(diǎn)奇怪嗎?說(shuō)到這里,我們就需要引入對(duì)字符串池相關(guān)知識(shí)的回顧了。

在JAVA虛擬機(jī)(JVM)中存在著一個(gè)字符串池,其中保存著很多String對(duì)象,并且可以被共享使用,因此它提高了效率。由于String類(lèi)是final的,它的值一經(jīng)創(chuàng)建就不可改變,因此我們不用擔(dān)心String對(duì)象共享而帶來(lái)程序的混亂。字符串池由String類(lèi)維護(hù),我們可以調(diào)用intern()方法來(lái)訪問(wèn)字符串池。

我們?cè)倩仡^看看String a="abc";,這行代碼被執(zhí)行的時(shí)候,JAVA虛擬機(jī)首先在字符串池中查找是否已經(jīng)存在了值為"abc"的這么一個(gè)對(duì)象,它的判斷依據(jù)是String類(lèi)equals(Object obj)方法的返回值。如果有,則不再創(chuàng)建新的對(duì)象,直接返回已存在對(duì)象的引用;如果沒(méi)有,則先創(chuàng)建這個(gè)對(duì)象,然后把它加入到字符串池中,再將它的引用返回。因此,我們不難理解前面三個(gè)例子中頭兩個(gè)例子為什么是這個(gè)答案了。

對(duì)于第三個(gè)例子:

Java代碼 復(fù)制代碼
  1. String?a= "ab" + "cd" ;??
    String a="ab"+"cd";

  


由于常量的值在編譯的時(shí)候就被確定了。在這里,"ab"和"cd"都是常量,因此變量a的值在編譯時(shí)就可以確定。這行代碼編譯后的效果等同于:

Java代碼 復(fù)制代碼
  1. String?a= "abcd" ;??
    String a="abcd";

  


因此這里只創(chuàng)建了一個(gè)對(duì)象"abcd",并且它被保存在字符串池里了。

現(xiàn)在問(wèn)題又來(lái)了,是不是所有經(jīng)過(guò)“+”連接后得到的字符串都會(huì)被添加到字符串池中呢?我們都知道“==”可以用來(lái)比較兩個(gè)變量,它有以下兩種情況:

  1. 如果比較的是兩個(gè)基本類(lèi)型(char,byte,short,int,long,float,double,boolean),則是判斷它們的值是否相等。
  2. 如果表較的是兩個(gè)對(duì)象變量,則是判斷它們的引用是否指向同一個(gè)對(duì)象。


下面我們就用“==”來(lái)做幾個(gè)測(cè)試。為了便于說(shuō)明,我們把指向字符串池中已經(jīng)存在的對(duì)象也視為該對(duì)象被加入了字符串池:

Java代碼 復(fù)制代碼
  1. public ? class ?StringTest?{ ??
  2. ???? public ? static ? void ?main(String[]?args)?{ ??
  3. ????????String?a?=? "ab" ; //?創(chuàng)建了一個(gè)對(duì)象,并加入字符串池中 ??
  4. ????????System.out.println( "String?a?=?\"ab\";" ); ??
  5. ????????String?b?=? "cd" ; //?創(chuàng)建了一個(gè)對(duì)象,并加入字符串池中 ??
  6. ????????System.out.println( "String?b?=?\"cd\";" ); ??
  7. ????????String?c?=? "abcd" ; //?創(chuàng)建了一個(gè)對(duì)象,并加入字符串池中 ??
  8. ??
  9. ????????String?d?=? "ab" ?+? "cd" ; ??
  10. ???????? //?如果d和c指向了同一個(gè)對(duì)象,則說(shuō)明d也被加入了字符串池 ??
  11. ???????? if ?(d?==?c)?{ ??
  12. ????????????System.out.println( "\"ab\"+\"cd\"?創(chuàng)建的對(duì)象?\"加入了\"?字符串池中" ); ??
  13. ????????} ??
  14. ???????? //?如果d和c沒(méi)有指向了同一個(gè)對(duì)象,則說(shuō)明d沒(méi)有被加入字符串池 ??
  15. ???????? else ?{ ??
  16. ????????????System.out.println( "\"ab\"+\"cd\"?創(chuàng)建的對(duì)象?\"沒(méi)加入\"?字符串池中" ); ??
  17. ????????} ??
  18. ??
  19. ????????String?e?=?a?+? "cd" ; ??
  20. ???????? //?如果e和c指向了同一個(gè)對(duì)象,則說(shuō)明e也被加入了字符串池 ??
  21. ???????? if ?(e?==?c)?{ ??
  22. ????????????System.out.println( "?a??+\"cd\"?創(chuàng)建的對(duì)象?\"加入了\"?字符串池中" ); ??
  23. ????????} ??
  24. ???????? //?如果e和c沒(méi)有指向了同一個(gè)對(duì)象,則說(shuō)明e沒(méi)有被加入字符串池 ??
  25. ???????? else ?{ ??
  26. ????????????System.out.println( "?a??+\"cd\"?創(chuàng)建的對(duì)象?\"沒(méi)加入\"?字符串池中" ); ??
  27. ????????} ??
  28. ??
  29. ????????String?f?=? "ab" ?+?b; ??
  30. ???????? //?如果f和c指向了同一個(gè)對(duì)象,則說(shuō)明f也被加入了字符串池 ??
  31. ???????? if ?(f?==?c)?{ ??
  32. ????????????System.out.println( "\"ab\"+?b???創(chuàng)建的對(duì)象?\"加入了\"?字符串池中" ); ??
  33. ????????} ??
  34. ???????? //?如果f和c沒(méi)有指向了同一個(gè)對(duì)象,則說(shuō)明f沒(méi)有被加入字符串池 ??
  35. ???????? else ?{ ??
  36. ????????????System.out.println( "\"ab\"+?b???創(chuàng)建的對(duì)象?\"沒(méi)加入\"?字符串池中" ); ??
  37. ????????} ??
  38. ??
  39. ????????String?g?=?a?+?b; ??
  40. ???????? //?如果g和c指向了同一個(gè)對(duì)象,則說(shuō)明g也被加入了字符串池 ??
  41. ???????? if ?(g?==?c)?{ ??
  42. ????????????System.out.println( "?a??+?b???創(chuàng)建的對(duì)象?\"加入了\"?字符串池中" ); ??
  43. ????????} ??
  44. ???????? //?如果g和c沒(méi)有指向了同一個(gè)對(duì)象,則說(shuō)明g沒(méi)有被加入字符串池 ??
  45. ???????? else ?{ ??
  46. ????????????System.out.println( "?a??+?b???創(chuàng)建的對(duì)象?\"沒(méi)加入\"?字符串池中" ); ??
  47. ????????} ??
  48. ????} ??
  49. }??
    public class StringTest {
	public static void main(String[] args) {
		String a = "ab";// 創(chuàng)建了一個(gè)對(duì)象,并加入字符串池中
		System.out.println("String a = \"ab\";");
		String b = "cd";// 創(chuàng)建了一個(gè)對(duì)象,并加入字符串池中
		System.out.println("String b = \"cd\";");
		String c = "abcd";// 創(chuàng)建了一個(gè)對(duì)象,并加入字符串池中

		String d = "ab" + "cd";
		// 如果d和c指向了同一個(gè)對(duì)象,則說(shuō)明d也被加入了字符串池
		if (d == c) {
			System.out.println("\"ab\"+\"cd\" 創(chuàng)建的對(duì)象 \"加入了\" 字符串池中");
		}
		// 如果d和c沒(méi)有指向了同一個(gè)對(duì)象,則說(shuō)明d沒(méi)有被加入字符串池
		else {
			System.out.println("\"ab\"+\"cd\" 創(chuàng)建的對(duì)象 \"沒(méi)加入\" 字符串池中");
		}

		String e = a + "cd";
		// 如果e和c指向了同一個(gè)對(duì)象,則說(shuō)明e也被加入了字符串池
		if (e == c) {
			System.out.println(" a  +\"cd\" 創(chuàng)建的對(duì)象 \"加入了\" 字符串池中");
		}
		// 如果e和c沒(méi)有指向了同一個(gè)對(duì)象,則說(shuō)明e沒(méi)有被加入字符串池
		else {
			System.out.println(" a  +\"cd\" 創(chuàng)建的對(duì)象 \"沒(méi)加入\" 字符串池中");
		}

		String f = "ab" + b;
		// 如果f和c指向了同一個(gè)對(duì)象,則說(shuō)明f也被加入了字符串池
		if (f == c) {
			System.out.println("\"ab\"+ b   創(chuàng)建的對(duì)象 \"加入了\" 字符串池中");
		}
		// 如果f和c沒(méi)有指向了同一個(gè)對(duì)象,則說(shuō)明f沒(méi)有被加入字符串池
		else {
			System.out.println("\"ab\"+ b   創(chuàng)建的對(duì)象 \"沒(méi)加入\" 字符串池中");
		}

		String g = a + b;
		// 如果g和c指向了同一個(gè)對(duì)象,則說(shuō)明g也被加入了字符串池
		if (g == c) {
			System.out.println(" a  + b   創(chuàng)建的對(duì)象 \"加入了\" 字符串池中");
		}
		// 如果g和c沒(méi)有指向了同一個(gè)對(duì)象,則說(shuō)明g沒(méi)有被加入字符串池
		else {
			System.out.println(" a  + b   創(chuàng)建的對(duì)象 \"沒(méi)加入\" 字符串池中");
		}
	}
}


  


運(yùn)行結(jié)果如下:

  1. String a = "ab";
  2. String b = "cd";
  3. "ab"+"cd" 創(chuàng)建的對(duì)象 "加入了" 字符串池中
  4. a? +"cd" 創(chuàng)建的對(duì)象 "沒(méi)加入" 字符串池中
  5. "ab"+ b?? 創(chuàng)建的對(duì)象 "沒(méi)加入" 字符串池中
  6. a? + b?? 創(chuàng)建的對(duì)象 "沒(méi)加入" 字符串池中


從上面的結(jié)果中我們不難看出,只有使用引號(hào)包含文本的方式創(chuàng)建的String對(duì)象之間使用“+”連接產(chǎn)生的新對(duì)象才會(huì)被加入字符串池中。對(duì)于所有包含new方式新建對(duì)象(包括null)的“+”連接表達(dá)式,它所產(chǎn)生的新對(duì)象都不會(huì)被加入字符串池中,對(duì)此我們不再贅述。

但是有一種情況需要引起我們的注意。請(qǐng)看下面的代碼:

Java代碼 復(fù)制代碼
  1. public ? class ?StringStaticTest?{ ??
  2. ???? //?常量A ??
  3. ???? public ? static ? final ?String?A?=? "ab" ; ??
  4. ??
  5. ???? //?常量B ??
  6. ???? public ? static ? final ?String?B?=? "cd" ; ??
  7. ??
  8. ???? public ? static ? void ?main(String[]?args)?{ ??
  9. ???????? //?將兩個(gè)常量用+連接對(duì)s進(jìn)行初始化 ??
  10. ????????String?s?=?A?+?B; ??
  11. ????????String?t?=? "abcd" ; ??
  12. ???????? if ?(s?==?t)?{ ??
  13. ????????????System.out.println( "s等于t,它們是同一個(gè)對(duì)象" ); ??
  14. ????????}? else ?{ ??
  15. ????????????System.out.println( "s不等于t,它們不是同一個(gè)對(duì)象" ); ??
  16. ????????} ??
  17. ????} ??
  18. }??
    public class StringStaticTest {
	// 常量A
	public static final String A = "ab";

	// 常量B
	public static final String B = "cd";

	public static void main(String[] args) {
		// 將兩個(gè)常量用+連接對(duì)s進(jìn)行初始化
		String s = A + B;
		String t = "abcd";
		if (s == t) {
			System.out.println("s等于t,它們是同一個(gè)對(duì)象");
		} else {
			System.out.println("s不等于t,它們不是同一個(gè)對(duì)象");
		}
	}
}

  


這段代碼的運(yùn)行結(jié)果如下:

  • s等于t,它們是同一個(gè)對(duì)象


這又是為什么呢?原因是這樣的,對(duì)于常量來(lái)講,它的值是固定的,因此在編譯期就能被確定了,而變量的值只有到運(yùn)行時(shí)才能被確定,因?yàn)檫@個(gè)變量可以被不同的方法調(diào)用,從而可能引起值的改變。在上面的例子中,A和B都是常量,值是固定的,因此s的值也是固定的,它在類(lèi)被編譯時(shí)就已經(jīng)確定了。也就是說(shuō):

Java代碼 復(fù)制代碼
  1. String?s=A+B;??
    String s=A+B;

  


等同于:

Java代碼 復(fù)制代碼
  1. String?s= "ab" + "cd" ;??
    String s="ab"+"cd";

  


我對(duì)上面的例子稍加改變看看會(huì)出現(xiàn)什么情況:

Java代碼 復(fù)制代碼
  1. public ? class ?StringStaticTest?{ ??
  2. ???? //?常量A ??
  3. ???? public ? static ? final ?String?A; ??
  4. ??
  5. ???? //?常量B ??
  6. ???? public ? static ? final ?String?B; ??
  7. ??
  8. ???? static ?{ ??
  9. ????????A?=? "ab" ; ??
  10. ????????B?=? "cd" ; ??
  11. ????} ??
  12. ??
  13. ???? public ? static ? void ?main(String[]?args)?{ ??
  14. ???????? //?將兩個(gè)常量用+連接對(duì)s進(jìn)行初始化 ??
  15. ????????String?s?=?A?+?B; ??
  16. ????????String?t?=? "abcd" ; ??
  17. ???????? if ?(s?==?t)?{ ??
  18. ????????????System.out.println( "s等于t,它們是同一個(gè)對(duì)象" ); ??
  19. ????????}? else ?{ ??
  20. ????????????System.out.println( "s不等于t,它們不是同一個(gè)對(duì)象" ); ??
  21. ????????} ??
  22. ????} ??
  23. }??
    public class StringStaticTest {
	// 常量A
	public static final String A;

	// 常量B
	public static final String B;

	static {
		A = "ab";
		B = "cd";
	}

	public static void main(String[] args) {
		// 將兩個(gè)常量用+連接對(duì)s進(jìn)行初始化
		String s = A + B;
		String t = "abcd";
		if (s == t) {
			System.out.println("s等于t,它們是同一個(gè)對(duì)象");
		} else {
			System.out.println("s不等于t,它們不是同一個(gè)對(duì)象");
		}
	}
}

  


它的運(yùn)行結(jié)果是這樣:

  • s不等于t,它們不是同一個(gè)對(duì)象


只是做了一點(diǎn)改動(dòng),結(jié)果就和剛剛的例子恰好相反。我們?cè)賮?lái)分析一下。A和B雖然被定義為常量(只能被賦值一次),但是它們都沒(méi)有馬上被賦值。在運(yùn)算出s的值之前,他們何時(shí)被賦值,以及被賦予什么樣的值,都是個(gè)變數(shù)。因此A和B在被賦值之前,性質(zhì)類(lèi)似于一個(gè)變量。那么s就不能在編譯期被確定,而只能在運(yùn)行時(shí)被創(chuàng)建了。

由于字符串池中對(duì)象的共享能夠帶來(lái)效率的提高,因此我們提倡大家用引號(hào)包含文本的方式來(lái)創(chuàng)建String對(duì)象,實(shí)際上這也是我們?cè)诰幊讨谐2捎玫摹?

接下來(lái)我們?cè)賮?lái)看看intern()方法,它的定義如下:

Java代碼 復(fù)制代碼
  1. public ? native ?String?intern();??
    public native String intern();

  


這是一個(gè)本地方法。在調(diào)用這個(gè)方法時(shí),JAVA虛擬機(jī)首先檢查字符串池中是否已經(jīng)存在與該對(duì)象值相等對(duì)象存在,如果有則返回字符串池中對(duì)象的引用;如果沒(méi)有,則先在字符串池中創(chuàng)建一個(gè)相同值的String對(duì)象,然后再將它的引用返回。

我們來(lái)看這段代碼:

Java代碼 復(fù)制代碼
  1. public ? class ?StringInternTest?{ ??
  2. ???? public ? static ? void ?main(String[]?args)?{ ??
  3. ???????? //?使用char數(shù)組來(lái)初始化a,避免在a被創(chuàng)建之前字符串池中已經(jīng)存在了值為"abcd"的對(duì)象 ??
  4. ????????String?a?=? new ?String( new ? char []?{? 'a' ,? 'b' ,? 'c' ,? 'd' ?}); ??
  5. ????????String?b?=?a.intern(); ??
  6. ???????? if ?(b?==?a)?{ ??
  7. ????????????System.out.println( "b被加入了字符串池中,沒(méi)有新建對(duì)象" ); ??
  8. ????????}? else ?{ ??
  9. ????????????System.out.println( "b沒(méi)被加入字符串池中,新建了對(duì)象" ); ??
  10. ????????} ??
  11. ????} ??
  12. }??
    public class StringInternTest {
	public static void main(String[] args) {
		// 使用char數(shù)組來(lái)初始化a,避免在a被創(chuàng)建之前字符串池中已經(jīng)存在了值為"abcd"的對(duì)象
		String a = new String(new char[] { 'a', 'b', 'c', 'd' });
		String b = a.intern();
		if (b == a) {
			System.out.println("b被加入了字符串池中,沒(méi)有新建對(duì)象");
		} else {
			System.out.println("b沒(méi)被加入字符串池中,新建了對(duì)象");
		}
	}
}

  


運(yùn)行結(jié)果:

  1. b沒(méi)被加入字符串池中,新建了對(duì)象


如果String類(lèi)的intern()方法在沒(méi)有找到相同值的對(duì)象時(shí),是把當(dāng)前對(duì)象加入字符串池中,然后返回它的引用的話,那么b和a指向的就是同一個(gè)對(duì)象;否則b指向的對(duì)象就是JAVA虛擬機(jī)在字符串池中新建的,只是它的值與a相同罷了。上面這段代碼的運(yùn)行結(jié)果恰恰印證了這一點(diǎn)。

最后我們?cè)賮?lái)說(shuō)說(shuō)String對(duì)象在JAVA虛擬機(jī)(JVM)中的存儲(chǔ),以及字符串池與堆(heap)和棧(stack)的關(guān)系。我們首先回顧一下堆和棧的區(qū)別:

  • 棧(stack):主要保存基本類(lèi)型(或者叫內(nèi)置類(lèi)型)(char、byte、short、int、long、float、double、boolean)和對(duì)象的引用,數(shù)據(jù)可以共享,速度僅次于寄存器(register),快于堆。
  • 堆(heap):用于存儲(chǔ)對(duì)象。


我們查看String類(lèi)的源碼就會(huì)發(fā)現(xiàn),它有一個(gè)value屬性,保存著String對(duì)象的值,類(lèi)型是char[],這也正說(shuō)明了字符串就是字符的序列。

當(dāng)執(zhí)行String a="abc";時(shí),JAVA虛擬機(jī)會(huì)在棧中創(chuàng)建三個(gè)char型的值'a'、'b'和'c',然后在堆中創(chuàng)建一個(gè)String對(duì)象,它的值(value)是剛才在棧中創(chuàng)建的三個(gè)char型值組成的數(shù)組{'a','b','c'},最后這個(gè)新創(chuàng)建的String對(duì)象會(huì)被添加到字符串池中。如果我們接著執(zhí)行String b=new String("abc");代碼,由于"abc"已經(jīng)被創(chuàng)建并保存于字符串池中,因此JAVA虛擬機(jī)只會(huì)在堆中新創(chuàng)建一個(gè)String對(duì)象,但是它的值(value)是共享前一行代碼執(zhí)行時(shí)在棧中創(chuàng)建的三個(gè)char型值值'a'、'b'和'c'。

說(shuō)到這里,我們對(duì)于篇首提出的String str=new String("abc")為什么是創(chuàng)建了兩個(gè)對(duì)象這個(gè)問(wèn)題就已經(jīng)相當(dāng)明了了。

?

向原作者致敬,轉(zhuǎn)自:

作者:臧圩人(zangweiren)
網(wǎng)址: http://zangweiren.iteye.com

JAVA面試題解惑系列(二)——到底創(chuàng)建了幾個(gè)String對(duì)象?


更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號(hào)聯(lián)系: 360901061

您的支持是博主寫(xiě)作最大的動(dòng)力,如果您喜歡我的文章,感覺(jué)我的文章對(duì)您有幫助,請(qǐng)用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長(zhǎng)非常感激您!手機(jī)微信長(zhǎng)按不能支付解決辦法:請(qǐng)將微信支付二維碼保存到相冊(cè),切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對(duì)您有幫助就好】

您的支持是博主寫(xiě)作最大的動(dòng)力,如果您喜歡我的文章,感覺(jué)我的文章對(duì)您有幫助,請(qǐng)用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長(zhǎng)會(huì)非常 感謝您的哦!!!

發(fā)表我的評(píng)論
最新評(píng)論 總共0條評(píng)論
主站蜘蛛池模板: 亚洲第一免费视频 | 亚洲精品中文字幕字幕 | 久久福利免费视频 | 99久热在线精品视频播放6 | 国产女人久久精品 | 日本四虎影视 | 欧美大黄大色一级毛片出红 | 亚洲国产成人资源在线桃色 | 欧美一区二区三区在观看 | 国产精品日本一区二区在线播放 | 国产香蕉久久精品综合网 | 亚洲五月综合缴情婷婷 | 成人免费aa在线观看 | 婷婷春色 | 噜噜嘿在线视频免费观看 | 日日爽夜夜 | 九九精品视频在线播放 | 免费福利在线播放 | 四虎影院国产精品 | 亚洲一区 在线播放 | 久久www免费人成_看片美女图 | 久操视频免费看 | 中日韩欧美一级毛片 | 国产国语高清在线视频二区 | 国产亚洲精品国产 | av大片 | 女人a级毛片 | 一区二区三区在线免费观看视频 | xxxxbbbb欧美| 久久色吧| 婷婷在线网站 | 久久精品爱 | 国产网站麻豆精品视频 | 午夜在线成人 | 中国大陆高清aⅴ毛片 | 神马九九 | 欧美最猛的24k毛片视频 | 国产精品分类视频分类一区 | 四虎影院在线免费观看视频 | 在线观看日韩精品 | 欧美精品亚洲精品日韩专区va |