日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 人文社科 > 生活经验 >内容正文

生活经验

Java泛型总结

發(fā)布時(shí)間:2023/11/27 生活经验 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Java泛型总结 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

0. 概述

泛型是Jdk1.5引入的特性。泛型是Java程序員最常用且最容易被忽視的知識(shí)之一。許多Java程序員只是使用泛型類。但不考慮其工作方式,直到出現(xiàn)問(wèn)題。

?

?

?

1 術(shù)語(yǔ)

用示例進(jìn)行描述。ArrayList<E>類、ArrayList<Integer>類:

  • 整個(gè)稱為ArrayList<E> 泛型類型
  • ArrayList<E>中的E稱為 類型變量 類型參數(shù)
  • 整個(gè)ArrayList<Integer> 稱為 參數(shù)化的類型
  • ArrayList<Integer>中的Integer稱為 類型參數(shù)的實(shí)例 或 實(shí)際類型參數(shù)
  • ArrayList<Integer>中的<>念著typeof。整個(gè)ArrayList<Integer>稱為"arraylist typof integer"。
  • ArrayList稱為原始類型。

?

?

?

2 泛型使用示例

由于經(jīng)常需要使用泛型。所以不再詳解泛型的實(shí)際使用。

此處示例一種遍歷Map的方式。

????????Map<String, Integer> hm = new HashMap<String, Integer>();

????????hm.put("zxx", 19);

????????hm.put("lis", 18);

?

????????Set<Map.Entry<String, Integer>> mes = hm.entrySet();

????????for (Map.Entry<String, Integer> me : mes) {

????????????System.out.println(me.getKey() + ":" + me.getValue());

????????}

?

附:對(duì)在jsp頁(yè)面中也經(jīng)常要對(duì)Set或Map集合進(jìn)行迭代。

<c:forEach items="${map}" var="entry">

????${entry.key}:${entry.value}

</c:forEach>

?

?

?

3 不使用泛型產(chǎn)生的困難

從集合中取出數(shù)據(jù)需要類型轉(zhuǎn)換。從集合中取出的數(shù)據(jù)需要造型,但由于集合中元素的類型沒(méi)有被限制,所以可能造成類型轉(zhuǎn)換錯(cuò)誤。

使用泛型可以不需要再使用強(qiáng)制類型轉(zhuǎn)換。且可以確保類型安全。

由于編譯生成的字節(jié)碼會(huì)去掉泛型的類型信息,只要能跳過(guò)編譯器,就可以往某個(gè)泛型集合中加入其它類型的數(shù)據(jù)。例,用反射得到集合,再調(diào)用其add方法即可。

?

?

?

4 Java泛型原理

Java中的泛型類型(或者泛型)類從表面上似于 C++ 中的模板,但兩者機(jī)制有本質(zhì)的不同。

Java的泛型方法沒(méi)有C++模板函數(shù)功能強(qiáng)大,Java中的如下代碼無(wú)法通過(guò)編譯:

<T> T add(T x,T y) {return (T) (x+y);}

Java中無(wú)論何時(shí)定義一個(gè)泛型類型,都自動(dòng)提供一個(gè)相應(yīng)的原始類型。原始類型的名字就是刪去類型參數(shù)后的泛型類型名。

Java 中的泛型基本上是在編譯器中實(shí)現(xiàn)。編譯器進(jìn)行執(zhí)行類型檢查和類型推斷,然后生成普通的非泛型的字節(jié)碼。編譯器使用泛型類型信息保證類型安全,然后在生成字節(jié)碼之前將其清除。這種實(shí)現(xiàn)技術(shù)稱為擦除(erasure)。

?所以泛型實(shí)際是提供給Javac編譯器使用的。限定輸入類型,讓編譯器擋住源程序中的非法輸入,編譯器編譯帶類型說(shuō)明的集合時(shí)會(huì)去除掉"類型"信息。程序運(yùn)行期間,沒(méi)有任何泛型泛型的痕跡。使程序運(yùn)行效率不受影響,對(duì)于參數(shù)化的泛型類型,getClass()方法的返回值和原始類型完全一樣。

例:通過(guò)以下代碼,可以看出運(yùn)行期泛型類型是被擦除的。

import java.util.ArrayList;

import java.util.List;

?

public class TestMain {

????public static void main(String[] args) {

?

????????List l = new ArrayList();

????????System.out.println(l.getClass());

????????

????????List<String> ls = new ArrayList<String>();

????????System.out.println(ls.getClass());

????????

????????List<Object> lo = new ArrayList<Object>();

????????System.out.println(lo.getClass());

????????

????????System.out.println(l.getClass().equals(ls.getClass())); //比較ArrayList與ArrayList<String>

????????System.out.println(l.getClass().equals(lo.getClass())); //比較ArrayList與List<Object>

????????System.out.println(lo.getClass().equals(ls.getClass())); //比較ArrayList<String>與List<Object>

????????

????}

}

輸出:

class java.util.ArrayList

class java.util.ArrayList

class java.util.ArrayList

true

true

true

?

?

例:使用反射機(jī)制繞過(guò)泛型的編譯器檢查。由于程序在運(yùn)行期間,不再帶有泛型約束,所以程序正確打印結(jié)果。

public class TestMain {

????public static void main(String[] args) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException {

????????List<Integer> ls = new ArrayList<Integer>();

????????//ls.add("abc"); //編譯器報(bào)錯(cuò)

????????ls.getClass().getMethod("add", Object.class).invoke(ls,"abc");

????????System.out.println(ls);

????}

}

輸出:

[abc]

?

?

?

5 正確使用泛型

5.1 參數(shù)化類型與原始類型的兼容性

參數(shù)化類型可以引用一個(gè)原始類型的對(duì)象。編譯器提示警告。

例,Collection<String> c = new ArrayList();

?

原始類型可以引用一個(gè)參數(shù)化類型的對(duì)象。編譯器提示警告。

例,Collection c = new ArrayList<String>();

?

參數(shù)化類型不考慮類型參數(shù)的繼承關(guān)系。

例:ArrayList<String> a = new ArrayList<Object>(); 編譯器提示錯(cuò)誤。

例:ArrayList<Object> a = new ArrayList<String>(); 編譯器提示錯(cuò)誤。

?

編譯器不允許創(chuàng)建泛型變量的數(shù)組。即在創(chuàng)建數(shù)組實(shí)例時(shí),數(shù)組的元素不能使用參數(shù)化的類型

例:ArrayList<Integer>[] a1 = new ArrayList<Integer>[10];

或 ArrayList<Integer> a2[] = new ArrayList<Integer>[10]; 編譯器提示錯(cuò)誤。

?

強(qiáng)調(diào),泛型只是在編譯期間編譯器做類型檢查的機(jī)制。

例:以下示例可以通過(guò)編譯。編譯器只是提示警告。

此處的a對(duì)象,本質(zhì)上變?yōu)锳rrayList<Object> 。

此處的a對(duì)象,本質(zhì)上變?yōu)锳rrayList<String> 。

?

?

5.2 Java泛型的約束和局限性

(1)不能使用基本類型實(shí)例化類型參數(shù)

不存在Pair<double>,只有Pair<Double>。由于類型擦除,Pair類含有Object類型的域,而Object不能存儲(chǔ)double。

但該缺陷,可以使用包裝類型解決。

重要結(jié)論:使用泛型或定義泛型類、泛型方法時(shí),泛型必須是引用類型,不能是基本類型。

?

(2)不能拋出也不能捕獲泛型類實(shí)例

泛型類不能繼承Throwable。

不能在catch子句中使用泛型類型變量。

?

(3)參數(shù)化類型的數(shù)組不合法

?

(4)不能實(shí)例化類型變量

若需要在方法中對(duì)泛型類型實(shí)例化,則需要傳入Class<T>

public static <T> void makePair(Class<T> cl) throws InstantiationException, IllegalAccessException{

T t = cl.newInstance();

}

?

(5)泛型類的靜態(tài)上下文中類型變量無(wú)效

不能在靜態(tài)域或方法中應(yīng)用類型變量。

?

(6)擦除后的沖突

以下代碼無(wú)法通過(guò)編譯

equals(T obj)equals(Object obj)沖突。擦除類型后,equals(T obj)就是equals(Object obj)

?

?

?

6 定義泛型類

泛型類是具有一個(gè)或多個(gè)類型變量的類。可以把泛型類看作是普通類的"工廠"。

自定義泛型使用尖括號(hào)<>聲明泛型參數(shù)。泛型類基本格式:

class CLS<T, U> {

????void method1(T param) {

????}

?

????T method2(T param) {

????????// return

????}

?

????U method3(T param1, U param2) {

????????// return ;

????}

}

?

一般Java中,使用變量E表示集合元素類型。K表示關(guān)鍵字,V表示值。T(或者U、S)表示"任意類型"。

當(dāng)一個(gè)變量被聲明為泛型時(shí),只能被實(shí)例變量、方法和內(nèi)部類調(diào)用,而不能被靜態(tài)變量和靜態(tài)方法調(diào)用。因?yàn)殪o態(tài)成員是被所有參數(shù)化的類所共享的,所以靜態(tài)成員不應(yīng)該有類級(jí)別的類型參數(shù)。若使用需要是靜態(tài)泛型方法,則重新聲明泛型參數(shù)。

?

例:定義泛型GenericDao 。

public class GenericDao<T> {

????public void save(T obj) {

????}

????public T getById(int id) {

????????return null;

????}

????/**

???? * 靜態(tài)方法。重新聲明T,此處的T與GenericDao<T>的T沒(méi)有關(guān)系。

???? */

????public static <T> void update(T obj){

????}

}

?

GenericDao引入類型變量T,用尖括號(hào)<> 括起來(lái),并放在類名后面。泛型類可以有多個(gè)類型變量,如:GenericDao<T,U>

?

在引用類名時(shí)指定的泛型類的泛型參數(shù)類型。

例,如下兩種方式都可以:

GenericDao<String> dao = null;

????new GenericDao<String>();

?

?

7 自定義泛型方法

用于放置泛型的類型參數(shù)的尖括號(hào)應(yīng)出現(xiàn)在方法的其他所有修飾符之后和在方法的返回類型之前,也就是緊鄰返回值之前。

按照慣例,類型參數(shù)通常用單個(gè)大寫字母表示。

普通方法、構(gòu)造方法和靜態(tài)方法中都可以使用泛型。

?

例:

原方法為:

????static int method(int x,int y){

????????return 0;

????}

????

泛型方法為:

????static <T> T method(T x,T y){

????????return null;

????}

<T>用于聲明一個(gè)泛型參數(shù)。

?

7.1 使用泛型化方法

當(dāng)調(diào)用一個(gè)泛型方法時(shí),在方法名前的尖括號(hào)中放入具體的類型。

例:使用調(diào)用TestMain類中的泛型化的靜態(tài)方法method。

String s = TestMain.<String>method("a","b");

必須有類名在最前面引出method方法,否則編譯器報(bào)錯(cuò)。

?

由于編譯器存在類型推斷機(jī)制,會(huì)自動(dòng)推斷出調(diào)用方法的泛型類型。所以使用泛型方法可以不需要指明泛型類型。

例:調(diào)用泛型化的method()方法。

?

例:交換數(shù)組中的兩個(gè)元素的位置的泛型方法語(yǔ)法定義如下:

????static <T> void swap(T[] a,int i,int j){

????????T tmp = a[i];

????????a[j]=a[i];

????????a[i]=tmp;

????}

使用swap方法:

?

說(shuō)明:

只有引用類型才能作為泛型方法的實(shí)際參數(shù)。swap(new int[]{1,2,3,4},1,3);編譯錯(cuò)誤。

?

在泛型中可以同時(shí)有多個(gè)類型參數(shù),在定義它們的尖括號(hào)中用逗號(hào)分。

例:

public static <K, V> V getValue(Map<K,V> map,K key) {

????????return map.get(key);

}

?

?

7.2 泛型方法例題

例:編寫一個(gè)泛型方法,自動(dòng)將Object類型的對(duì)象轉(zhuǎn)換成其他類型。

解:

public static <T> T autoConvert(Object obj){

????????return (T)obj;

????}

使用autoConvert方法。

????Object obj = "abc";

????String abc1 = (String)obj;

????String abc2 = autoConvert(obj);

?

例:定義一個(gè)方法,可以將任意類型的數(shù)組中的所有元素填充為相應(yīng)類型的某個(gè)對(duì)象。

????static <T> void fillArray(T[] a,T obj){

????????for(int i=0;i<a.length;i++){

????????????a[i]=obj;

????????}

????}

?

例:采用自定泛型方法的方式打印出任意參數(shù)化類型的集合中的所有內(nèi)容。

????static <T> void printCollection(Collection<T> collection){

????????for (Object obj : collection) {

????????????System.out.println(obj);

????????}

????}

說(shuō)明:該例使用之前的通配符方案要比范型方法更有效。

當(dāng)一個(gè)類型變量用來(lái)表達(dá)兩個(gè)參數(shù)之間或者參數(shù)和返回值之間的關(guān)系時(shí),即同一個(gè)類型變量在方法簽名的兩處被使用,或者類型變量在方法體代碼中也被使用而不是僅在簽名的時(shí)候使用,才需要使用范型方法。

?

?

例:定義一個(gè)方法,把任意參數(shù)類型的集合中的數(shù)據(jù)安全地復(fù)制到相應(yīng)類型的數(shù)組中。

static <T> void copy1(Collection<T> dest,T[] src){

????????// ...略

????}

????

????static <T> void copy2(T[] dest,T[] src){

????????// ...略

????}

?

使用copy1方法和copy2方法:

//copy1泛型方法的T的類型Object。因?yàn)锳rrayList與String父類的交集為Object。

copy1(new ArrayList(),new String[10]);

//copy2泛型方法的T的類型Object。因?yàn)镈ate與String父類的交集為Object。

copy2(new Date[10],new String[10]);

?

//new ArrayList<Date>()確定了T為Data,而new String[10]又指明T為String。

//由于類型推斷的傳播性,導(dǎo)致編譯器報(bào)錯(cuò)。

copy1(new ArrayList<Date>(),new String[10]);

?

?

8 泛型類型變量的限定

使用< T extends BoundingType >限定泛型類型。T應(yīng)該是綁定類型的子類型。T和綁定類型可以是類或接口。

例:<T extends Comparable & Serializable>

?

例:Class.getAnnotation()方法的定義。

public <A extends Annotation> A getAnnotation(Class<A> annotationClass)

<A extends Annotation> 表示聲明一個(gè)泛型參數(shù),該參數(shù)類型必須是Annotation類或其的子類。

?

例:通用泛型Dao。

public interface GenericDao<T extends Serializable,ID extends Serializable> {

}

?

public abstract class GenericDaoImpl<T extends Serializable ,ID extends Serializable> implements GenericDao<T, ID> {

}

?

一個(gè)泛型變量或通配符可以有多個(gè)限定。限定類型使用"&"分割。若用一個(gè)類做限定,它必須是限定列表中的第一個(gè)。

例:<V extends Serializable & Cloneable> void method(){}

<V extends Serializable & cloneable> 表示聲明一個(gè)泛型參數(shù),參數(shù)類型必須繼承Serializable 且必須繼承Cloneable

?

可以用類型變量表示異常,稱為參數(shù)化的異常,可以用于方法的throws列表中,但是不能用于catch子句中。

例:

private static <T extends Exception> void sayHello() throws T {

try {

?

????????} catch (Exception e) {

????????????throw (T) e;

????}

}

?

?

?

9 泛型通配符

使用"?"通配符可以引用其他各種參數(shù)化的類型,"?"通配符定義的變量主要用作引用,可以調(diào)用與參數(shù)化無(wú)關(guān)的方法,不能調(diào)用與參數(shù)化有關(guān)的方法。

例:Collection<?>可以適配Collection<Object>Collection<Integer>Collection<String>等。

?

例:定義一個(gè)方法,該方法用于打印出任意參數(shù)化類型的集合中的所有數(shù)據(jù),該方法如何定義呢?

錯(cuò)誤方式:

????public static void printCollection(Collection<Object> cols) {

????????for (Object obj : cols) {

????????????System.out.println(obj);

????????}

????}

說(shuō)明:該方法只能接收Collection<Object>類型的參數(shù)。對(duì)Collection<Integer>Collection<String>無(wú)法接收。

正確方式:

不使用泛型,編譯器提示警告。

????public static void printCollection(Collection cols) {

????????for (Object obj : cols) {

????????????System.out.println(obj);

????????}

????}

利用泛型通配符,使用泛型。

????public static void printCollection(Collection<?> cols) {

????????for (Object obj : cols) {

????????????System.out.println(obj);

????????}

????}

說(shuō)明:該方法可以接收Collection<Integer>Collection<Object>Collection<String>等。

?

參數(shù)通配符使用的聲明的類型,是不確定類型的。在使用的時(shí)候,可能會(huì)造成一些錯(cuò)誤。

例:定義兩個(gè)方法method1與method2。

?

?

9.1 限定通配符的上邊界

<? extends Number>用于匹配Number及Number的子類。

正確:Vector<? extends Number> x = new Vector<Integer>(); Integer繼承了Number

錯(cuò)誤:Vector<? extends Number> x = new Vector<String>();

?

9.2限定通配符的下邊界

<? super Integer>用于匹配Integer及Integer的父類。

正確:Vector<? super Integer> x = new Vector<Number>();

錯(cuò)誤:Vector<? super Integer> x = new Vector<Byte>();

?

說(shuō)明:

限定通配符總是包括自己。

?只能用作引用,不能用它去給其他變量賦值

????Vector<? extends Number> y = new Vector<Integer>();

????Vector<Number> x = y; 錯(cuò)誤,原理與Vector<Object > x11 = new Vector<String>();相似,只能通過(guò)強(qiáng)制類型轉(zhuǎn)換方式來(lái)賦值。

?

?

10 泛型類型推斷

例,對(duì)于上面定義的static <T> T method(T x,T y)方法。注意其返回類型。

Integer i = method(1,2); //1與2都是Integer,所以返回Integer

Double d = method(1.2,2.3); //1.2,2.3默認(rèn)都是Double,所以返回Double

Number n = method(1.2,2); //1.2是Double,2是Integer,兩者均能匹配Number。返回Number。

Object o = method(1.2,"2"); //1.2是Double,"2"是String,這者均能匹配Object。返回Object。

method的返回類型是參數(shù)x與參數(shù)y允許允許匹配類型的交集。

?

編譯器判斷范型方法的實(shí)際類型參數(shù)的過(guò)程稱為類型推斷。類型推斷是相對(duì)于知覺(jué)推斷的,其實(shí)現(xiàn)方法是一種非常復(fù)雜的過(guò)程。

根據(jù)調(diào)用泛型方法時(shí)實(shí)際傳遞的參數(shù)類型或返回值的類型來(lái)推斷,具體規(guī)則如下:

  • 當(dāng)某個(gè)類型變量只在整個(gè)參數(shù)列表中的所有參數(shù)和返回值中的一處被應(yīng)用了,那么根據(jù)調(diào)用方法時(shí)該處的實(shí)際應(yīng)用類型來(lái)確定,這很容易憑著感覺(jué)推斷出來(lái),即直接根據(jù)調(diào)用方法時(shí)傳遞的參數(shù)類型或返回值來(lái)決定泛型參數(shù)的類型。
    例: swap(new String[3],3,4) ---> static <E> void swap(E[] a, int i, int j)
  • 當(dāng)某個(gè)類型變量在整個(gè)參數(shù)列表中的所有參數(shù)和返回值中的多處被應(yīng)用了,如果調(diào)用方法時(shí)這多處的實(shí)際應(yīng)用類型都對(duì)應(yīng)同一種類型來(lái)確定,這很容易憑著感覺(jué)推斷出來(lái)。
    例:add(3,5) ---> static <T> T add(T a, T b)
  • 當(dāng)某個(gè)類型變量在整個(gè)參數(shù)列表中的所有參數(shù)和返回值中的多處被應(yīng)用了,如果調(diào)用方法時(shí)這多處的實(shí)際應(yīng)用類型對(duì)應(yīng)到了不同的類型,且沒(méi)有使用返回值,這時(shí)候取多個(gè)參數(shù)中的最大交集類型
    例:下面語(yǔ)句實(shí)際對(duì)應(yīng)的類型就是Number了,編譯沒(méi)問(wèn)題,只是運(yùn)行時(shí)出問(wèn)題。
    fill(new Integer[3],3.5f) ---> static <T> void fill(T[] a, T v)
  • 當(dāng)某個(gè)類型變量在整個(gè)參數(shù)列表中的所有參數(shù)和返回值中的多處被應(yīng)用了,如果調(diào)用方法時(shí)這多處的實(shí)際應(yīng)用類型對(duì)應(yīng)到了不同的類型, 并且使用返回值,這時(shí)候優(yōu)先考慮返回值的類型。
    例如,下面語(yǔ)句實(shí)際對(duì)應(yīng)的類型就是Integer了,編譯將報(bào)告錯(cuò)誤,將變量x的類型改為float,對(duì)比eclipse報(bào)告的錯(cuò)誤提示,接著再將變量x類型改為Number,則沒(méi)有了錯(cuò)誤。
    int x =(3,3.5f) ---> static <T> T add(T a, T b)
  • 參數(shù)類型的類型推斷具有傳遞性,下面第一種情況推斷實(shí)際參數(shù)類型為Object,編譯沒(méi)有問(wèn)題,而第二種情況則根據(jù)參數(shù)化的Vector類實(shí)例將類型變量直接確定為String類型,編譯將出現(xiàn)問(wèn)題。
    例:copy(new Integer[5],new String[5]) ---> static <T> void copy(T[] a,T[] b);
    copy(new Vector<String>(), new Integer[5]) ---> static <T> void copy(Collection<T> a , T[] b);

?

?

?

11 通過(guò)反射獲取泛型類型

如List<Date> list= new ArrayList<Date>(); 通過(guò)反射獲取list的類型。這是很多框架內(nèi)部實(shí)現(xiàn)的常見(jiàn)需求。

雖然Java編譯器會(huì)把泛型類型擦除,但擦除的類仍然保留一些泛型祖先的微弱記憶。

?

方法一:反射相關(guān)的Method對(duì)象,可以獲取其代表方法的參數(shù)所帶的泛型信息。

示例代碼:

public class GenericalReflection {

????private List<Date> dates = new ArrayList<Date>();

?

????public void setDates(List<Date> dates) {

????????this.dates = dates;

????}

?

????public static void main(String[] args) throws SecurityException, NoSuchMethodException {

????????//獲取setDates的Method對(duì)象

????????Method methodApply = GenericalReflection.class.getDeclaredMethod("setDates", List.class);

????????Type[] gTypes= methodApply.getGenericParameterTypes();

????????ParameterizedType pType = (ParameterizedType) (gTypes)[0];

????????Type[] actualTypeArguments = pType.getActualTypeArguments();

????????//輸出Method對(duì)象泛型擦除后的類型。

????????System.out.println(((Class)pType.getRawType()).getName());

????????//輸出Method對(duì)象泛型信息。

System.out.println(((Class)actualTypeArguments[0]).getName());

????}

}

?

方法二:通過(guò)使用class實(shí)例的getGenericSuperclass()方法獲取泛型信息。

例:泛型DAO實(shí)現(xiàn)類中獲取泛型類型。

public interface BaseDao<T> {

}

?

@SuppressWarnings("unchecked")

public abstract class BaseDaoImpl<T> implements BaseDao<T> {

????protected Class<T> clazz;

?

????public BaseDaoImpl() {

????????Type type = this.getClass().getGenericSuperclass();

????????ParameterizedType pt = (ParameterizedType) type;

????????this.clazz = (Class) pt.getActualTypeArguments()[0];

????????System.out.println("clazz = " + this.clazz);

????}

}

?

?

轉(zhuǎn)載于:https://www.cnblogs.com/shijiaqi1066/p/3441445.html

總結(jié)

以上是生活随笔為你收集整理的Java泛型总结的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。