[java] 문자열은 Java에서 객체이므로 ‘new’를 사용하여 생성하지 않는 이유는 무엇입니까?

일반적으로 new다음과 같은 키워드를 사용하여 객체를 만듭니다 .

Object obj = new Object();

문자열은 객체이지만이 new를 생성하는 데 사용하지 않습니다 .

String str = "Hello World";

왜 이런거야? 문자열을 만들 수 있습니까 new?



답변

이미 말한 것 외에도 Java에서 문자열 리터럴 [즉, 유사 "abcd"하지만 유사 하지 않은 문자열 new String("abcd")]이 인턴됩니다. 즉, “abcd”를 참조 할 때마다 String새 인스턴스가 아닌 단일 인스턴스에 대한 참조를 얻게됩니다. 매번. 따라서 다음을 갖게됩니다.

String a = "abcd";
String b = "abcd";

a == b; //True

하지만 만약 당신이

String a = new String("abcd");
String b = new String("abcd");

그런 다음 가질 수 있습니다

a == b; // False

(그리고 누군가가 상기시킬 필요가있는 경우 항상 .equals()문자열을 비교 하는 데 사용하십시오 ==. 물리적 동등성 테스트).

Interning String 리터럴은 종종 두 번 이상 사용되기 때문에 좋습니다. 예를 들어 (기인 된) 코드를 고려하십시오.

for (int i = 0; i < 10; i++) {
  System.out.println("Next iteration");
}

문자열의 인턴이 없다면 “Next iteration”은 10 번 인스턴스화되어야하지만 지금은 한 번만 인스턴스화됩니다.


답변

문자열은 Java에서 “특별한”개체입니다. 자바 설계자들은 문자열이 너무 자주 사용되어 캐싱 전략뿐만 아니라 자체 구문이 필요하다고 현명하게 결정했습니다. 다음과 같이 말하여 문자열을 선언 할 때 :

String myString = "something";

myString은 값이 “something”인 String 객체에 대한 참조입니다. 나중에 선언하는 경우 :

String myOtherString = "something";

Java는 myString과 myOtherString이 동일하고 동일한 객체로 전역 문자열 테이블에 저장된다는 것을 알아낼만큼 똑똑합니다. 이 작업을 수행하기 위해 문자열을 수정할 수 없다는 사실에 의존합니다. 이렇게하면 필요한 메모리 양이 줄어들고 더 빠르게 비교할 수 있습니다.

대신에

String myOtherString = new String("something");

Java는 myString 객체와는 다른 새로운 객체를 생성합니다.


답변

String a = "abc"; // 1 Object: "abc" added to pool

String b = "abc"; // 0 Object: because it is already in the pool

String c = new String("abc"); // 1 Object

String d = new String("def"); // 1 Object + "def" is added to the Pool

String e = d.intern(); // (e==d) is "false" because e refers to the String in pool

String f = e.intern(); // (f==e) is "true" 

//Total Objects: 4 ("abc", c, d, "def").

이것이 몇 가지 의심을 없애기를 바랍니다. 🙂


답변

지름길입니다. 원래는 그렇지 않았지만 Java가 변경했습니다.

FAQ 는 이에 대해 간략하게 설명합니다. Java 사양 가이드에서도 이에 대해 설명합니다. 하지만 온라인에서 찾을 수 없습니다.


답변

문자열은 몇 가지 최적화를 거쳐야합니다 (더 나은 문구를 원하기 위해). String에는 다른 객체와 달리 연산자 오버로딩 (+ 연산자의 경우)도 있습니다. 그래서 그것은 매우 특별한 경우입니다.


답변

우리는 일반적으로 불필요한 객체 생성을 피하기 위해 문자열 리터럴을 사용합니다. new 연산자를 사용하여 String 객체를 생성하면 매번 새로운 객체를 생성합니다.

예:

String s1=“Hello“;
String s2=“Hello“;
String s3= new String(“Hello“);
String s4= new String(“Hello“);

메모리에있는 위 코드의 경우 :

여기에 이미지 설명 입력


답변

Java에서 문자열은 특수한 경우이며 문자열에만 적용되는 많은 규칙이 있습니다. 큰 따옴표를 사용하면 컴파일러가 String 개체를 만듭니다. String 객체는 불변이므로 컴파일러가 여러 문자열을 인턴하고 더 큰 문자열 풀을 빌드 할 수 있습니다. 두 개의 동일한 문자열 상수는 항상 동일한 객체 참조를 갖습니다. 이 경우를 원하지 않는 경우 new String ( “”)을 사용할 수 있습니다. 그러면 런타임에 String 객체가 생성됩니다. intern () 메서드는 일반적으로 사용되어 동적으로 생성 된 문자열을 문자열 조회 테이블에 대해 확인합니다. 일단 문자열이 인턴되면 개체 참조는 표준 String 인스턴스를 가리 킵니다.

    String a = "foo";
    String b = "foo";
    System.out.println(a == b); // true
    String c = new String(a);
    System.out.println(a == c); // false
    c = c.intern();
    System.out.println(a == c); // true

클래스 로더가 클래스를로드하면 모든 문자열 상수가 문자열 풀에 추가됩니다.