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분기