우리는 디자인하는 동안 Java 디자이너가 실제로 무엇을 생각했는지 확신 할 수 없지만 String
문자열 불변성에서 얻을 수있는 이점을 기반으로 이러한 이유를 결론 내릴 수 있습니다.
1. 문자열 상수 풀의 존재
문자열이 문자열 상수 풀에 저장 되는 이유 기사 에서 설명한 것처럼 모든 응용 프로그램은 너무 많은 문자열 객체를 생성하고 많은 문자열 객체를 생성 한 다음 가비지 수집을 시작하지 않아도 JVM을 절약 할 수 있습니다. JVM은 모든 문자열 오브젝트를 문자열 상수 풀이라는 별도의 메모리 영역에 저장하고 캐시 된 풀의 오브젝트를 재사용합니다.
문자열 리터럴 JVM을 만들 때마다 해당 리터럴이 상수 풀에 이미 존재하는지 여부를 확인한 후 존재하는 경우 SCP에서 동일한 객체를 가리키는 새로운 참조가 시작됩니다.
String a = "Naresh";
String b = "Naresh";
String c = "Naresh";
값 위의 예제 문자열 객체에서 Naresh
한 번만 SCP에서 만든 얻을 것이다 모든 참조 a
, b
, c
우리가 변화를 만들려고하면 같은 객체하지만 가리 킵니다 a
예를 a.replace("a", "")
.
이상적으로, a
값이 있어야 Nresh
하지만 b
, c
때문에 우리가 변화하고 있습니다 최종 사용자로 변경되지 않은 상태로 유지해야 a
만. 그리고 우리는 알고 a
, b
, c
우리가 변화 할 경우, 그래서 모두 같은 객체를 가리키고 a
, 다른 사람도 변화를 반영해야한다.
그러나 문자열 불변성은이 시나리오에서 우리를 구해 주며 문자열 객체의 불변성으로 인해 문자열 객체 Naresh
는 절대 변경되지 않습니다. 따라서 a
문자열 객체를 변경하는 대신 변경 Naresh
하면 JVM이 새 객체를 생성 한 a
다음 해당 객체를 변경합니다.
따라서 문자열 풀은 문자열의 불변성으로 인해 가능하며 문자열을 변경할 수 없으면 문자열 객체를 캐싱하고 재사용하면 변수가 값을 변경하고 다른 변수가 손상되어 가능성이 없습니다.
그렇기 때문에 JVM이 매우 특별하게 처리하고 특수한 메모리 영역이 제공되는 이유입니다.
2. 스레드 안전
객체는 여러 스레드가 작동 중일 때 스레드 안전이라고 불리지 만 어느 상태에서도 손상을 입을 수 없으며 어느 시점에서나 모든 스레드에 대해 동일한 상태를 유지하지 못합니다.
우리가 불변 객체를 만든 후에는 변경할 수 없으므로 모든 불변 객체는 기본적으로 스레드 안전합니다. 동기화 된 메소드 작성과 같은 스레드 안전 조치를 적용 할 필요는 없습니다.
따라서 변경 불가능한 자연 문자열로 인해 여러 스레드에서 공유 할 수 있으며 많은 스레드에서 조작하더라도 값이 변경되지 않습니다.
3. 보안
모든 애플리케이션에서 사용자의 사용자 이름 \ 암호, 연결 URL과 같은 몇 가지 비밀을 전달해야하며 일반적으로이 모든 정보는 문자열 객체로 전달됩니다.
이제 String이 본질적으로 변경 불가능하지 않다면 응용 프로그램에 심각한 보안 위협이 발생한다고 가정하십시오.이 값은 변경 될 수 있기 때문에 허용 된 경우 잘못 작성된 코드 또는 다른 사람으로 인해 변경 될 수 있습니다 변수 참조에 액세스 할 수 있습니다.
4. 클래스 로딩
Example 을 사용 하여 Java에서 Reflection을 통해 객체 만들기 에서 설명했듯이 Class.forName("class_name")
method를 사용하여 클래스를 메모리에로드하여 다른 메서드를 다시 호출 할 수 있습니다. 그리고 JVM조차도 이러한 메소드를 사용하여 클래스를로드합니다.
그러나 모든 메소드가 클래스 이름을 문자열 객체로 허용하므로 문자열은 Java 클래스 로딩에 사용되며 불변성은 올바른 클래스가로드되는 보안을 제공합니다 ClassLoader
.
String이 불변이 아니고 사이에 java.lang.Object
변경되는 것을로드하려고 시도 org.theft.OurObject
하고 이제 모든 객체가 누군가가 원하지 않는 것에 사용할 수있는 동작을 가지고 있다고 가정하십시오.
해시 코드 캐싱
객체에서 해싱 관련 작업을 수행 hashCode()
하려는 경우 메서드 를 재정의 하고 객체 상태를 사용하여 정확한 해시 코드를 생성해야합니다. 객체의 상태가 변경되면 해시 코드도 변경되어야합니다.
String은 불변이므로 하나의 문자열 객체가 보유하는 값은 변경되지 않으므로 해시 코드도 변경되지 않으므로 String 클래스는 객체 생성 중에 해시 코드를 캐시 할 수 있습니다.
예, String 객체는 객체 생성시 해시 코드를 캐시하므로 해시 코드를 다시 계산할 필요가 없으므로 시간을 절약 할 수 있기 때문에 해시 관련 작업을 수행 할 수 있습니다. 이것이 문자열이 주로 HashMap
키로 사용되는 이유 입니다.
Java에서 String이 변경 불가능하고 최종적인 이유 에 대해 자세히 알아보십시오 .