logo

Java에서 불변 클래스를 만드는 방법은 무엇입니까?

Java에서 불변성은 객체가 생성되면 내부 상태를 변경할 수 없음을 의미합니다. Java의 불변 클래스는 스레드 안전성, 손쉬운 디버깅 등과 같은 많은 이점을 제공합니다. 자바에서는 모든 래퍼 클래스 (Integer Boolean Byte Short와 같은) String 클래스는 변경할 수 없습니다. 우리는 불변 클래스를 직접 만들 수도 있습니다.

이 기사에서 우리는 다음을 배울 것입니다:

  • 불변성의 의미
  • 유용한 이유
  • 불변 클래스를 만드는 방법
  • 깊은 복사가 중요한 이유
  • Java 레코드 유형에는 어떤 제한이 있습니까?

불변 클래스란 무엇입니까?

불변 클래스는 일단 생성된 객체를 변경할 수 없는 클래스입니다. 수정을 하면 새로운 객체가 생성됩니다. 이 방법은 동시 애플리케이션에 사용됩니다.



불변 클래스 생성 규칙

  • 클래스는 다음과 같이 선언되어야 합니다. 결정적인 하위 클래스를 생성할 수 없도록 합니다.
  • 클래스의 데이터 멤버를 선언해야 합니다. 사적인 직접 접근이 불가능하도록 말이죠.
  • 클래스의 데이터 멤버는 다음과 같이 선언되어야 합니다. 결정적인 객체 생성 후에는 값을 변경할 수 없습니다.
  • 매개변수화된 생성자는 다음을 수행하는 모든 필드를 초기화해야 합니다. 딥 카피 개체 참조로 데이터 멤버를 수정할 수 없도록 합니다.
  • 실제 개체 참조를 반환하는 대신 복사본을 반환하려면 getter 메서드에서 개체의 전체 복사를 수행해야 합니다.

메모 : 설정자가 없어야 합니다. 간단히 말해서 인스턴스 변수의 값을 변경하는 옵션이 없어야 합니다.


우선순위 큐 자바

예: 불변 클래스 구현

Student.java

Java
// Java Program to Create An Immutable Class import java.util.HashMap; import java.util.Map; // declare the class as final final class Student {  // make fields private and final  private final String name;  private final int regNo;  private final Map<String String> metadata;  // initialize all fields via constructor  public Student(String name int regNo Map<String String> metadata) {  this.name = name;  this.regNo = regNo;  // deep copy of mutable object (Map)  Map<String String> tempMap = new HashMap<>();  for (Map.Entry<String String> entry : metadata.entrySet()) {  tempMap.put(entry.getKey() entry.getValue());  }  this.metadata = tempMap;  }  // only provide getters (no setters)  public String getName() {  return name;  }  public int getRegNo() {  return regNo;  }  // return deep copy to avoid exposing internal state  public Map<String String> getMetadata() {  Map<String String> tempMap = new HashMap<>();  for (Map.Entry<String String> entry : this.metadata.entrySet()) {  tempMap.put(entry.getKey() entry.getValue());  }  return tempMap;  } } 

이 예에서는 이름이 지정된 최종 클래스를 만들었습니다. 학생. 여기에는 세 개의 최종 데이터 멤버(매개변수화된 생성자 및 getter 메소드)가 있습니다. 여기에는 setter 메소드가 없다는 점에 유의하십시오. 또한 래퍼 유형의 데이터 멤버는 이미 변경할 수 없으므로 깊은 복사나 복제를 수행할 필요가 없습니다.

Geeks.java:

자바의 어떤 컬렉션
Java
import java.util.HashMap; import java.util.Map; public class Geeks {  public static void main(String[] args) {  // create a map and adding data  Map<String String> map = new HashMap<>();  map.put('1' 'first');  map.put('2' 'second');  // create an immutable Student object  Student s = new Student('GFG' 101 map);  // accessing data  System.out.println(s.getName());   System.out.println(s.getRegNo());   System.out.println(s.getMetadata());   // try to modify the original map  map.put('3' 'third');  System.out.println(s.getMetadata());   // try to modify the map returned by getMetadata()  s.getMetadata().put('4' 'fourth');  System.out.println(s.getMetadata());   } } 

원본 또는 반환된 Map을 수정한 후에도 Student 개체의 내부 상태는 변경되지 않습니다. 이는 불변성 개념을 확인시켜줍니다.

산출:

GFG  
101
{1=first 2=second}
{1=first 2=second}
{1=first 2=second}


가변 필드가 있는 Java 레코드의 제한

자바 14 도입 기록 . 이는 클래스와 같은 불변성을 정의하는 명확하고 간결한 방법입니다.

자식 상태 -s

기록 Student(문자열 이름 int regNo Map메타데이터) {}


그러나 이는 얕은 불변성을 제공할 뿐입니다. 맵이 외부적으로 수정되면 레코드의 내부 상태가 변경됩니다.

지도지도 = 새로운 HashMap<>();

map.put('1' '첫 번째');

자바에서 정렬된 배열 목록


Student s = new Student('ABC' 101 지도);


// 내부 상태 변경 - 안전하지 않음

map.put('2' '초');

s.metadata().put('3' '세 번째');

메모 : 모든 필드가 String int 또는 기타 레코드와 같이 변경할 수 없는 유형인 경우에만 레코드를 사용하십시오.


3분기