하나에 답하세요:
가장 인기 있는 Java 인터뷰 질문 중 하나는 불변 객체(immutable object)란 무엇이며, 불변 객체의 이점은 무엇이며, 어떤 상황에서 사용해야 합니까? 또는 더 구체적으로 왜 Java의 String 클래스를 an로 설정해야 합니까? 불변 유형?
이름에서 알 수 있듯이 불변 객체는 생성 후에 변경할 수 없는 객체입니다. 일반적인 예는 Java의 String 클래스입니다.
다음과 같이 코드 코드를 복사합니다.
문자열 s = "ABC";
s.toLowerCase();
위와 같이 s.toLowerCase()는 "ABC"의 값을 변경하지 않지만 새 문자열 클래스 "abc"를 만든 다음 새 인스턴스를 변수 s를 가리킵니다.
불변 객체는 가변 객체에 비해 많은 장점을 가지고 있습니다:
1) 불변 객체는 문자열 풀의 효율성과 안전성을 향상시킬 수 있습니다. 객체가 불변이라는 것을 알고 있다면 객체의 내용을 복사해야 할 때 객체 자체를 복사할 필요는 없고 주소(보통 포인터 크기)만 복사하면 메모리가 거의 필요하지 않습니다. 매우 효율적입니다. 이 "ABC"를 동시에 참조하는 다른 변수에는 영향을 미치지 않습니다.
2) 불변 객체는 다중 스레드에 안전합니다. 여러 스레드가 동시에 실행될 때 변경 가능한 객체의 값이 다른 프로세스에 의해 변경되어 예측할 수 없는 결과가 발생할 가능성이 높기 때문입니다. 상황을 피할 수 있습니다.
물론 다른 이유도 있지만 Java가 String을 불변으로 설정하는 가장 큰 이유는 효율성과 안전성입니다.
두 가지 대답:
이것은 오래되었지만 여전히 인기 있는 질문입니다. Java에서 문자열을 불변으로 설계하는 것은 다양한 요소를 고려한 결과입니다. 이 문제를 이해하려면 다음에서 구조적 및 데이터 고려 사항을 통합해야 합니다. , 다양한 이유를 요약하겠습니다.
1. 문자열 상수 풀의 필요성
문자열 상수 풀(String pool, String intern pool, String Retention Pool)은 Java 힙 메모리의 특수 저장 영역으로, String 개체 생성 시 해당 문자열 값이 상수 풀에 이미 존재하는 경우 새로 생성되지 않습니다. 객체이지만 기존 객체에 대한 참조입니다.
다음 코드에서 볼 수 있듯이 힙 메모리에는 실제 String 객체가 하나만 생성됩니다.
다음과 같이 코드 코드를 복사합니다.
문자열 s1 = "abcd";
문자열 s2 = "abcd";
개략도는 다음과 같습니다.
문자열 개체를 변경하도록 허용하면 다양한 논리적 오류가 발생합니다. 예를 들어 하나의 개체를 변경하면 다른 독립 개체에 영향을 미치게 됩니다. 엄밀히 말하면 이 상수 풀의 아이디어는 최적화 방법입니다.
생각해보세요: 코드가 다음과 같다면 s1과 s2는 여전히 동일한 실제 String 객체를 가리킬까요?
다음과 같이 코드 코드를 복사합니다.
문자열 s1= "ab" + "cd";
문자열 s2= "abc" + "d";
이 질문은 초보자에게는 직관에 반할 수도 있지만 최신 컴파일러가 정기적인 최적화를 수행한다는 점을 고려하면 모두 상수 풀에서 동일한 개체를 가리킬 것입니다. 또는 jd-gui와 같은 도구를 사용하여 컴파일된 클래스 문서를 볼 수 있습니다.
2. String 객체가 HashCode를 캐시하도록 허용
Java에서 String 객체의 해시 코드는 hashMap과 같은 컨테이너에서 자주 사용됩니다.
문자열 불변성은 해시 코드의 고유성을 보장하므로 안심하고 캐시할 수 있습니다. 이는 성능 최적화 방법이기도 하며, 이는 매번 새로운 해시 코드를 계산할 필요가 없음을 의미합니다. String 클래스의 :
다음과 같이 코드 코드를 복사합니다.
private int hash;//HashCode를 캐시하는 데 사용됩니다.
3. 보안
String은 네트워크 연결 주소 URL, 파일 경로, 리플렉션 메커니즘에 필요한 String 매개 변수 등 많은 Java 클래스(라이브러리)에서 매개 변수로 사용됩니다.
다음 코드가 있는 경우:
다음과 같이 코드 코드를 복사합니다.
부울 연결(문자열 s){
if (!isSecure(s)) {
새로운 SecurityException()을 던져라;
}
// 문자열을 다른 곳에서 수정할 수 있으면 여기서 예상치 못한 다양한 문제/오류가 발생합니다.
원인문제;
}
일반적으로 String이 불변인 이유에는 디자인 고려 사항, 효율성 최적화 문제 및 보안이 포함됩니다. 실제로 이는 Java 인터뷰에서 많은 "이유"에 대한 답변이기도 합니다.
답변 3: String 클래스 불변성의 이점
문자열은 모든 언어에서 가장 일반적으로 사용되는 클래스입니다. 우리는 Java에서 문자열이 불변이고 최종적이라는 것을 알고 있습니다. Java는 또한 런타임 시 String 풀을 저장하여 String을 특수 클래스로 만듭니다.
String 클래스 불변성의 이점
1. 문자열 풀링은 문자열이 변경 불가능한 경우에만 가능합니다. 문자열 풀을 구현하면 다양한 문자열 변수가 풀의 동일한 문자열을 가리키기 때문에 런타임 시 많은 힙 공간을 절약할 수 있습니다. 하지만 문자열이 가변적이라면 문자열 인턴은 불가능합니다. (역자 주: 문자열 인턴은 서로 다른 하나의 문자열만 저장된다는 의미입니다. 즉, 동일한 여러 문자열은 저장되지 않습니다.) 값이 변경되면 이 값을 가리키는 다른 변수의 값도 변경됩니다.
2. 문자열이 가변적일 경우 심각한 보안 문제가 발생할 수 있습니다. 예를 들어, 데이터베이스 연결을 얻기 위해 데이터베이스의 사용자 이름과 비밀번호가 문자열로 전달되거나, 소켓 프로그래밍에서는 호스트 이름과 포트가 문자열로 전달됩니다. 문자열은 불변이기 때문에 값을 변경할 수 없습니다. 그렇지 않으면 해커가 허점을 이용하여 문자열이 가리키는 개체의 값을 변경하여 보안 취약점을 일으킬 수 있습니다.
3. 문자열은 변경할 수 없기 때문에 다중 스레드로부터 안전하며 동일한 문자열 인스턴스를 여러 스레드에서 공유할 수 있습니다. 이렇게 하면 스레드 안전 문제로 인해 동기화를 사용할 필요가 없습니다. 문자열 자체는 스레드로부터 안전합니다.
4. 클래스 로더는 문자열을 사용하며 불변성은 올바른 클래스가 로드되도록 보안을 제공합니다. 예를 들어 java.sql.Connection 클래스를 로드하려고 하는데 이 값이 myhacked.Connection으로 변경되면 데이터베이스에 알 수 없는 손상이 발생합니다.
5. 문자열은 변경할 수 없기 때문에 해시코드는 생성될 때 캐시되며 다시 계산할 필요가 없습니다. 이는 문자열을 맵의 키로 매우 적합하게 만들고 문자열은 다른 키 개체보다 빠르게 처리될 수 있습니다. 이것이 HashMap의 키가 종종 문자열을 사용하는 이유입니다.
위 내용은 문자열 불변성의 이점을 요약한 것입니다.