기본형 변수와 참조형 변수, final 이해

이상민·2024년 8월 5일
0

목표

  • 기본형 변수와 참조형 변수의 차이를 이해
  • final을 사용하여 불변을 활용하며, 불변 객체의 특징을 이해
  • 불변 특징을 활용하여 메모리 관리, 데이터 조작의 효율성을 높임

객체 만들기

public class Adventurer{
    private String name = "새싹";
}
public class Artifact {
     public int data;

    public Artifact(int data) {
        this.data = data;
    }
}
public class FakeArtifact extends Artifact {

    public FakeArtifact(int data) {
        super(data);
    }
}

던전: 보물의 방 만들기

public class TreasureChamber {

    private Artifact magicObj = new Artifact(1); // 💎💎💎

    public Artifact findArtifact(Adventurer adventurer) {
        return artifact;
    }
}

던전: 미로 만들기

public class Labyrinth {

    private final TreasureChamber chamber;

    public Labyrinth(TreasureChamber chamber) {
        this.chamber = chamber;
    }

    public Artifact navigate(Adventurer adventurer) {
        Artifact artifact = chamber.findArtifact(adventurer);
        return artifact;
    }
}

던전: 입구 만들기

public class Entrance {
    private final Labyrinth labyrinth;

    public Entrance(Labyrinth labyrinth) {
        this.labyrinth = labyrinth;
    }

    public Artifact enterDungeon(Adventurer adventurer) {
        Artifact artifact = labyrinth.navigate(adventurer);
        return artifact;
    }
}

던전 환경 만들기

public class Main {

    public static void main(String[] args) {
        // 던전 인스턴스화
        TreasureChamber chamber = new TreasureChamber();
        Labyrinth labyrinth = new Labyrinth(chamber);
        Entrance entrance = new Entrance(labyrinth);
    }
}

만든 던전의 입구,미로,보물의 방을 연결해줍니다.

노트
던전을 구성하기 위해 입구,미로,보물의 방을 만들어준다.

유물의 데이터를 변형하는 알수없는 힘 만들기 (static 키워드)

public class Main {

    public static int UNKOWN_FORCE = 1; // 신비로운 힘

    public static void <main(String[] args) {
       ...
    }
}

노트
static으로 선언된 변수와 메서드는 클래스 로딩 시점에 JVM 메모리 영역인 메타스페이스에 저장된다.

각 던전 계층에 신비로운힘 구현하기

public class Labyrinth {
    ... 
    public Artifact navigate(Adventurer adventurer) {
        ...
        artifact.data += Main.UNKOWN_FORCE;
        ...
    }
}

public class Entrance {
    ...
    public Artifact enterDungeon(Adventurer adventurer) {
        ...
        artifact.data += Main.UNKOWN_FORCE;
        ...
    }
}
public class TreasureChamber {
    ...
    public Artifact findMagicObject(Adventurer adventurer) {
        artifact.data += Main.UNKOWN_FORCE;
        ...
    }
}

던전 탐험 시작

public class Main {

    public static int UNKOWN_FORCE = 1;

    public static void main(String[] args) {
        TreasureChamber chamber = new TreasureChamber();
        Labyrinth labyrinth = new Labyrinth(chamber);
        Entrance entrance = new Entrance(labyrinth);

        Adventurer saeSsak = new Adventurer();
        Artifact artifact = entrance.enterDungeon(saeSsak);
        System.out.println("찾은 유물: " + artifact.data);
    }
}

위 코드에서 Artifact의 데이터가 계속 변경되는데 이 데이터를 어떻게 보호할 수 있을까?

final

유물을 불변으로 만들어 보자

public class TreasureChamber {

    private final Artifact artifact = new Artifact(1);

    public Artifact findMagicObject(Adventurer adventurer) {
        artifact.data += Main.UNKOWN_FORCE;
        return artifact;
    }
}

final 키워드를 사용해 데이터를 보호하려고 하지만 원하는 결과를 얻지못했다

public class Artifact {
     public int data; // <- 변경 가능

    public Artifact(int data) {
        this.data = data;
    }
}

        artifact.data += Main.UNKOWN_FORCE; // <- 계속 변경이 일어납니다.

불변객체를 만들기

public class Artifact {
     public final int data; // <- final 키워드 추가

    public Artifact(int data) {
        this.data = data;
    }
}

객체의 상태를 완전히 불변으로 만들려면, 모든 필드
final로 선언하고, 객체가 한 번 생성된 후에는 변경할 수 없도록 해야한다. 예로, MagicObjectdata필드를 final로 선언하면 객체의 불변성을 보장할 수 있다.

final 키워드를 사용하여 클래스 상속을 막기

public final class Artifact { // final 키워드 추가
     public final int data;

    public Artifact(int data) {
        this.data = data;
    }
}

public class FakeArtifact extends Artifact {

    public FakeArtifact(int data) {
        super(data);
    }
}

final 키워드를 클래스 선언에 추가하면, 해당 클래스를 다른 클래스가 상속할 수 없게 된다. 이러한 방식은 클래스의 설계를 고정시키고, 의도치 않은 확장을 방지하여 객체의 일관성을 유지하는 데 유용하다.

노트

final필드를 생성할까?
1. 메모리 효율성
2. 코드의 안전성

자바는 왜 String 을 불변객체로 만들었을까?

매번 같은 객체가 생성된다면?

StringPool 사용


String strA = "hello"; // 리터럴
String strB = new String("hello"); // new 키워드
String strC = new String("hello");
String strD = "hello";

System.out.println(strB==strC);
System.out.println(strA==strD);

노트

B와C는 false 결과값이 나온다

불변 객체는 수정대신 새로운 객체를 반환한다.


String concat = strA.concat(strB);
System.out.println(concat);
profile
안녕하세요

0개의 댓글