객체지향 프로그래밍에서는 불변 문자열 또는 객체 일단 생성되면 수정할 수 없습니다. 그러나 객체에 대한 참조만 변경할 수 있습니다. 우리는 객체 자체를 변경하는 것으로 제한합니다. 그만큼 문자열은 불변이다 ~에 자바 보안, 동기화 및 동시성, 캐싱 및 클래스 로딩 때문입니다. 문자열을 final로 만드는 이유는 불변성을 파괴하고 다른 사람이 이를 확장하는 것을 허용하지 않기 위해서입니다.
String 개체는 String 풀에 캐시되어 문자열은 변경할 수 없습니다. . 캐시된 문자열 리터럴은 여러 클라이언트에서 액세스됩니다. 따라서 한 클라이언트가 수행하는 작업이 다른 모든 클라이언트에 영향을 미치는 위험이 항상 존재합니다. 예를 들어, 한 클라이언트가 작업을 수행하고 문자열 값을 Pressure에서 PRESSURE로 변경하면 나머지 모든 클라이언트도 해당 값을 읽습니다. 성능상의 이유로 String 객체의 캐싱이 중요하므로 이러한 위험을 제거하려면 String을 Immutable로 만들어야 합니다.
String을 불변으로 만드는 몇 가지 이유는 다음과 같습니다.
- Java에서 문자열을 변경할 수 없으면 문자열 풀을 사용할 수 없습니다. 많은 힙 공간이 절약됩니다. JRE . 동일한 문자열 변수는 풀에 있는 둘 이상의 문자열 변수에서 참조될 수 있습니다. 문자열이 변경 불가능하지 않으면 문자열 인터닝도 불가능합니다.
- 문자열을 불변으로 만들지 않으면 애플리케이션에 심각한 보안 위협이 됩니다. 예를 들어, 데이터베이스 사용자 이름, 비밀번호는 데이터베이스 연결을 수신하기 위해 문자열로 전달됩니다. 그만큼 소켓 프로그래밍 호스트 및 포트 설명도 문자열로 전달됩니다. 문자열은 변경할 수 없으므로 해당 값을 변경할 수 없습니다. 문자열이 변경 불가능한 상태로 유지되지 않으면 해커가 참조 값을 변경하여 애플리케이션에 보안 문제를 일으킬 수 있습니다.
- String은 불변성으로 인해 멀티스레딩에 안전합니다. 다양한 스레드가 단일 '문자열 인스턴스'에 액세스할 수 있습니다. 문자열을 암시적으로 스레드로부터 안전하게 만들기 때문에 스레드 안전을 위한 동기화를 제거합니다.
- 불변성은 Classloader를 통해 올바른 클래스를 로드하는 보안을 제공합니다. 예를 들어 java.sql.Connection 클래스를 로드하려고 시도했지만 myhacked.Connection 클래스에 대한 참조 값이 변경되어 데이터베이스에 원하지 않는 작업을 수행하는 인스턴스가 있다고 가정해 보겠습니다.
예를 통해 불변성의 개념을 이해해보자.
불변문자열.java
import java.util.*; class ImmutableString{ public static void main(String args[]){ String NewString = 'Hello'; NewString.concat('World'); System.out.println(NewString); } }
산출:
설명: 다음 다이어그램을 통해 위의 예를 이해할 수 있습니다.
문자열 상수 풀에서는 안녕하세요 변경되지 않고 새 문자열 객체가 생성됩니다. 헬로월드 . 문자열이 변경 불가능함을 보여줍니다. 참조변수는 다음을 가리킨다. 안녕하세요 아니라 안녕하세요.
우리가 원한다면 그것은 헬로월드 , 해당 변수에 명시적으로 할당해야 합니다. 예를 들어:
import java.util.*; class ImmutableString{ public static void main(String args[]){ String NewString = 'Hello'; NewString = NewString.concat('World'); System.out.println(NewString); } }
산출: