欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java基礎(chǔ)字符編碼與內(nèi)存流詳細(xì)解讀

 更新時(shí)間:2021年08月23日 16:35:52   作者:zsr6135  
這篇文章主要給大家介紹了關(guān)于Java中方法使用的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(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)系。

image-20210819132612577

對(duì)于內(nèi)存操作流也分為兩組:

**字節(jié)內(nèi)存操作流:**內(nèi)存輸入流(ByteArrayInputStream)內(nèi)存輸出流(ByteArrayOutputStream)

**字符內(nèi)存操作流:**內(nèi)存輸入流(CharArrayReader)內(nèi)存輸出流(CharArrayWriter)

image-20210819132728511

ByteArrayInputStream ByteArrayOutputStreamjava.lang.Object java.io.InputStream java.io.ByteArrayInputStreamjava.lang.Object java.io.OutputStream java.io.ByteArrayOutputStreampublic ByteArrayInputStream(byte[] buf)public ByteArrayOutputStream()

輸出流

image-20210819133020134

輸入流

image-20210819133247011

通過(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)

image-20210819145012602

看見(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è)操作的常量。

image-20210819183205994

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)。

image-20210819191629741

使用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

image-20210819210231615

image-20210819210310589

實(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)文章

最新評(píng)論