Java基礎(chǔ)字符編碼與內(nèi)存流詳細(xì)解讀
1、字符編碼
1.1 常用字符編碼
在計(jì)算機(jī)的世界之中,所有的顯示文字都是按照其指定的數(shù)字編碼進(jìn)行保存的,如果沒(méi)有正確的解碼,那么就坑你產(chǎn)生亂碼,如果要想清楚解決亂碼問(wèn)題,就要了解經(jīng)常見(jiàn)到一些常見(jiàn)的編碼:
GBK/GBK2312:表示國(guó)標(biāo)中文編碼,其中GBK是包含簡(jiǎn)體中文和繁體中文,而GB2312只有簡(jiǎn)體;
ISO 8859-1:是一種國(guó)際通用編碼,可以表示任何文字,但是對(duì)于中國(guó)文字需要進(jìn)行轉(zhuǎn)碼;
UNICODE:使用十六進(jìn)制完成的編碼,可以準(zhǔn)確的表示出任何的語(yǔ)言文字;
UTF-8:部分編碼使用UNICODE,而一些編碼繼續(xù)使用像ISO 8859-1,類(lèi)型的編碼,適合于網(wǎng)絡(luò)傳輸,在以后的所有的項(xiàng)目開(kāi)發(fā)之中,都必須采用此編碼??墒强紤]到日后學(xué)習(xí)的方便,幾乎都會(huì)使用命令行進(jìn)行操作,所以命令行只支持GBK編碼,UTF不支持,一旦程序設(shè)置了UTF編碼,那么通過(guò)命令行查看就是亂碼。
在開(kāi)發(fā)之中經(jīng)常會(huì)遇見(jiàn)亂碼的問(wèn)題,所謂的亂碼的核心在于編碼和解碼不統(tǒng)一。如果要想正確的避免項(xiàng)目之中出現(xiàn)的亂碼,那么首先就應(yīng)該知道環(huán)境之中所支持的編碼是什么。
1.2 亂碼產(chǎn)生分析
讀取Java運(yùn)行屬性
package com.day15.demo; public class ListDemo { public static void main(String[] args) { System.getProperties().list(System.out); } }
這個(gè)時(shí)候顯示出來(lái)的信息是很多的,這里面有專(zhuān)門(mén)的編碼選項(xiàng)“file.encoding=GBK”,也就是說(shuō)如果沒(méi)有任何的意外,所有的文字編碼都是GBK。
改變編碼
package com.day15.demo; import java.io.File; import java.io.FileOutputStream; import java.io.OutputStream; public class ListDemo { public static void main(String[] args) throws Exception{ OutputStream out = new FileOutputStream(new File("f:" + File.separator + "test" + File.separator + "hello.txt"),true); out.write("世界和平".getBytes()); out.close(); } }
2、內(nèi)存流基本操作
在講解之前首先來(lái)思考一個(gè)問(wèn)題:就是如果現(xiàn)在某個(gè)操作必須發(fā)生IO,但有不希望有一些臨時(shí)文件產(chǎn)生的話,那么現(xiàn)在肯定無(wú)法使用之前的文件操作流,所以為了解決這樣的問(wèn)題,提供了內(nèi)存操作流,即:以內(nèi)存進(jìn)行操作的終端,以發(fā)生IO操作關(guān)系。
對(duì)于內(nèi)存操作流也分為兩組:
**字節(jié)內(nèi)存操作流:**內(nèi)存輸入流(ByteArrayInputStream)內(nèi)存輸出流(ByteArrayOutputStream)
**字符內(nèi)存操作流:**內(nèi)存輸入流(CharArrayReader)內(nèi)存輸出流(CharArrayWriter)
ByteArrayInputStream ByteArrayOutputStreamjava.lang.Object java.io.InputStream java.io.ByteArrayInputStreamjava.lang.Object java.io.OutputStream java.io.ByteArrayOutputStreampublic ByteArrayInputStream(byte[] buf)public ByteArrayOutputStream()
輸出流
輸入流
通過(guò)內(nèi)存實(shí)現(xiàn)大小寫(xiě)轉(zhuǎn)換的操作
package com.day15.demo; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.InputStream; import java.io.OutputStream; import com.sun.xml.internal.messaging.saaj.util.ByteOutputStream; public class MemoryDemo { public static void main(String[] args) throws Exception{ String str = "Hello,World!"; InputStream in = new ByteArrayInputStream(str.getBytes()); OutputStream out = new ByteOutputStream(); int temp = 0; while((temp = in.read())!=-1){ out.write(Character.toUpperCase(temp)); } in.close(); out.close(); System.out.println(out.toString()); } }
此過(guò)程我們發(fā)現(xiàn)沒(méi)有文件的產(chǎn)生,而此過(guò)程只不過(guò)是產(chǎn)生了臨時(shí)文件。
3、打印流
如果說(shuō)想在要想輸出數(shù)據(jù),肯定使用OuputStream或者是Writer,那么請(qǐng)問(wèn),這兩個(gè)操作類(lèi)在執(zhí)行輸出的時(shí)候你認(rèn)為它好用嗎?
打印流主要解決的就是OutputStream缺陷,屬于OutputStream加強(qiáng)版,如果現(xiàn)在操作不是二進(jìn)制的數(shù)據(jù),只是通過(guò)程序向終端目標(biāo)輸出信息。OutputStream并不方便。
缺點(diǎn)一:所有的數(shù)據(jù)必須變?yōu)樽止?jié)數(shù)組
缺點(diǎn)二:只支持String類(lèi)型,輸出int、double就不方便
如果現(xiàn)在要想輸出字符串,使用Writer可以直接輸出,而使用OutputStream還需要將字符串變?yōu)樽止?jié)數(shù)組,那么如果現(xiàn)在要想輸出數(shù)字(int型或double型),還需要將這些數(shù)據(jù)先變?yōu)樽址笤僮優(yōu)樽止?jié)數(shù)組輸出,多以,如果用戶直接調(diào)用OutputStream或Writer輸出的時(shí)候本身并不方便,所以在這個(gè)時(shí)候可以想辦法將OutputStream或Writer變得加強(qiáng)一些,定義一個(gè)專(zhuān)門(mén)的工具類(lèi):PrintUtil.java。
編寫(xiě)一個(gè)輸出功能類(lèi)PrintUtil類(lèi)
package com.day15.demo; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.OutputStream; class PrintUtil{ OutputStream out; public PrintUtil(OutputStream out){ this.out=out; } public void print(String str) throws Exception{ this.out.write(str.getBytes()); } public void println(String str) throws Exception{ this.print(str.concat("\r\n")); } public void print(int num) throws Exception{ this.print(String.valueOf(num)); } public void println(int num) throws Exception{ this.println(String.valueOf(num)); } } public class PintUtilDemo { public static void main(String[] args) throws Exception { PrintUtil printUtil = new PrintUtil(new FileOutputStream(new File("f:" + File.separator + "test" + File.separator + "test.txt"))); printUtil.println("姓名:" + "張麻子"); printUtil.print("年齡"); printUtil.print(19); } }
以后使用PrintWriter的使用率挺高,但是這兩者的使用形式相同的。首先觀察這兩個(gè)類(lèi)的繼承結(jié)構(gòu)和構(gòu)造方法:
首先來(lái)觀察一下PrintStream,PrintWriter的繼承結(jié)構(gòu)和構(gòu)造方法:
PrintStream | PrintWriter |
java.lang.Object java.io.OutputStream java.io.FilterOutputStream java.io.PrintStream |
java.lang.Object java.io.Writer java.io.PrintWriter |
public PrintStream(OuputStream out) | public PrintWriter(Writer out) |
看見(jiàn)以上的結(jié)構(gòu),可能第一反應(yīng)就屬于代理設(shè)計(jì)模式,但它并不是代理,代理設(shè)計(jì)模式的特點(diǎn):以接口為使用原則,用戶調(diào)用代理主題方法的時(shí)候依然是接口之中定義的方法。而此時(shí)PrintStream類(lèi)調(diào)用的絕對(duì)不是OutputStream類(lèi)之中定義的一系列write()方法。雖然PrintStream在外表操作上產(chǎn)生了變化,但實(shí)際上依然執(zhí)行的是OutputStream累哦所定義的操作,所以本質(zhì)沒(méi)有發(fā)生變化,只是提供了一些更加方便的功能支持,多以這種設(shè)計(jì)模式上講稱(chēng)為裝飾設(shè)計(jì)模式。
3.1 格式化文本信息
在JDK1.5之后,打印流也進(jìn)行了更新,增加了一個(gè)新的方法,格式化輸出:格式化輸出:public PrintStream printf(String format,Object… args)
當(dāng)看到此方法名稱(chēng)的時(shí)候首先想到的是C語(yǔ)言中的輸出,而現(xiàn)在Java也具備了同樣的功能,而輸出的時(shí)候可以使用一些標(biāo)記表示要輸出的內(nèi)容,例如:字符串(%s),數(shù)字(%d)小數(shù)(%m.nf),字符(%c)等。
觀察格式化輸出
package com.day15.demo; import java.io.File; import java.io.FileOutputStream; import java.io.PrintWriter; public class PrintWriterDemo { public static void main(String[] args) throws Exception{ PrintWriter pu = new PrintWriter(new FileOutputStream(new File("f:" + File.separator + "test" + File.separator + "test.txt")),true); String name = "張麻子"; int age=23; double score=8123219.127456; pu.printf("姓名:%s 年齡:%d 成績(jī):%7.2f",name,age,score); } }
而在JDK1.5之后增加字符串格式化操作類(lèi)不光有PrintStream,還有String類(lèi),String類(lèi)也提供了一個(gè)格式化字符串的操作方法:public static String format(String format,Object… args)
格式化字符串
package com.day15.demo; import java.io.File; import java.io.FileOutputStream; import java.io.PrintWriter; public class PrintWriterDemo { public static void main(String[] args) throws Exception{ PrintWriter pu = new PrintWriter(new FileOutputStream(new File("f:" + File.separator + "test" + File.separator + "test.txt")),true); String name = "張麻子"; int age=23; double score=8123219.127456; String str = String.format("姓名:%s 年齡:%d 成績(jī):%7.2f",name,age,score); System.out.println(str); } }
雖然格式化字符串可以執(zhí)行準(zhǔn)確的四舍五入操作,但是這種處理完的數(shù)據(jù)都是String型,而實(shí)際工作中,如果要四舍五入,肯定還是要編寫(xiě)B(tài)igDecimal類(lèi)完成。
以后只要是程序輸出數(shù)據(jù)的操作,都使用PrintStream類(lèi)。
4、 System類(lèi)
在我們學(xué)習(xí)完了PrintWriter、PrintStream之后我們會(huì)發(fā)現(xiàn)里面的方法都很熟悉,例如print()、println()輸出就利用我們的IO流模式完成的。在System類(lèi)中實(shí)際上定義有三個(gè)操作的常量。
public static final PrintStream out | 標(biāo)準(zhǔn)輸出 |
public static final PrintStream err | 錯(cuò)誤輸出 |
public static final InputStream in | 標(biāo)準(zhǔn)輸出 |
4.1 系統(tǒng)輸出
系統(tǒng)輸出我們發(fā)現(xiàn)一共有兩個(gè)常量:out、err,而且這兩個(gè)常量所表示的都是PrintSream的對(duì)象。從
Java設(shè)計(jì)的本質(zhì)上來(lái)講這樣的輸出有以下設(shè)計(jì)的目的。out是希望輸出的用戶可以看見(jiàn)的內(nèi)容
,err是希望輸出用戶不能夠看見(jiàn)的內(nèi)容。
package com.day15.demo; public class PrintDemo { public static void main(String[] args) throws Exception{ try{ Integer.valueOf("abc"); }catch(Exception e){ System.err.println(e); System.out.println(e); } } } /* java.lang.NumberFormatException: For input string: "abc" java.lang.NumberFormatException: For input string: "abc" */
4.2 系統(tǒng)輸出
系統(tǒng)輸出是將所有的信息輸出到指定的輸出設(shè)備上——顯示器。而System.out本身是屬于PrintStream對(duì)象,而PrintStream是OutputStream子類(lèi),所以現(xiàn)在實(shí)際上可以利用System.out為OutputStream類(lèi)執(zhí)行實(shí)例化操作。
package com.day15.demo; import java.io.OutputStream; public class PrintDemo { public static void main(String[] args) throws Exception { String str ="hello,world"; OutputStream output = System.out;//System.out為OutputStream實(shí)例化 output.write(str.getBytes()); } }
本程序沒(méi)有任何的意義,而講解的主要目的就希望可以理解:OutputStream會(huì)根據(jù)實(shí)例化它的子類(lèi)或?qū)ο蟮牟煌?,輸出的位置也不同?/p>
4.3 系統(tǒng)輸入
系統(tǒng)輸入針對(duì)于標(biāo)準(zhǔn)的輸入設(shè)備——鍵盤(pán),也就是俗稱(chēng)的鍵盤(pán)輸入數(shù)據(jù),但是System.in返回的是InputStream型的數(shù)據(jù),所以下面編寫(xiě)一個(gè)操作由鍵盤(pán)輸入數(shù)據(jù)。
package com.day15.demo; import java.io.IOException; import java.io.InputStream; public class inDemo { public static void main(String[] args) throws Exception { InputStream input = System.in; System.out.println("請(qǐng)輸入!"); byte data[] = new byte[1024]; int len = input.read(data); System.out.println(new String(data,0,len)); } }
除了實(shí)例化InputStream類(lèi)的對(duì)象不同之外,其他的地方和之前文件輸入數(shù)據(jù)沒(méi)有任何區(qū)別,但是這個(gè)程序本身有問(wèn)題,已經(jīng)開(kāi)辟的空間大小是1024,如果輸入的數(shù)據(jù)超過(guò)1024呢?發(fā)現(xiàn)只會(huì)接收滿足指定長(zhǎng)度的數(shù)據(jù),程序有bug,那么最好的解決方法是不設(shè)置長(zhǎng)度,輸入一個(gè)讀取一個(gè),一直到用戶不輸入為止。
package com.day15.demo; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; public class inDemo { public static void main(String[] args) throws Exception { InputStream input = System.in;//為父類(lèi)實(shí)例化 ByteArrayOutputStream bos = new ByteArrayOutputStream(); byte data[] = new byte[10];//開(kāi)辟一個(gè)空間 System.out.println("請(qǐng)輸入!"); int temp = 0; while((temp = input.read(data))!=-1){//數(shù)據(jù)讀取到字節(jié)數(shù) //這里面要用戶自己來(lái)處理?yè)Q行問(wèn)題 bos.write(data,0,temp);//保存在內(nèi)存輸出流 if(temp < data.length){ break; } } System.out.println(new String(bos.toByteArray())); } }
簡(jiǎn)化操作,但是中文無(wú)法識(shí)別
package com.day15.demo; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; public class inDemo { public static void main(String[] args) throws Exception { InputStream input = System.in;//為父類(lèi)實(shí)例化 StringBuffer buf = new StringBuffer(); System.out.println("請(qǐng)輸入!"); int temp = 0; while((temp = input.read())!=-1){//數(shù)據(jù)讀取到字節(jié)數(shù) //這里面要用戶自己來(lái)處理?yè)Q行問(wèn)題 if(temp == '\n'){ break; } buf.append((char)temp); } System.out.println(buf); } }
通過(guò)以上比較可以感受到System.in的支持度原本不高,對(duì)于英文的操作是支持,但是對(duì)于中文是不太友好的,對(duì)于中文的輸出還必須借助內(nèi)存流來(lái)實(shí)現(xiàn)的。
5、BufferedReader類(lèi)
BufferedReader屬于一個(gè)緩沖的輸入流,而且是一個(gè)字符流的操作對(duì)象。但是必須清楚一點(diǎn)就是對(duì)于我們的緩存流定義有兩類(lèi):字節(jié)緩沖流( BufferedInputStream )、字節(jié)緩沖流( BufferedReader )。
如果說(shuō)想在把所有的輸入數(shù)據(jù)放在一起了,一次性讀取出來(lái),那么這個(gè)時(shí)候肯定就能夠避免中文問(wèn)題了,而這一操作就必須依靠緩沖區(qū)操作流完成。對(duì)于緩沖區(qū)的讀取在IO包中定義了兩種類(lèi):BufferedInputStream,BufferedReader,但是考慮到本次操作有中文的問(wèn)題,肯定使用BufferedReader類(lèi)完成操作。下面就需要觀察一下BufferedReader類(lèi)的繼承結(jié)構(gòu),構(gòu)造方法,操作方法:
繼承結(jié)構(gòu): | java.lang.Object java.io.Reader java.io.BuffereedReader |
構(gòu)造方法: | public BuffereedReader(Reader in) |
讀取操作: | public String readLine() throws IOException |
之所以選擇BufferReader類(lèi)操作提供的readLine()方法,這個(gè)方法可以讀取一行數(shù)據(jù)以回車(chē)為準(zhǔn)。
使用BufferedReader進(jìn)行數(shù)據(jù)讀取
package com.day15.demo; import java.io.BufferedReader; import java.io.InputStreamReader; public class BufferReaderDemo { public static void main(String[] args) throws Exception{ BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in)); System.out.println("請(qǐng)輸入"); //默認(rèn)的換行模式是BufferReader最大的缺點(diǎn) String str = bufr.readLine();//接受輸入信息,默認(rèn)使用回車(chē)換行 System.out.println(str); } }
對(duì)輸入的數(shù)據(jù)進(jìn)行驗(yàn)證,判斷是否是數(shù)字
package com.day15.demo; import java.io.BufferedReader; import java.io.InputStreamReader; public class BufferReaderDemo { public static void main(String[] args) throws Exception{ BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in)); System.out.println("請(qǐng)輸入年齡"); //默認(rèn)的換行模式是BufferReader最大的缺點(diǎn) String str = bufr.readLine();//接受輸入信息,默認(rèn)使用回車(chē)換行 if(str.matches("\\d{1,3}")) System.out.println(str); else System.out.println("輸入數(shù)據(jù)有誤!"); } }
6、Scanner
這個(gè)類(lèi)是作為了一個(gè)工具類(lèi)出現(xiàn)的,在Scanner之中定義兩個(gè)如下的一些方法:
public Scanner(InputStream sourse); | 構(gòu)造方法 |
public Boolean hasNextXxx(); | 判斷是否有數(shù)據(jù) |
public 數(shù)據(jù)類(lèi)型 nextXxx(); | 取得數(shù)據(jù) |
public Scanner useDelimiter(String partern); | 定義分隔符 |
以后調(diào)用的時(shí)候在執(zhí)行nextXxx()之前一定要首先使用hasNextXxx()判斷是否有指定格式的數(shù)據(jù)出現(xiàn)。
通過(guò)Scanner類(lèi)進(jìn)行數(shù)據(jù)的輸入
package com.day15.demo; import java.util.Scanner; public class ScannerDemo { public static void main(String[] args) { Scanner sc = new Scanner(System.in); System.out.println("請(qǐng)輸入數(shù)據(jù):"); if(sc.hasNext()){//現(xiàn)在有輸入的內(nèi)容,不能判斷空字符串 System.out.println(sc.next()); } sc.close(); } }
使用Scanner類(lèi)判斷輸入數(shù)據(jù)是否是int型數(shù)據(jù)
package com.day15.demo; import java.util.Scanner; public class ScannerDemo { public static void main(String[] args) { System.out.println("請(qǐng)輸入數(shù)據(jù):"); Scanner sca=new Scanner(System.in); if(sca.hasNextInt()){ int date=sca.nextInt(); System.out.println("輸入的數(shù)據(jù)是:"+date); }else{ System.out.println("輸入的不是數(shù)字"); } } }
在Scaner類(lèi)之中,useDelimiter()方法的輸入針對(duì)于字符串,但是其他的數(shù)據(jù)類(lèi)型并不方便使用。
使用Scanner類(lèi)判斷用戶輸入的是不是生日
package com.day15.demo; import java.util.Scanner; public class ScannerDemo { public static void main(String[] args) { Scanner sc = new Scanner(System.in); System.out.println("請(qǐng)輸入生日:"); if(sc.hasNext("\\d{4}-\\d{2}-\\d{2}")){//現(xiàn)在有輸入的內(nèi)容,不能判斷空字符串 String bir = sc.next("\\d{4}-\\d{2}-\\d{2}"); System.out.println(bir); } sc.close(); } }
Scanner讀取文件內(nèi)容
package com.day15.demo; import java.io.File; import java.io.FileInputStream; import java.util.Scanner; public class ScannerDemo { public static void main(String[] args) throws Exception{ Scanner sc = new Scanner(new FileInputStream(new File("f:" + File.separator + "test" + File.separator + "hello.txt"))); sc.useDelimiter("\n"); if(sc.hasNext()){//現(xiàn)在有輸入的內(nèi)容,不能判斷空字符串 System.out.println(sc.next()); } sc.close(); } }
除了二進(jìn)制文件拷貝處理之外,只要針對(duì)于程序的信息輸出都使用打印流,對(duì)于信息的輸入都是Scanner。
7、對(duì)象序列化
所有的項(xiàng)目都一定有序列化的概念。
7.1 對(duì)象序列化的概念
所謂的對(duì)象序列化是指在內(nèi)存中保存的對(duì)象變?yōu)槎M(jìn)制流的形式進(jìn)行傳輸,或者將其保存在文本中。但是我們并不意味著所有對(duì)象都可以被序列化,嚴(yán)格來(lái)講,我們需要被實(shí)例化的類(lèi)對(duì)象往往需要傳輸使用,同時(shí)這個(gè)類(lèi) 必須實(shí)現(xiàn)java.io.Serializable接口。但是這個(gè)接口沒(méi)有任何方法定義,所以只是一個(gè)標(biāo)識(shí)。
package com.day15.demo; import java.io.Serializable; class Person implements Serializable{ private String name; private int age; public Person(String name, int age) { this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } } public class SerializableDemo { }
序列化對(duì)象是所需要保存的就是對(duì)象中的屬性所以默認(rèn)情況下對(duì)象的屬性將被轉(zhuǎn)為二進(jìn)制數(shù)據(jù)流存儲(chǔ)。
7.2 實(shí)現(xiàn)序列化和反序列化
如果要想進(jìn)行對(duì)象的序列化和反序列話的手工操作,在java之中提提供了兩個(gè)操作類(lèi):ObjectOutputStream,ObjectInputStream,而這兩個(gè)類(lèi)的繼承結(jié)構(gòu),構(gòu)造方法,操作方法定義如下:
ObjectOutputStream | ObjectInputStream |
java.lang.Object java.io.OutputStream java.io.ObjectOutputStream |
java.lang.Object java.io.InputStream java.io.ObjectInputStream |
public ObjectOutputStream(OutputStream out) throws IOException |
public ObjectInputStream(InputStream in) throws IOException |
public final void writeObject(Object obj) throws IOException |
public final Object readObject() throws IOException,ClassNotFoundException |
實(shí)現(xiàn)對(duì)象的序列化操作
package com.day15.demo; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.Serializable; import java.util.Arrays; class Person implements Serializable{ private String name; private int age; public Person(String name, int age) { this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override public String toString() { return "Person [name=" + name + ", age=" + age + "]"; } } public class SerializableDemo{ public static final File FILE = new File("F:" + File.separator + "test" + File.separator + "person.txt"); public static void ser(Object o) throws Exception { ObjectOutputStream outputStream = new ObjectOutputStream(new FileOutputStream(FILE)); outputStream.writeObject(o); outputStream.close(); } public static void dser() throws Exception { ObjectInputStream inputStream = new ObjectInputStream(new FileInputStream(FILE)); System.out.println(inputStream.readObject()); inputStream.close(); } public static void main(String[] args) throws Exception{ //序列化 //ser(new Person("張麻子",20)); //反序列化 dser(); } }
如果出現(xiàn)com.day15.demo.Person@6d311334這個(gè)情況的主要原因是因?yàn)閷?shí)體類(lèi)沒(méi)有進(jìn)行toString()方法的重寫(xiě)。
7.3 transient關(guān)鍵字(了解)
實(shí)際上序列化的處理在Java.io有兩類(lèi),Serializable是使用最多的序列化接口,這種操作采用自動(dòng)化的模式完成,默認(rèn)情況下所有的屬性都會(huì)進(jìn)行序列化。有一個(gè)Externalizable接口需要用戶手動(dòng)序列化處理。
由于默認(rèn)情況Serializable會(huì)將對(duì)象中的所有屬性進(jìn)行保存,但是如果現(xiàn)在有某些屬性不希望被保存了,那么可以使用transient關(guān)鍵字。
使用transient
package com.day15.demo; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.Serializable; import java.util.Arrays; class Person implements Serializable{ private transient String name; private int age; public Person(String name, int age) { this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override public String toString() { return "Person [name=" + name + ", age=" + age + "]"; } } public class SerializableDemo{ public static final File FILE = new File("F:" + File.separator + "test" + File.separator + "person.txt"); public static void ser(Object o) throws Exception { ObjectOutputStream outputStream = new ObjectOutputStream(new FileOutputStream(FILE)); outputStream.writeObject(o); outputStream.close(); } public static void dser() throws Exception { ObjectInputStream inputStream = new ObjectInputStream(new FileInputStream(FILE)); System.out.println(inputStream.readObject()); inputStream.close(); } public static void main(String[] args) throws Exception{ ser(new Person("張麻子",20)); dser(); } } /* Person [name=null, age=20] */
發(fā)現(xiàn)此處name沒(méi)有進(jìn)行序列化操作。使用序列化往往在簡(jiǎn)單java類(lèi)上使用,其他類(lèi)上使用序列化的使用很少,但是在簡(jiǎn)單java類(lèi)中基本上不去使用transient。
到此這篇關(guān)于Day15基礎(chǔ)不牢地動(dòng)山搖-Java基礎(chǔ)的文章就介紹到這了,更多相關(guān)Java基礎(chǔ)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Spring Boot監(jiān)聽(tīng)Redis Key失效事件實(shí)現(xiàn)定時(shí)任務(wù)的示例
這篇文章主要介紹了Spring Boot監(jiān)聽(tīng)Redis Key失效事件實(shí)現(xiàn)定時(shí)任務(wù)的示例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-04-04java并發(fā)編程專(zhuān)題(一)----線程基礎(chǔ)知識(shí)
這篇文章主要介紹了java并發(fā)編程線程的基礎(chǔ)知識(shí),文中講解非常詳細(xì),幫助大家更好的學(xué)習(xí)JAVA并發(fā)編程,感興趣想學(xué)習(xí)JAVA的可以了解下2020-06-06如何解決Maven依賴無(wú)法導(dǎo)入的問(wèn)題
本文介紹了如何通過(guò)在setting.xml中配置倉(cāng)庫(kù)坐標(biāo)和在IntelliJ IDEA中進(jìn)行相關(guān)設(shè)置來(lái)提高M(jìn)aven下載Jar包的速度,首先在setting.xml中找到mirrors標(biāo)簽進(jìn)行配置,然后在IntelliJ IDEA的設(shè)置中輸入特定的命令2024-10-10Java不指定長(zhǎng)度的二維數(shù)組實(shí)例
今天小編就為大家分享一篇Java不指定長(zhǎng)度的二維數(shù)組實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-07-07一文學(xué)會(huì)處理SpringBoot統(tǒng)一返回格式
這篇文章主要介紹了一文學(xué)會(huì)處理SpringBoot統(tǒng)一返回格式,文章圍繞主題展開(kāi)詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的小伙伴可以參考一下2022-08-08Spring Cloud Feign的文件上傳實(shí)現(xiàn)的示例代碼
這篇文章主要介紹了Spring Cloud Feign的文件上傳實(shí)現(xiàn)的示例代碼,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-03-03java實(shí)現(xiàn)發(fā)送email小案例
這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)發(fā)送email小案例,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-02-02深入Parquet文件格式設(shè)計(jì)原理及實(shí)現(xiàn)細(xì)節(jié)
這篇文章主要介紹了深入Parquet文件格式設(shè)計(jì)原理及實(shí)現(xiàn)細(xì)節(jié),有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-08-08