item 17 leekyunghee - JAVA-JIKIMI/EFFECTIVE-JAVA3 GitHub Wiki

๋ณ€๊ฒฝ ๊ฐ€๋Šฅ์„ฑ์„ ์ตœ์†Œํ™”ํ•˜๋ผ

  • ๋ถˆ๋ณ€ ํด๋ž˜์Šค

์ธ์Šคํ„ด์Šค์˜ ๋‚ด๋ถ€ ๊ฐ’์„ ์ˆ˜์ •ํ•  ์ˆ˜ ์—†๋Š” ํด๋ž˜์Šค

String, ๊ธฐ๋ณธ ํƒ€์ž…์˜ ๋ฐ•์‹ฑ๋œ ํด๋ž˜์Šค, BigInteger, BicDecimal

ํด๋ž˜์Šค๋ฅผ ๋ถˆ๋ณ€์œผ๋กœ ๋งŒ๋“ค๊ธฐ ์œ„ํ•œ ๋‹ค์„ฏ ๊ฐ€์ง€ ๊ทœ์น™

  • ๊ฐ์ฒด์˜ ์ƒํƒœ๋ฅผ ๋ณ€๊ฒฝํ•˜๋Š” ๋ฉ”์„œ๋“œ(๋ณ€๊ฒฝ์ž)๋ฅผ ์ œ๊ณตํ•˜์ง€ ์•Š๋Š”๋‹ค.
  • ํด๋ž˜์Šค๋ฅผ ํ™•์žฅํ•  ์ˆ˜ ์—†๋„๋ก ํ•œ๋‹ค.
  • ์ƒ์†์„ ๋ง‰๋Š” final๋กœ ์„ ์–ธ
  • ๋ชจ๋“  ํ•„๋“œ๋ฅผ final๋กœ ์„ ์–ธํ•œ๋‹ค.
  • ์ƒˆ๋กœ ์ƒ์„ฑ๋œ ์ธ์Šคํ„ด์Šค๋ฅผ ๋™๊ธฐํ™” ์—†์ด ๋‹ค๋ฅธ ์Šค๋ ˆ๋“œ๋กœ ๊ฑด๋„ค๋„ ๋ฌธ์ œ์—†์ด ๋™์ž‘ํ•˜๊ฒŒ๋” ๋ณด์žฅํ•˜๋Š” ๋ฐ๋„ ํ•„์š”ํ•˜๋‹ค. - ์ž๋ฐ” ์–ธ์–ด ๋ช…์„ธ์˜ ๋ฉ”๋ชจ๋ฆฌ ๋ชจ๋ธ ๋ถ€๋ถ„ ์ฐธ๊ณ 
  • ๋ชจ๋“  ํ•„๋“œ๋ฅผ private์œผ๋กœ ์„ ์–ธํ•œ๋‹ค.
  • ํ•„๋“œ๊ฐ€ ์ฐธ์กฐํ•˜๋Š” ๊ฐ€๋ณ€ ๊ฐ์ฒด๋ฅผ ํด๋ผ์ด์–ธํŠธ์—์„œ ์ง์ ‘ ์ ‘๊ทผํ•ด ์ˆ˜์ •ํ•˜๋Š” ์ผ์„ ๋ง‰์•„์ค€๋‹ค.
  • ๊ธฐ์ˆ ์ ์œผ๋กœ๋Š” ๊ธฐ๋ณธ ํƒ€์ž… ํ•„๋“œ๋‚˜ ๋ถˆ๋ณ€ ๊ฐ์ฒด๋ฅผ ์ฐธ์กฐํ•˜๋Š” ํ•„๋“œ๋ฅผ Public final๋กœ๋งŒ ์„ ์–ธํ•ด๋„ ๋ถˆ๋ณ€ ๊ฐ์ฒด๊ฐ€ ๋˜์ง€๋งŒ ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ๋‹ค์Œ์— ๋‚ด๋ถ€ ํ‘œํ˜„์„ ๋ฐ”๊พธ์ง€ ๋ชปํ•˜๋ฏ€๋กœ ๊ถŒํ•˜์ง€ ์•Š์Œ(์•„์ดํ…œ 15, 16)
  • ์ž์‹  ์™ธ์—๋Š” ๋‚ด๋ถ€์˜ ๊ฐ€๋ณ€ ์ปดํฌ๋„ŒํŠธ์— ์ ‘๊ทผํ•  ์ˆ˜ ์—†๋„๋ก ํ•œ๋‹ค.
  • ํด๋ž˜์Šค์— ๊ฐ€๋ณ€ ๊ฐ์ฒด๋ฅผ ์ฐธ์กฐํ•˜๋Š” ํ•„๋“œ๊ฐ€ ํ•˜๋‚˜๋ผ๋„ ์žˆ๋‹ค๋ฉด ํด๋ผ์ด์–ธํŠธ์—์„œ ๊ทธ ๊ฐ์ฒด์˜ ์ฐธ์กฐ๋ฅผ ์–ป์„ ์ˆ˜ ์—†๋„๋ก ํ•ด์•ผ ํ•œ๋‹ค.
  • ์ƒ์„ฑ์ž, ์ ‘๊ทผ์ž readObject ๋ฉ”์„œ๋“œ(์•„์ดํ…œ 88) ๋ชจ๋‘์—์„œ ๋ฐฉ์–ด์  ๋ณต์‚ฌ๋ฅผ ์ˆ˜ํ–‰ํ•˜๋ผ.
๋ถˆ๋ณ€ ๋ณต์†Œ์ˆ˜ ํด๋ž˜์Šค 
public final class Complex {
    private final double re;
    private final double im;

    public static final Complex ZERO = new Complex(0, 0);
    public static final Complex ONE  = new Complex(1, 0);
    public static final Complex I    = new Complex(0, 1);

    public Complex(double re, double im) {
        this.re = re;
        this.im = im;
    }

    // ์‹ค์ˆ˜๋ถ€์™€ ํ—ˆ์ˆ˜๋ถ€ ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•˜๋Š” ์ ‘๊ทผ์ž ๋ฉ”์„œ๋“œ 
    public double realPart()      { return re; }
    public double imaginaryPart() { return im; }

    // ์‚ฌ์น™์—ฐ์‚ฐ ๋ฉ”์„œ๋“œ (plus, minus, times, dividedBy) 
    // plus ๋ผ๋Š” ๋ฉ”์„œ๋“œ ์ด๋ฆ„ - ๊ฐ์ฒด์˜ ๊ฐ’์„ ๋ณ€๊ฒฝํ•˜์ง€ ์•Š๋Š”๋‹ค๋Š” ์˜๋„ 
    public Complex plus(Complex c) {
        return new Complex(re + c.re, im + c.im);
    }

    public Complex minus(Complex c) {
        return new Complex(re - c.re, im - c.im);
    }

    public Complex times(Complex c) {
        return new Complex(re * c.re - im * c.im,
                re * c.im + im * c.re);
    }

    public Complex dividedBy(Complex c) {
        double tmp = c.re * c.re + c.im * c.im;
        return new Complex((re * c.re + im * c.im) / tmp,
                (im * c.re - re * c.im) / tmp);
    }

    @Override public boolean equals(Object o) {
        if (o == this)
            return true;
        if (!(o instanceof Complex))
            return false;
        Complex c = (Complex) o;

        // == ๋Œ€์‹  compare๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์ด์œ ๋Š” 63์ชฝ์„ ํ™•์ธํ•˜๋ผ.
        return Double.compare(c.re, re) == 0
                && Double.compare(c.im, im) == 0;
    }
    @Override public int hashCode() {
        return 31 * Double.hashCode(re) + Double.hashCode(im);
    }

    @Override public String toString() {
        return "(" + re + " + " + im + "i)";
    }
}
  • ์‚ฌ์น™์—ฐ์‚ฐ ๋ฉ”์„œ๋“œ๋“ค์ด ์ธ์Šคํ„ด์Šค ์ž์‹ ์€ ์ˆ˜์ •ํ•˜์ง€ ์•Š๊ณ  ์ƒˆ๋กœ์šด Complex ์ธ์Šคํ„ด์Šค๋ฅผ ๋งŒ๋“ค์–ด ๋ฐ˜ํ™˜ํ•˜๋Š” ๋ชจ์Šต์— ์ฃผ๋ชฉ
  • ํ•จ์ˆ˜ํ˜• ํ”„๋กœ๊ทธ๋ž˜๋ฐ

์ด์ฒ˜๋Ÿผ ํ”ผ ์—ฐ์‚ฐ์ž์— ํ•จ์ˆ˜๋ฅผ ์ ์šฉํ•ด ๊ทธ ๊ฒฐ๊ณผ๋ฅผ ๋ฐ˜ํ™˜ํ•˜์ง€๋งŒ ํ”ผ์—ฐ์‚ฐ์ž ์ž์ฒด๋Š” ๊ทธ๋Œ€๋กœ์ธ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ํŒจํ„ด

๋ถˆ๋ณ€ ๊ฐ์ฒด๋Š” ๋‹จ์ˆœํ•˜๋‹ค.

๋ถˆ๋ณ€ ๊ฐ์ฒด๋Š” ๊ทผ๋ณธ์ ์œผ๋กœ ์Šค๋ ˆ๋“œ ์•ˆ์ „ํ•˜์—ฌ ๋”ฐ๋กœ ๋™๊ธฐํ™”ํ•  ํ•„์š” ์—†๋‹ค.

์—ฌ๋Ÿฌ ์Šค๋ ˆ๋“œ๊ฐ€ ๋™์‹œ์— ์‚ฌ์šฉํ•ด๋„ ์ ˆ๋Œ€ ํ›ผ์†๋˜์ง€ ์•Š๋Š”๋‹ค.

  • ๋ถˆ๋ณ€ ๊ฐ์ฒด์— ๋Œ€ํ•ด์„œ๋Š” ๊ทธ ์–ด๋–ค ์Šค๋ ˆ๋“œ๋„ ๋‹ค๋ฅธ ์Šค๋ ˆ๋“œ์— ์˜ํ–ฅ์„ ์ค„ ์ˆ˜ ์—†์œผ๋‹ˆ ๋ถˆ๋ณ€ ๊ฐ์ฒด๋Š” ์•ˆ์‹ฌํ•˜๊ณ  ๊ณต์œ ํ•  ์ˆ˜ ์žˆ๋‹ค.
public static final Complex ZERO = new Complex(0,0);
public static final Complex ONE = new Complex(1,0);
public static final Complex I = new Complex(0,1);

// ๋ถˆ๋ณ€ ํด๋ž˜์Šค๋Š” ์ž์ฃผ ์‚ฌ์šฉ๋˜๋Š” ์ธ์Šคํ„ด์Šค๋ฅผ ์บ์‹ฑํ•˜์—ฌ ๊ฐ™์€ ์ธ์Šคํ„ด์Šค๋ฅผ ์ค‘๋ณต ์ƒ์„ฑํ•˜์ง€ ์•Š๊ฒŒ ํ•ด์ฃผ๋Š” ์ •์  ํŒฉํ„ฐ๋ฆฌ(์•„์ดํ…œ 1)์„ ์ œ๊ณตํ•  ์ˆ˜ ์žˆ๋‹ค.
// ๋ฐ•์‹ฑ๋œ ๊ธฐ๋ณธ ํƒ€์ž… ํด๋ž˜์Šค ์ „๋ถ€์™€ BigInteger๊ฐ€ ์—ฌ๊ธฐ ์†ํ•œ๋‹ค. 
// ์ •์  ํŒฉํ„ฐ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์—ฌ๋Ÿฌ ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์ธ์Šคํ„ด์Šค๋ฅผ ๊ณต์œ ํ•˜์—ฌ ๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์šฉ๋Ÿ‰๊ณผ ๊ฐ€๋น„์ง€ ์ปฌ๋ ‰์…˜ ๋น„์šฉ์ด ์ค„์–ด๋“ ๋‹ค. 
  • ๋ถˆ๋ณ” ๊ฐ์ฒด๋ฅผ ์ž์œ ๋กญ๊ฒŒ ๊ณต์œ ํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ์ ์€ ๋ฐฉ์–ด์  ๋ณต์‚ฌ(์•„์ดํ…œ 50)๋„ ํ•„์š” ์—†๋‹ค๋Š” ๊ฒฐ๋ก 
  • ๋ณต์‚ฌ๋ฅผ ํ•ด๋„ ์›๋ณธ๊ฐ€ ๋˜‘๊ฐ™์œผ๋‹ˆ ์˜๋ฏธ๊ฐ€ ์—†๋‹ค.
  • clone ๋ฉ”์„œ๋“œ๋‚˜ ๋ณต์‚ฌ ์ƒ์„ฑ์ž(์•„์ดํ…œ 13)์„ ์ œ๊ณตํ•˜์ง€ ์•Š๋Š”๊ฒŒ ์ข‹๋‹ค.
  • String ํด๋ž˜์Šค์˜ ๋ณต์‚ฌ ์ƒ์„ฑ์ž๋Š” ๋˜๋„๋ก ์‚ฌ์šฉํ•˜์ง€ ๋ง์•„์•ผํ•œ๋‹ค. (์•„์ดํ…œ 6)

๋ถˆ๋ณ€ ๊ฐ์ฒด๋Š” Set์˜ ์›์†Œ๋กœ ์“ฐ๊ธฐ์— ์•ˆ์„ฑ๋งž์ถค

๋ถˆ๋ณ€ ๊ฐ์ฒด์˜ ๋‹จ์ 

  • ๊ฐ’์ด ๋‹ค๋ฅด๋ฉด ๋ฐ˜๋“œ์‹œ ๋…๋ฆฝ๋œ ๊ฐ์ฒด๋กœ ๋งŒ๋“ค์–ด์•ผ ํ•œ๋‹ค.
BigInteger moby = ...;
moby = moby.flipBit(0);

// BigInteger์—์„œ ๋น„ํŠธ ํ•˜๋‚˜๋ฅผ ๋ฐ”๊ฟ”์•ผ ํ•œ๋‹ค๊ณ  ํ•  ๊ฒฝ์šฐ 
BitSet moby = ...;
moby = moby.flip(0);

// BitSet์€ ๊ฐ€๋ณ€์ด๋‹ค. ์›ํ•˜๋Š” ๋น„ํŠธ ํ•˜๋‚˜๋งŒ ์ƒ์ˆ˜ ์‹œ๊ฐ„์•ˆ์— ๋ฐ”๊ฟ”์ฃผ๋Š” ๋ฉ”์†Œ๋“œ๋ฅผ ์ œ๊ณต 

๋‹ค๋‹จ๊ณ„ ์—ฐ์‚ฐ๋“ค์„ ์˜ˆ์ธกํ•˜์—ฌ ๊ธฐ๋ณธ ๊ธฐ๋Šฅ์œผ๋กœ ์ œ๊ณต

  • String์˜ ๊ฐ€๋ณ€ ๋™๋ฐ˜ ํด๋ž˜์Šค - StringBuilder, StringBuffer

๋ถˆ๋ณ€ ํด๋ž˜์Šค๋ฅผ ๋งŒ๋“œ๋Š” ์„ค๊ณ„ ๋ฐฉ๋ฒ•

  • ๋ชจ๋“  ์ƒ์„ฑ์ž๋ฅผ private ํ˜น์€ package-private์œผ๋กœ ๋งŒ๋“ค๊ณ  public ์ •์  ํŒฉํƒ€๋ฆฌ๋ฅผ ์ œ๊ณตํ•˜๋Š” ๋ฐฉ๋ฒ•
public final class Complex {
    private final double re;
    private final double im;


    **private** Complex(double re, double im) {
        this.re = re;
        this.im = im;
    }
 // ์ฝ”๋“œ 17-2 ์ •์  ํŒฉํ„ฐ๋ฆฌ(private ์ƒ์„ฑ์ž์™€ ํ•จ๊ป˜ ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹ค.) (110-111์ชฝ)
    public static Complex valueOf(double re, double im) {
        return new Complex(re, im);
    }
}

// ํŒจํ‚ค์ง€ ๋ฐ”๊นฅ์˜ ํด๋ผ์ด์–ธํŠธ์—์„œ ๋ฐ”๋ผ๋ณธ ์ด ๋ถˆ๋ณ€ ๊ฐ์ฒด๋Š” ์‚ฌ์‹ค์ƒ final์ด๋‹ค. 
// ์ •์  ํŒฉํ„ฐ๋ฆฌ ๋ฐฉ์‹์€ ๋‹ค์ˆ˜์˜ ๊ตฌํ˜„ ํด๋ž˜์Šค๋ฅผ ํ™œ์šฉํ•œ ์œ ์—ฐ์„ฑ์„ ์ œ๊ณตํ•˜๊ณ  ๊ฐ์ฒด ์บ์‹ฑ ๊ธฐ๋Šฅ์„ ์ถ”๊ฐ€ํ•ด ์„ฑ๋Šฅ์„ ๋Œ์–ด์˜ฌ๋ฆด ์ˆ˜๋„ ์žˆ๋‹ค. 

์–ด๋–ค ๋ฉ”์„œ๋“œ๋„ ๊ฐ์ฒด์˜ ์ƒํƒœ์ค‘ ์™ธ๋ถ€์— ๋น„์น˜๋Š” ๊ฐ’์„ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์—†๋‹ค.

ํ•ต์‹ฌ ์ •๋ฆฌ

- getter๊ฐ€ ์žˆ๋‹ค๊ณ  ํ•ด์„œ ๋ฌด์กฐ๊ฑด setter๋ฅผ ๋งŒ๋“ค์ง€๋Š” ๋ง์ž.
- ํด๋ž˜์Šค๋Š” ๊ผญ ํ•„์š”ํ•œ ๊ฒฝ์šฐ๊ฐ€ ์•„๋‹ˆ๋ผ๋ฉด ๋ถˆ๋ณ€์ด์–ด์•ผ ํ•œ๋‹ค. 
- ๋‹จ์ˆœํ•œ ๊ฐ’ ๊ฐ์ฒด๋Š” ํ•ญ์ƒ ๋ถˆ๋ณ€์œผ๋กœ ๋งŒ๋“ค์ž. 
- ์„ฑ๋Šฅ ๋–„๋ฌธ์— ์–ด์ฉ” ์ˆ˜ ์—†๋‹ค๋ฉด ๋ถˆ๋ณ€ ํด๋ž˜์Šค์™€ ์Œ์„ ์ด๋ฃจ๋Š” ๊ฐ€๋ณ€ ๋™๋ฐ˜ ํด๋ž˜์Šค๋ฅผ public ํด๋ž˜์Šค๋กœ ์ œ๊ณตํ•˜๋„๋ก ํ•˜์ž.