4.JAVA泛型
1)泛型方法:該方法可以在調(diào)用時接受不同的參數(shù),根據(jù)傳遞給泛型方法的參數(shù)類型適當(dāng)?shù)奶幚砻恳粋€方法調(diào)用咐扭。注意:滑废,示例如下:
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é)果如下:
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();
}
}
輸出如下:
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的接口對象才能被序列化。
凡是實現(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é)果如下:
3)transient關(guān)鍵字阻止該變量被序列化到文件中
-在變量聲明前加上transient關(guān)鍵字,可以阻止該變量被序列化到文件中泛释,在反序列化后滤愕,tanslent變量值被設(shè)為初始值,如int型的是0怜校,對象型的是null.下圖中仍舊是用上述代碼间影,將Person類中的age變量前面加入transient后,可以看到在進(jìn)行序列化時并未將該變量加入到序列化文件中茄茁。結(jié)果如下所示:
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é)果如下:
- 深克滤崆铡:經(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é)果如下:
由結(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é)果如下:
很明顯由輸出結(jié)果可知葛假,我們需要的功能完全實現(xiàn)障陶。