Post

[Java] Record

[Java] Record

๐Ÿ“Œ Record๋ž€?

์ž๋ฐ”์˜ Record ๋Š” Java 16์—์„œ ์ •์‹์œผ๋กœ ๋„์ž…๋œ ํŠน๋ณ„ํ•œ ์ข…๋ฅ˜์˜ ํด๋ž˜์Šค์ด๋‹ค. Record์˜ ํ•ต์‹ฌ ๋ชฉ์ ์€ ๋ถˆ๋ณ€ ๋ฐ์ดํ„ฐ๋ฅผ ๋‹ด๋Š” ๊ฐ์ฒด๋ฅผ ๊ฐ„๊ฒฐํ•˜๊ฒŒ ์ž‘์„ฑํ•˜๋Š” ๊ฒƒ์ด๋‹ค.

Record๊ฐ€ ์—†๋˜ ์‹œ์ ˆ

๋ณดํ†ต Record๋Š” DTO์™€ ๊ฐ™์€ ๋ถˆ๋ณ€ ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉํ•œ๋‹ค. ์ด๋ฅผ Record๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ  ์ž‘์„ฑํ•˜๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ๋‹ค.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
public final class Person {

    private final String name;
    private final int age;

    public PersonClass(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        PersonClass that = (PersonClass) o;
        return age == that.age && java.util.Objects.equals(name, that.name);
    }

    @Override
    public int hashCode() {
        return java.util.Objects.hash(name, age);
    }

    @Override
    public String toString() {
        return "PersonClass[" +
               "name='" + name + '\'' +
               ", age=" + age +
               ']';
    }
}

๋จผ์ € ํด๋ž˜์Šค์— final ํ‚ค์›Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ƒ์†์„ ๋ง‰์•„์•ผ ํ•˜๊ณ , ํ•„๋“œ๋ฅผ private final ๋กœ ์„ ์–ธํ•˜๊ณ , ๋ชจ๋“  ํ•„๋“œ๋ฅผ ์ดˆ๊ธฐํ™”ํ•˜๋Š” ์ƒ์„ฑ์ž๋ฅผ ๋งŒ๋“ค๊ณ , getter๋ฅผ ๋งŒ๋“ค๊ณ , hashCode ์™€ equals, toString ๋ฉ”์„œ๋“œ๋ฅผ ๊ตฌํ˜„ํ•ด์•ผ ํ•œ๋‹ค. ์ด์ œ ๋‹ค๋ฅธ ๋ถˆ๋ณ€ ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค์ž. ๋ฐฉ๊ธˆ ์ž‘์„ฑํ•œ ์ฝ”๋“œ๋ฅผ ๋‹ค์‹œ ์ž‘์„ฑํ•˜๊ณ  ์‹ถ์€๊ฐ€? ๊ทธ์ € ๋ถˆ๋ณ€ ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค๊ณ  ์‹ถ์—ˆ์„ ๋ฟ์ธ๋ฐ, ์ˆ˜์‹ญ ์ค„์˜ ์ฝ”๋“œ๋ฅผ ์ผ์ผํžˆ ์ž‘์„ฑํ•ด์•ผ ํ•œ๋‹ค.

@Lombok ์–ด๋…ธํ…Œ์ด์…˜์˜ ๋“ฑ์žฅ ๋ฐฐ๊ฒฝ์„ ๋ณด๋ฉด ์•Œ๊ฒ ์ง€๋งŒ, ๋ณด์ผ๋Ÿฌํ”Œ๋ ˆ์ดํŠธ ์ฝ”๋“œ๋ฅผ ์ง์ ‘ ์ž‘์„ฑํ•˜๋Š” ๊ฒƒ์€ ์–ด๋งˆ๋ฌด์‹œํ•œ ์ƒ์‚ฐ์„ฑ ์ €ํ•˜๋ฅผ ๊ฐ€์ ธ์˜จ๋‹ค.

์ด์ œ, Record๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋‹ค์‹œ ์ž‘์„ฑํ•ด๋ณด์ž.

1
public record Person(String name, int age) {}

๋†€๋ผ์šธ ์ •๋„๋กœ ๊ฐ„๋‹จํ•ด์ง„๋‹ค. Record๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์ด์ „์— ์ž‘์„ฑํ•œ private final ํ•„๋“œ์™€ ์ƒ์„ฑ์ž, getter, equals, hashCode, toString ๋ฉ”์„œ๋“œ๋ฅผ ์ž๋ฐ” ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ ์ปดํŒŒ์ผ ์‹œ์ ์— ์ž๋™์œผ๋กœ ์ƒ์„ฑํ•ด์ค€๋‹ค.

๐Ÿ“Œ ์ปดํŒฉํŠธ ์ƒ์„ฑ์ž

Record๋งŒ์˜ ํŠน๋ณ„ํ•œ ๊ธฐ๋Šฅ์ด ์žˆ๋Š”๋ฐ, ์ปดํŒฉํŠธ ์ƒ์„ฑ์ž์ด๋‹ค.

์ปดํŒฉํŠธ ์ƒ์„ฑ์ž๋Š” Record๊ฐ€ ์ž๋™์œผ๋กœ ์ƒ์„ฑํ•˜๋Š” ์ƒ์„ฑ์ž์— ๊ฒ€์ฆ, ๊ธฐ๋ณธ ๊ฐ’ ํ• ๋‹น ๋“ฑ๊ณผ ๊ฐ™์€ ๋กœ์ง์„ ๊ฐ„๋‹จํ•˜๊ฒŒ ์ถ”๊ฐ€ํ•˜๊ธฐ ์œ„ํ•ด ๋“ฑ์žฅํ•œ ๊ฐœ๋…์ด๋‹ค. Record๊ฐ€ ๋ชจ๋“  ํ•„๋“œ๋ฅผ ์ธ์ž๋กœ ๋ฐ›์•„ ์ดˆ๊ธฐํ™”ํ•˜๋Š” ์ƒ์„ฑ์ž๋ฅผ ๋งŒ๋“ค๊ธฐ ์ „์— ๋™์ž‘ํ•œ๋‹ค.

1
2
3
4
5
public Person {
    if (age < 0) {
        throw new IllegalArgumentException("๋‚˜์ด๋Š” ์Œ์ˆ˜์ผ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.");
    }
}

์—ฌํƒ€ ์ƒ์„ฑ์ž์™€ ๊ฐ€์žฅ ํฐ ํŠน์ง•์€ ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ๋ฐ›๋Š” ์†Œ๊ด„ํ˜ธ๊ฐ€ ์—†๋‹ค๋Š” ๊ฒƒ์ด๋‹ค. ์•”๋ฌต์ ์œผ๋กœ Record์— ์ •์˜๋œ ๋ชจ๋“  ํ•„๋“œ๋ฅผ ๋ฐ›๋Š”๋‹ค. ์ปดํŒฉํŠธ ์ƒ์„ฑ์ž ๋‚ด๋ถ€์—์„œ ์‚ฌ์šฉํ•˜๋Š” ๋ณ€์ˆ˜๋Š” final ํ•„๋“œ๊ฐ€ ์•„๋‹ˆ๋ผ ๊ฐ€๋ณ€์ ์ธ ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ, ๊ฐ’ ๋ณ€๊ฒฝ์ด ๊ฐ€๋Šฅํ•˜๋‹ค. ์ปดํŒฉํŠธ ์ƒ์„ฑ์ž์˜ ๋ชจ๋“  ๋กœ์ง์ด ์‹คํ–‰๋œ ํ›„ ์ตœ์ข…์ ์œผ๋กœ ๊ฒฐ์ก๋œ ํŒŒ๋ฆฌ๋ฏธํ„ฐ ๊ฐ’๋“ค์ด final ํ•„๋“œ์— ํ• ๋‹น๋œ๋‹ค.

๐Ÿ“Œ ์‚ฌ์šฉ ์˜ˆ์‹œ

์–ธ๊ธ‰ํ–ˆ๋‹ค์‹œ๋ฏธ DTO๋ฅผ Record๋ฅผ ํ†ตํ•ด ๋งŽ์ด ๊ตฌํ˜„ํ•œ๋‹ค.

1
2
3
4
5
6
7
8
public record Coordinate(int x, int y) {}

public class GameMap {

	Map<Coordinate, String> worldMap = new HashMap<>();
	
	// ...
}

๊ทธ ์™ธ์—๋„ JSON๊ณผ ๋งคํ•‘๋˜๋Š” API์˜ ๋ฐ์ดํ„ฐ ๋ชจ๋ธ, Map์˜ ํ‚ค๋กœ ์‚ฌ์šฉ๋  ๋ณตํ•ฉ์ ์ธ ๊ฐ’์„ ํ‘œํ˜„ํ•  ๋•Œ ์‚ฌ์šฉํ•œ๋‹ค.

๐Ÿ“Œ ํ•œ๊ณ„์ 

๋จผ์ € JPA Entity๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†๋‹ค. JPA์˜ Lazy Loading ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†๊ธฐ ๋•Œ๋ฌธ์ธ๋ฐ, Lazy Loading์„ ํ†ตํ•ด ์—”ํ‹ฐํ‹ฐ๋ฅผ ์ƒ์†๋ฐ›๋Š” ํ”„๋ก์‹œ ๊ฐ์ฒด๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ Record๋Š” final ํด๋ž˜์Šค์ด๋ฏ€๋กœ ์ƒ์†์ด ๋ถˆ๊ฐ€๋Šฅํ•˜๋‹ค.

๋˜ํ•œ ๋ชจ๋“  ํ•„๋“œ๋Š” final ์ด๋ฏ€๋กœ setter๋ฅผ ๊ฐ€์งˆ ์ˆ˜ ์—†๋‹ค. ์ฆ‰, ์ƒํƒœ ๋ณ€๊ฒฝ์ด ํ•„์š”ํ•œ ๊ฐ์ฒด์—๋Š” Record๊ฐ€ ์ ํ•ฉํ•˜์ง€ ์•Š๋‹ค.

This post is licensed under CC BY 4.0 by the author.