JAVA基礎(chǔ)-泛型鸳谜、序列化和反序列化膝藕、克隆

4.JAVA泛型

1)泛型方法:該方法可以在調(diào)用時接受不同的參數(shù),根據(jù)傳遞給泛型方法的參數(shù)類型適當(dāng)?shù)奶幚砻恳粋€方法調(diào)用咐扭。注意:\color{red}{將一個泛型方法聲明為任何其他方法時芭挽,類型參數(shù)只能表示引用類型,而不是原始類型(int,double和char)}滑废,示例如下:

package cn.tedu.test;

public class Test {
    public static <E> void print(E[] inputArray){
        for(E e:inputArray) {
            System.out.print(e+" ");
        }
    }
    public static void main(String[] args) {
        System.out.println("字符數(shù)組:");
        Character s[]= {'A','B','C'};
        print(s);
        System.out.println("\nint數(shù)組:");
        Double d[]= {2.1,1.2,3.3};
        print(d);
        System.out.println("\ndouble數(shù)組:");
        Integer i[]= {1,2,34};
        print(i);
    }
}

輸出結(jié)果如下:

泛型方法.png

2)泛型類:泛型類的類型參數(shù)聲明部分也包括一個或多個類型參數(shù),參數(shù)間用逗號隔開袜爪,注意:,示例如下:

package cn.tedu.test;

public class Test1<T,K> {
    private T t;
    private K k;
    public void set(T t,K k) {
        this.t=t;
        this.k=k;
    }
    public void print() {
        System.out.println("T:"+t+",K:"+k);
    }
    public static void main(String[] args) {
        //不可以直接使用原始類
        Test1<Integer,String> t=new Test1<Integer,String>();
        t.set(1, "ABC");
        t.print();
    }
}

輸出如下:


泛型類.png

3)類型通配符:一般使用蠕趁?代替具體的參數(shù),例如List<?>在邏輯上是List<String>辛馆、List<Integer>等所有List<具體類型實參的父類>俺陋。<? extends T>表示該通配符所代表的類型是T類型的子類,<? super T>表示該通配符所代表的類型是T類型的父類昙篙。
4)類型擦除:Java中的泛型基本上都是在編譯器這個層次上實現(xiàn)的腊状。在生成的Java字節(jié)碼中是不包含泛型中的類型信息,使用泛型的時候加上的類型參數(shù)苔可,會被編譯器在編譯的時候去掉缴挖,這個過程就稱為類型擦除。

5.JAVA序列化與反序列化

1)概念:序列化:把對象轉(zhuǎn)換為字節(jié)序列的過程稱為對象的序列化
反序列化:把字節(jié)序列恢復(fù)為對象的過程稱為對象的反序列化焚辅。
2)序列化API:
java.io.ObjectOutoutStream代表對象輸出流映屋,他的writeObject(Object obj)方法可對指定對象obj對象進(jìn)行序列化,把得到的對象字節(jié)序列寫入到一個目標(biāo)輸出流法焰。
java.io.ObjectInputSTream代表對象輸入流秧荆,他的readObject()方法可從輸入流中讀取字節(jié)序列,再把他們反序列化轉(zhuǎn)換為一個對象埃仪,并將其返回乙濒。
只有實現(xiàn)了Serlizable的接口對象才能被序列化。
\color{red}{注意:}凡是實現(xiàn)Serializable接口的類都有一個表示序列化版本標(biāo)識符的靜態(tài)變量卵蛉,如果類中沒有添加serialVersionUID,那么就會出現(xiàn)警告提示颁股,通過鼠標(biāo)點(diǎn)擊警告提示,可以對其進(jìn)行添加傻丝,若不進(jìn)行添加該變量甘有,之后對序列化對象進(jìn)行修改時,再次運(yùn)行反序列化函數(shù)將會拋出異常信息
代碼實例如下:
定義一個Person對象葡缰,實現(xiàn)Serialiable接口

package cn.tedu.test;

import java.io.Serializable;

public class Person implements Serializable{
    /**
     * 
     */
    private static final long serialVersionUID = 1L;
    private int age;
    private String name;
    private String sex;
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getSex() {
        return sex;
    }
    public void setSex(String sex) {
        this.sex = sex;
    }
    @Override
    public String toString() {
        return "Person [age=" + age + ", name=" + name + ", sex=" + sex + "]";
    }
    
}

執(zhí)行序列化和反序列化的功能:

package cn.tedu.test;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

public class SerializeTest {
    //序列化
    public static void SerializablePerson() throws FileNotFoundException, IOException {
        Person p=new Person();
        p.setAge(11);
        p.setName("張一思");
        p.setSex("男");
        ObjectOutputStream oo=new ObjectOutputStream(new FileOutputStream
                (new File("person.txt")));
        oo.writeObject(p);
        System.out.println("person對象序列化成功");
        oo.close();
    }
    
    //反序列化
    public static Person DeserializablePerson() throws FileNotFoundException, IOException, ClassNotFoundException{
        ObjectInputStream ois=new ObjectInputStream(new FileInputStream
                (new File("person.txt")));
        Person p=(Person) ois.readObject();
        System.out.println("person對象反序列化成功亏掀!");
        ois.close();
        return p;
    }
    public static void main(String[] args) throws FileNotFoundException, IOException, ClassNotFoundException {
        SerializablePerson();
        Person p=DeserializablePerson();
        System.out.println(p.toString());
    }
}

輸出結(jié)果如下:


序列化與反序列化.png

3)transient關(guān)鍵字阻止該變量被序列化到文件中
-在變量聲明前加上transient關(guān)鍵字,可以阻止該變量被序列化到文件中泛释,在反序列化后滤愕,tanslent變量值被設(shè)為初始值,如int型的是0怜校,對象型的是null.下圖中仍舊是用上述代碼间影,將Person類中的age變量前面加入transient后,可以看到在進(jìn)行序列化時并未將該變量加入到序列化文件中茄茁。結(jié)果如下所示:


transient.png

6.Java克隆

  • 在Java中若對對象進(jìn)行直接賦值時魂贬,將會直接將對象的引用復(fù)制給另外一個對象,兩個不同的變量將會同為一個對象的引用巩割,無法實現(xiàn)將某一個對象作為另外一個對象的初始值,之后再對其進(jìn)行相應(yīng)改變的功能付燥。而要實現(xiàn)該功能宣谈,將會引入兩種復(fù)制方式:淺復(fù)制和深復(fù)制。
    *淺克禄帷:首先被復(fù)制的類需要實現(xiàn)Cloneable接口蒲祈,之后覆蓋clone方法,訪問修飾符設(shè)為public萝嘁。方法中調(diào)用super梆掸。clone()方法得到需要復(fù)制的對象,該對象賀源對象不為同一個牙言。直接賦值復(fù)制和淺克隆的示例如下:
package day01;

public class Demo1 {
    public class Student{
        private String name;
        private int age;
        public Student(String name,int age) {
            // TODO Auto-generated constructor stub
            this.name=name;
            this.age=age;
        }
        @Override
        public String toString() {
            return "Girl [name=" + name + ", age=" + age + "]";
        }
        
    }
    public class Girl implements Cloneable{
        private String name;
        private int age;
        public Girl(String name,int age) {
            // TODO Auto-generated constructor stub
            this.name=name;
            this.age=age;
        }
        @Override
        public String toString() {
            return "Student [name=" + name + ", age=" + age + "]";
        }
        @Override
        protected Object clone() throws CloneNotSupportedException {
            // TODO Auto-generated method stub
            return (Girl)super.clone();
        }
    }
    public static void main(String[] args) throws CloneNotSupportedException {
        Demo1.Student s1=new Demo1().new Student("A",11);
        //直接賦值復(fù)制
        Demo1.Student s2=s1;
        s1.age=22;
        System.out.println("直接賦值復(fù)制:");
        System.out.println("是否相等:"+(s1==s2));
        System.out.println("student1:"+s1);
        System.out.println("studnet2:"+s2);
        //淺復(fù)制
        Demo1.Girl girl1=new Demo1().new Girl("麗麗", 18);
        Demo1.Girl girl2=(Girl) girl1.clone();
        System.out.println("淺復(fù)制:");
        System.out.println("是否相等:"+(girl1==girl2));
        System.out.println(girl1);
        System.out.println(girl2);
    }
}

輸出結(jié)果如下:


淺復(fù)制和直接賦值復(fù)制.png
  • 深克滤崆铡:經(jīng)過淺克隆的學(xué)習(xí),感覺只有淺克隆就足以應(yīng)對我們需要的功能咱枉,那么在這樣的情況下卑硫,我們?yōu)槭裁催€需要再次增加一個深克隆的內(nèi)容,我們以下面的情況為例:當(dāng)我們需要在上面的girl類中增加一個屬性Address類元素時蚕断,再次進(jìn)行淺復(fù)制的內(nèi)容欢伏,將會出現(xiàn)下面的結(jié)果,代碼如下:
package day01;

public class Demo11 {
    public class Address{
        private String addr;

        public String getAddr() {
            return addr;
        }

        public void setAddr(String addr) {
            this.addr = addr;
        }

        @Override
        public String toString() {
            return "Address [addr=" + addr + "]";
        }
    }
    public class Girl implements Cloneable{
        private String name;
        private int age;
        private Address address;
        public String getName() {
            return name;
        }
        public int getAge() {
            return age;
        }
        public Address getAddress() {
            return address;
        }
        public void setName(String name) {
            this.name = name;
        }
        public void setAge(int age) {
            this.age = age;
        }
        public void setAddress(Address address) {
            this.address = address;
        }
        @Override
        public String toString() {
            return "Girl [name=" + name + ", age=" + age + ", address=" + address + "]";
        }
        @Override
        protected Object clone() throws CloneNotSupportedException {
            // TODO Auto-generated method stub
            return (Girl)super.clone();
        }
    }
    public static void main(String[] args) throws CloneNotSupportedException{
        //深復(fù)制
        Demo11.Girl firGirl=new Demo11().new Girl();
        Address address=new Demo11().new Address();
        address.setAddr("浙江省");
        firGirl.setAddress(address);
        firGirl.setAge(11);
        firGirl.setName("B");
        Demo11.Girl g2=(Girl) firGirl.clone();
        address.setAddr("山西省");
        System.out.println("g2:"+g2);
        System.out.println("g1"+firGirl);
    }
}

輸出結(jié)果如下:


深復(fù)制.png

由結(jié)果很明顯可以看到亿乳,兩個對象的地址元素同步進(jìn)行了更新硝拧,這是我們需要使用深克隆來實現(xiàn)其功能,具體代碼如下:

package day01;

public class Demo111 {
    public class Address implements Cloneable{
        private String addr;

        public String getAddr() {
            return addr;
        }

        public void setAddr(String addr) {
            this.addr = addr;
        }

        @Override
        public String toString() {
            return "Address [addr=" + addr + "]";
        }
        @Override
        protected Object clone() throws CloneNotSupportedException {
            // TODO Auto-generated method stub
            return super.clone();
        }
    }
    public class Girl implements Cloneable{
        private String name;
        private int age;
        private Address address;
        public String getName() {
            return name;
        }
        public int getAge() {
            return age;
        }
        public Address getAddress() {
            return address;
        }
        public void setName(String name) {
            this.name = name;
        }
        public void setAge(int age) {
            this.age = age;
        }
        public void setAddress(Address address) {
            this.address = address;
        }
        @Override
        public String toString() {
            return "Girl [name=" + name + ", age=" + age + ", address=" + address + "]";
        }
        @Override
        protected Object clone() throws CloneNotSupportedException {
            // TODO Auto-generated method stub
            Girl g=(Girl) super.clone();
            g.address=(Address) this.address.clone();
            return g;
        }
    }
    public static void main(String[] args) throws CloneNotSupportedException{
        //深復(fù)制
        Demo111.Girl firGirl=new Demo111().new Girl();
        Address address=new Demo111().new Address();
        address.setAddr("浙江省");
        firGirl.setAddress(address);
        firGirl.setAge(11);
        firGirl.setName("B");
        Demo111.Girl g2=(Girl) firGirl.clone();
        address.setAddr("山西省");
        System.out.println("g2:"+g2);
        System.out.println("g1"+firGirl);
    }
}

輸出結(jié)果如下:


深克隆使用.png

很明顯由輸出結(jié)果可知葛假,我們需要的功能完全實現(xiàn)障陶。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市聊训,隨后出現(xiàn)的幾起案子抱究,更是在濱河造成了極大的恐慌,老刑警劉巖带斑,帶你破解...
    沈念sama閱讀 219,589評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件鼓寺,死亡現(xiàn)場離奇詭異,居然都是意外死亡勋磕,警方通過查閱死者的電腦和手機(jī)侄刽,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,615評論 3 396
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來朋凉,“玉大人,你說我怎么就攤上這事醋安≡优恚” “怎么了墓毒?”我有些...
    開封第一講書人閱讀 165,933評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長亲怠。 經(jīng)常有香客問我所计,道長,這世上最難降的妖魔是什么团秽? 我笑而不...
    開封第一講書人閱讀 58,976評論 1 295
  • 正文 為了忘掉前任主胧,我火速辦了婚禮,結(jié)果婚禮上习勤,老公的妹妹穿的比我還像新娘踪栋。我一直安慰自己,他們只是感情好图毕,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,999評論 6 393
  • 文/花漫 我一把揭開白布夷都。 她就那樣靜靜地躺著,像睡著了一般予颤。 火紅的嫁衣襯著肌膚如雪囤官。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,775評論 1 307
  • 那天蛤虐,我揣著相機(jī)與錄音党饮,去河邊找鬼。 笑死驳庭,一個胖子當(dāng)著我的面吹牛刑顺,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播嚷掠,決...
    沈念sama閱讀 40,474評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼捏检,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了不皆?” 一聲冷哼從身側(cè)響起贯城,我...
    開封第一講書人閱讀 39,359評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎霹娄,沒想到半個月后能犯,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,854評論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡犬耻,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,007評論 3 338
  • 正文 我和宋清朗相戀三年踩晶,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片枕磁。...
    茶點(diǎn)故事閱讀 40,146評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡渡蜻,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情茸苇,我是刑警寧澤排苍,帶...
    沈念sama閱讀 35,826評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站学密,受9級特大地震影響淘衙,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜腻暮,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,484評論 3 331
  • 文/蒙蒙 一彤守、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧哭靖,春花似錦具垫、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,029評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至抡草,卻和暖如春饰及,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背康震。 一陣腳步聲響...
    開封第一講書人閱讀 33,153評論 1 272
  • 我被黑心中介騙來泰國打工燎含, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人腿短。 一個月前我還...
    沈念sama閱讀 48,420評論 3 373
  • 正文 我出身青樓屏箍,卻偏偏與公主長得像,于是被迫代替她去往敵國和親橘忱。 傳聞我的和親對象是個殘疾皇子赴魁,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,107評論 2 356