item 86 Sijun - JAVA-JIKIMI/EFFECTIVE-JAVA3 GitHub Wiki

[์•„์ดํ…œ 86] Serializable์„ ๊ตฌํ˜„ํ• ์ง€๋Š” ์‹ ์ค‘ํžˆ ๊ฒฐ์ •ํ•˜๋ผ

์ง๋ ฌํ™” ํ•˜๋Š” ๋ฐฉ๋ฒ•

import java.io.Serializable;

public class Student implements Serializable{

	String name;
	int grade;
	
}
  • Serializable๋งŒ ๊ตฌํ˜„ํ•˜๋ฉด ๋œ๋‹ค. ๋„ˆ๋ฌด ์‰ฝ๊ฒŒ ์ ์šฉํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ํ”„๋กœ๊ทธ๋ž˜๋จธ๊ฐ€ ํŠน๋ณ„ํžˆ ์‹ ๊ฒฝ ์“ธ ๊ฒŒ ์—†๋‹ค๋Š” ์˜คํ•ด๊ฐ€ ์ƒ๊ธธ ์ˆ˜ ์žˆ์ง€๋งŒ, ์ง„์‹ค์€ ํ›จ์”ฌ ๋” ๋ณต์žกํ•˜๋‹ค. ์ง๋ ฌํ™”๋ฅผ ์ง€์›ํ•˜๊ธฐ๋ž€ ์งง๊ฒŒ ๋ณด๋ฉด ์†์‰ฌ์›Œ ๋ณด์ด์ง€๋งŒ, ๊ธธ๊ฒŒ ๋ณด๋ฉด ์•„์ฃผ ๊ฐ’๋น„์‹ผ ์ผ์ด๋‹ค.

์ง๋ ฌํ™”์— ์‹ ์ค‘ํ•ด์•ผ ํ•˜๋Š” ์ด์œ 

  1. ๋ฆด๋ฆฌ์Šคํ•œ ๋’ค์—๋Š” ์ˆ˜์ •ํ•˜๊ธฐ ์–ด๋ ต๋‹ค.

    ์ง๋ ฌํ™”ํ•˜๊ฒŒ ๋˜๋ฉด, ์ง๋ ฌํ™”๋œ ๋ฐ”์ดํŠธ ์ŠคํŠธ๋ฆผ ์ธ์ฝ”๋”ฉ๋„ ํ•˜๋‚˜์˜ ๊ณต๊ฐœ API๊ฐ€ ๋œ๋‹ค. ๊ทธ๋ž˜์„œ ์ด ํด๋ž˜์Šค๊ฐ€ ๋„๋ฆฌ ํผ์ง„๋‹ค๋ฉด ๊ทธ ์ง๋ ฌํ™” ํ˜•ํƒœ๋„ ์˜์›ํžˆ ์ง€์›ํ•ด์•ผ ํ•œ๋‹ค.

    private๊ณผ package-private ์ธ์Šคํ„ด์Šค ํ•„๋“œ๋“ค๋งˆ์ € API๋กœ ๊ณต๊ฐœ๋˜์–ด ์บก์Šํ™”๊ฐ€ ๊นจ์ง€๊ฒŒ ๋œ๋‹ค. private์„ ํฌํ•จํ•œ ๋‚ด๋ถ€ ๊ตฌ์กฐ๊ฐ€ ๋ณ€๊ฒฝ๋˜๋ฉด, ์ง๋ ฌํ™” ํ˜•ํƒœ๋„ ๋‹ฌ๋ผ์ง„๋‹ค. ๊ตฌ ๋ฒ„์ „ ์ธ์Šคํ„ด์Šค๋ฅผ ์ง๋ ฌํ™”ํ•˜๊ณ  ๋‹ค๋ฅธ ์ชฝ์€ ์‹ ๋ฒ„์ „ ํด๋ž˜์Šค๋กœ ์—ญ์ง๋ ฌํ™”ํ•œ๋‹ค๋ฉด ์‹คํŒจํ•˜๊ฒŒ ๋œ๋‹ค.

    ex) Student class์— ์ƒˆ๋กœ์šด field๊ฐ€ ์ถ”๊ฐ€ ๋˜๋ฉด ์ง๋ ฌํ™” ํ˜•ํƒœ๋„ ๋‹ฌ๋ผ์ง€๊ฒŒ ๋˜๋Š” ๊ฒƒ

  2. ๋ฒ„๊ทธ์™€ ๋ณด์•ˆ ๊ตฌ๋ฉ์ด ์ƒ๊ธธ ์œ„ํ—˜์ด ๋†’์•„์ง„๋‹ค.

    ๊ฐ์ฒด๋Š” ์ƒ์„ฑ์ž๋ฅผ ์‚ฌ์šฉํ•ด ๋งŒ๋“œ๋Š” ๊ฒƒ์ด ๊ธฐ๋ณธ์ด๋‹ค. ์—ญ์ง๋ ฌํ™”๋„ ๊ฐ์ฒด ์ƒ์„ฑ ๊ธฐ๋ฒ•์ด๊ธฐ์— ๋ถˆ๋ณ€์‹์„ ๋ชจ๋‘ ๋ณด์žฅํ•ด์•ผ ํ•˜๊ณ  ์ƒ์„ฑ ๋„์ค‘ ๊ณต๊ฒฉ์ž๊ฐ€ ๊ฐ์ฒด ๋‚ด๋ถ€๋ฅผ ๋“ค์—ฌ๋ณผ ์ˆ˜ ์—†๋„๋ก ํ•ด์•ผ ํ•˜๋ฉฐ, ๊ธฐ๋ณธ ์—ญ์ง๋ ฌํ™”๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋ถˆ๋ณ€์‹ ๊นจ์ง๊ณผ ํ—ˆ๊ฐ€๋˜์ง€ ์•Š์€ ์ ‘๊ทผ์— ์‰ฝ๊ฒŒ ๋…ธ์ถœ๋˜๊ฒŒ ๋œ๋‹ค. (์•„์ดํ…œ 88)

  3. ํ•ด๋‹น ํด๋ž˜์Šค์˜ ์‹ ๋ฒ„์ „์„ ๋ฆด๋ฆฌ์Šคํ•  ๋•Œ ํ…Œ์ŠคํŠธํ•  ๊ฒƒ์ด ๋Š˜์–ด๋‚œ๋‹ค.

    ์ง๋ ฌํ™” ๊ฐ€๋Šฅ ํด๋ž˜์Šค๊ฐ€ ์ˆ˜์ •๋˜๋ฉด ์‹ ๋ฒ„์ „ ์ธ์Šคํ„ด์Šค๋ฅผ ์ง๋ ฌํ™”ํ•œ ํ›„ ๊ตฌ๋ฒ„์ „์œผ๋กœ ์—ญ์ง๋ ฌํ™”ํ•  ์ˆ˜ ์žˆ๋Š”์ง€, ๊ทธ๋ฆฌ๊ณ  ๊ทธ ๋ฐ˜๋Œ€๋„ ๊ฐ€๋Šฅํ•œ์ง€๋ฅผ ๊ฒ€์‚ฌํ•ด์•ผ ํ•œ๋‹ค.

    ๋˜ํ•œ, ๊ฐ์ฒด๋ฅผ ์ถฉ์‹คํžˆ ๋ณต์ œํ•ด๋‚ด๋Š”์ง€๋ฅผ ๋ฐ˜๋“œ์‹œ ํ™•์ธํ•ด์•ผ ํ•œ๋‹ค.

์ง๋ ฌํ™” ์˜ˆ์‹œ

Serializable ๊ตฌํ˜„์— ๋”ฐ๋ฅด๋Š” ๋น„์šฉ์ด ์ ์ง€ ์•Š์œผ๋‹ˆ, ํด๋ž˜์Šค๋ฅผ ์„ค๊ณ„ํ•  ๋•Œ๋งˆ๋‹ค ๊ทธ ์ด๋“๊ณผ ๋น„์šฉ์„ ์ž˜ ์ €์šธ์งˆํ•ด์•ผ ํ•œ๋‹ค.

์—ญ์‚ฌ์ ์œผ๋กœ BigInteger์™€ Instance ๊ฐ™์€ '๊ฐ’'ํด๋ž˜์Šค์™€ ์ปฌ๋ ‰์…˜ ํด๋ž˜์Šค๋“ค์€ Serializable์„ ๊ตฌํ˜„ํ•˜๊ณ , ์Šค๋ ˆ๋“œ ํ’€์ฒ˜๋Ÿผ '๋™์ž‘'ํ•˜๋Š” ๊ฐ์ฒด๋ฅผ ํ‘œํ˜„ํ•˜๋Š” ํด๋ž˜์Šค๋“ค์€ ๋Œ€๋ถ€๋ถ„ Serializable์„ ๊ตฌํ˜„ํ•˜์ง€ ์•Š์•˜๋‹ค.

์ƒ์†์šฉ์œผ๋กœ ์„ค๊ณ„๋œ ํด๋ž˜์Šค๋Š” ๋Œ€๋ถ€๋ถ„ Serializable์„ ๊ตฌํ˜„ํ•˜๋ฉด ์•ˆ ๋˜๋ฉฐ, ์ธํ„ฐํŽ˜์ด์Šค๋„ ๋Œ€๋ถ€๋ถ„ Serializable์„ ํ™•์žฅํ•ด์„œ๋Š” ์•ˆ ๋œ๋‹ค. ์ด ๊ทœ์น™์„ ๋”ฐ๋ฅด์ง€ ์•Š์œผ๋ฉด, ๊ทธ๋Ÿฐ ํด๋ž˜์Šค๋ฅผ ํ™•์žฅํ•˜๊ฑฐ๋‚˜ ๊ทธ๋Ÿฐ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ตฌํ˜„ํ•˜๋Š” ์ด์—๊ฒŒ ์ปค๋‹ค๋ž€ ๋ถ€๋‹ด์„ ์ง€์šฐ๊ฒŒ ๋œ๋‹ค.

์ƒ์†์šฉ์œผ๋กœ ์„ค๊ณ„๋œ ํด๋ž˜์Šค ์ค‘ Serializable์„ ๊ตฌํ˜„ํ•œ ์˜ˆ๋กœ๋Š” Throwable๊ณผ Component๊ฐ€ ์žˆ๋‹ค. Throwable์€ ์„œ๋ฒ„๊ฐ€ RMI๋ฅผ ํ†ตํ•ด ํด๋ผ์ด์–ธํŠธ๋กœ ์˜ˆ์™ธ๋ฅผ ๋ณด๋‚ด๊ธฐ ์œ„ํ•ด Serializable์„ ๊ตฌํ˜„ํ–ˆ๋‹ค. Component๋Š” GUI๋ฅผ ์ „์†กํ•˜๊ณ  ์ €์žฅํ•˜๊ณ  ๋ณต์›ํ•˜๊ธฐ ์œ„ํ•ด Serializable์„ ๊ตฌํ˜„ํ–ˆ์ง€๋งŒ, Swing๊ณผ AWT๊ฐ€ ๋„๋ฆฌ ์“ฐ์ด๋˜ ์‹œ์ ˆ์—๋„ ํ˜„์—…์—์„œ ์ด๋Ÿฐ ์šฉ๋„๋กœ๋Š” ๊ฑฐ์˜ ์“ฐ์ด์ง€ ์•Š์•˜๋‹ค.

์ง๋ ฌํ™”์™€ ํ™•์žฅ์ด ๊ฐ€๋Šฅํ•œ ๊ฒฝ์šฐ ์ฃผ์˜ํ•  ์ 

  1. ์ธ์Šคํ„ด์Šค ํ•„๋“œ ๊ฐ’ ์ค‘ ๋ถˆ๋ณ€์‹์„ ๋ณด์žฅํ•ด์•ผ ํ•  ๊ฒŒ ์žˆ๋‹ค๋ฉด ๋ฐ˜๋“œ์‹œ ํ•˜์œ„ ํด๋ž˜์Šค์—์„œ finalize ๋ฉ”์„œ๋“œ๋ฅผ ์žฌ์ •์˜ํ•˜์ง€ ๋ชปํ•˜๊ฒŒ ํ•ด์•ผ ํ•œ๋‹ค. ์ฆ‰, finalize ๋ฉ”์„œ๋“œ๋ฅผ ์ž์‹ ์ด ์žฌ์ •์˜ํ•˜๋ฉด์„œ final๋กœ ์„ ์–ธํ•˜๋ฉด ๋œ๋‹ค. ์ด๋ ‡๊ฒŒ ํ•ด๋‘์ง€ ์•Š์œผ๋ฉด finalizer ๊ณต๊ฒฉ์„ ๋‹นํ•  ์ˆ˜ ์žˆ๋‹ค.

  2. ์ธ์Šคํ„ด์Šค ํ•„๋“œ ์ค‘ ๊ธฐ๋ณธ๊ฐ’์œผ๋กœ ์ดˆ๊ธฐํ™”๋˜๋ฉด ์œ„๋ฐฐ๋˜๋Š” ๋ถˆ๋ณ€์‹์ด ์žˆ๋‹ค๋ฉด ํด๋ž˜์Šค์— ๋‹ค์Œ์˜ readObjectNoData ๋ฉ”์„œ๋“œ๋ฅผ ๋ฐ˜๋“œ์‹œ ์ถ”๊ฐ€ํ•ด์•ผ ํ•œ๋‹ค.

    ์ด ๋ฉ”์„œ๋“œ๋Š” ์ž๋ฐ” 4์— ์ถ”๊ฐ€๋œ ๊ฒƒ์œผ๋กœ, ๊ธฐ์กด์˜ ์ง๋ ฌํ™” ๊ฐ€๋Šฅ ํด๋ž˜์Šค์— ์ง๋ ฌํ™” ๊ฐ€๋Šฅ ์ƒ์œ„ ํด๋ž˜์Šค๋ฅผ ์ถ”๊ฐ€ํ•˜๋Š” ๋“œ๋ฌธ ๊ฒฝ์šฐ๋ฅผ ์œ„ํ•œ ๋ฉ”์„œ๋“œ๋‹ค.

    private void readObjectNoData() throws InvalidObjectException {
    		throw new InvalidObjectException("์ŠคํŠธ๋ฆผ ๋ฐ์ดํ„ฐ๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค");
    }
    

    ์˜ˆ์‹œ ์ฝ”๋“œ)

    ์ง๋ ฌํ™” ํ•  ๋•Œ ์ฝ”๋“œ

    public class Employee implements Serializable {
    	protected String address;
    	static final long serialVersionUID = 1L;
    
    	public Employee(){
    		address ="sample address";
    	}
    }
    

    ์ง๋ ฌํ™” ํ›„ ์ˆ˜์ •๋œ ์ฝ”๋“œ

    public class Employee extends Person implements Serializable {
    	protected String address;
    	static final long serialVersionUID = 1L;
    
    	public Employee(){
    		address ="sample address";
    	}
    }
    
    public class Person implements Serializable{
    
    	String name;
    	int age;
    	
    	public Person() {
    		
    	}
    	
    	public Person(String name, int age) {
    		this.name = name;
    		this.age = age;
    	}
    
    	private void readObjectNoData() throws ObjectStreamException {
    		name = "test";
    		age = 1;
    	}
    	
    }
    
  3. ๋‚ด๋ถ€ ํด๋ž˜์Šค๋Š” ์ง๋ ฌํ™”๋ฅผ ๊ตฌํ˜„ํ•˜์ง€ ๋ง์•„์•ผ ํ•œ๋‹ค. ๋‹จ, ์ •์  ๋ฉค๋ฒ„ ํด๋ž˜์Šค๋Š” Serializable์„ ๊ตฌํ˜„ํ•ด๋„ ๋œ๋‹ค.

    Java.io.NotSerializableException์ด ๋ฐœ์ƒํ•˜๊ฒŒ ๋œ๋‹ค. Outer class์˜ ์ธ์Šคํ„ด์Šค์— ๋Œ€ํ•œ ์ •์˜๊ฐ€ ๋ถˆ๋ช…ํ™•ํ•˜๊ธฐ ๋•Œ๋ฌธ์ธ ๊ฒƒ์ด๋ผ ํŒ๋‹จ๋œ๋‹ค.

ํ•ต์‹ฌ ์ •๋ฆฌ

Serializable์€ ๊ตฌํ˜„ํ•œ๋‹ค๊ณ  ์„ ์–ธํ•˜๊ธฐ๋Š” ์•„์ฃผ ์‰ฝ์ง€๋งŒ, ๊ทธ๊ฒƒ์€ ๋ˆˆ์†์ž„์ผ ๋ฟ์ด๋‹ค. ํ•œ ํด๋ž˜์Šค์˜ ์—ฌ๋Ÿฌ ๋ฒ„์ „์ด ์ƒํ˜ธ์ž‘์šฉํ•  ์ผ์ด ์—†๊ณ  ์„œ๋ฒ„๊ฐ€ ์‹ ๋ขฐํ•  ์ˆ˜ ์—†๋Š” ๋ฐ์ดํ„ฐ์— ๋…ธ์ถœ๋  ๊ฐ€๋Šฅ์„ฑ์ด ์—†๋Š” ๋“ฑ, ๋ณดํ˜ธ๋œ ํ™˜๊ฒฝ์—์„œ๋งŒ ์“ฐ์ผ ํด๋ž˜์Šค๊ฐ€ ์•„๋‹ˆ๋ผ๋ฉด Serializable ๊ตฌํ˜„์€ ์•„์ฃผ ์‹ ์ค‘ํ•˜๊ฒŒ ์ด๋ค„์ ธ์•ผ ํ•œ๋‹ค. ์ƒ์†ํ•  ์ˆ˜ ์žˆ๋Š” ํด๋ž˜์Šค๋ผ๋ฉด ์ฃผ์˜์‚ฌํ•ญ์ด ๋”์šฑ ๋งŽ์•„์ง„๋‹ค.