자바 문자열 :“String s = new String (”silly“);”


85

저는 Java를 배우는 C ++ 사람입니다. 효과적인 Java를 읽고 있는데 뭔가 혼란 스러웠습니다. 다음과 같은 코드를 작성하지 말라고합니다.

String s = new String("silly");

불필요한 String물건을 만들기 때문입니다. 그러나 대신 다음과 같이 작성해야합니다.

String s = "No longer silly";

지금까지는 괜찮아요 ...하지만이 수업이 주어지면 :

public final class CaseInsensitiveString {
    private String s;
    public CaseInsensitiveString(String s) {
        if (s == null) {
            throw new NullPointerException();
        }
        this.s = s;
    }
    :
    :
}

CaseInsensitiveString cis = new CaseInsensitiveString("Polish");
String s = "polish";
  1. 첫 번째 진술은 왜 괜찮습니까? 안돼

    CaseInsensitiveString cis = "Polish";

  2. 어떻게해야합니까 CaseInsensitiveString처럼 행동 String때문에 위의 문 (와 연장없이 OK입니다 String)? 리터럴을 그대로 전달할 수 있도록하는 것은 String에 대해 무엇입니까? 내 이해에서 Java에는 "복사 생성자"개념이 없습니까?


2
문자열 str1 = "foo"; 문자열 str2 = "foo"; str1과 str2는 모두 동일한 String 객체에 속합니다. "foo", Java 용 b'coz는 StringPool에서 문자열을 관리하므로 새 변수가 동일한 문자열을 참조하므로 다른 변수를 생성하지 않고 동일한 alerady를 할당합니다. StringPool. 하지만 이렇게하면 : String str1 = new String ( "foo"); 문자열 str2 = new String ( "foo"); 여기서 str1과 str2는 모두 다른 객체에 속합니다. b'coz new String ()은 강제로 새 문자열 객체를 만듭니다.
Akash5288

답변:


111

String언어의 특수 내장 클래스입니다. 말을 피해야 하는 String수업 만을 위한 것입니다.

String s = new String("Polish");

리터럴 "Polish"은 이미 유형 String이고 불필요한 개체를 추가로 생성하고 있기 때문입니다 . 다른 수업의 경우

CaseInsensitiveString cis = new CaseInsensitiveString("Polish");

해야 할 올바른 (그리고이 경우에만) 일입니다.


8
두 번째 요점은 컴파일러가 "String (literal)"과 같은 이상한 함수 호출로 반드시 가능하지 않은 문자열 리터럴로 internig / propagating-stuff를 꾸밀 수 있다는 것입니다
Tetha

5
을 호출해서는 안되므로 new String("foo")생성자 new String(String)가 존재하는 이유를 스스로에게 물어볼 수 있습니다. 대답은 때때로 좋은 용도가 있다는 것입니다. stackoverflow.com/a/390854/1442870
Enwired

참고로, 위의 Tetha의 코멘트처럼, 단어 "인턴을"맞춤법이 틀린 문자열 인턴 .
Basil Bourque

57

리터럴 형식 (즉, new String ( "foo")이 아닌 "foo")을 사용할 때의 주요 이점은 모든 문자열 리터럴이 VM에 의해 '인턴'된다는 것입니다. 즉, 동일한 문자열을 생성하는 다른 코드가 새 인스턴스를 생성하는 대신 풀링 된 문자열을 사용하도록 풀에 추가됩니다.

설명을 위해 다음 코드는 첫 번째 줄에 대해 true를 인쇄하고 두 번째 줄에 대해서는 false를 인쇄합니다.

System.out.println("foo" == "foo");
System.out.println(new String("bar") == new String("bar"));

15
마찬가지로 FindBugs가 "new Integer (N)"를 "Integer.valueOf (N)"로 대체하라고 말하는 이유입니다. 인턴 때문에.
Paul Tomblin

6
"foo"== new String ( "foo"). intern ()도 추가해야합니다.
James Schek

5
수정 : 문자열 리터럴은 VM이 아닌 컴파일러에 의해 동일한 참조를 가리 키도록 만들어집니다. VM은 런타임에 String 개체를 인턴 할 수 있으므로 두 번째 줄은 true 또는 false를 반환 할 수 있습니다!
Craig P. Motlin

1
@Motlin : 그것이 맞는지 잘 모르겠습니다. String 클래스에 대한 javadoc은 "모든 리터럴 문자열과 문자열 값 상수 표현식이 인턴됩니다"라고 요구합니다. 따라서 우리는 리터럴이 인턴되는 것에 의존 할 수 있습니다. 즉, "foo"== "foo"는 항상 true를 반환해야합니다.
Leigh

4
@Leigh 예, 리터럴은 VM이 아닌 컴파일러에 의해 인턴됩니다. Motlin이 얻는 것은 VM이 추가로 문자열을 인턴 할 수 있다는 것입니다. 따라서 new String ( "bar") == new String ( "bar")-> false 여부는 구현에 따라 다릅니다.
Aaron Maenpaa

30

문자열은 자바에서 약간 특별하게 취급되며 불변이므로 참조 계수로 처리하는 것이 안전합니다.

쓰면

String s = "Polish";
String t = "Polish";

그런 다음 s와 t는 실제로 동일한 객체를 참조하고 s == t는 "=="객체에 대해 true를 반환합니다. 객체가 "is the same object"라고 읽습니다 (또는 어쨌든 이것이 다음의 일부인지 확실하지 않습니다. 실제 언어 사양 또는 단순히 컴파일러 구현의 세부 사항-따라서 이것에 의존하는 것이 안전하지 않을 수 있습니다).

당신이 쓰면

String s = new String("Polish");
String t = new String("Polish");

s! = t (명시 적으로 새 문자열을 만들었 기 때문에) s.equals (t)는 true를 반환하지만 (문자열이이 동작을 같음에 추가하기 때문에).

당신이 쓰고 싶은 것은

CaseInsensitiveString cis = "Polish";

따옴표가 객체에 대한 일종의 단락 생성자라고 생각하기 때문에 작동하지 않습니다. 사실 이것은 평범한 오래된 java.lang.Strings에서만 작동합니다.


나는 불변성을 언급하기 위해 +1, 이것이 자바 strA = strB에서 strA = new String(strB). 스트링 인턴과는 많이 관련이 없습니다.
kritzikratzi

참조 계수로 처리되지 않습니다. JLS에는 문자열 풀링이 필요합니다.
Marquis of Lorne

20
String s1="foo";

리터럴은 풀에 들어가고 s1은 참조합니다.

String s2="foo";

이번에는 "foo"리터럴이 StringPool에서 이미 사용 가능한지 여부를 확인하므로 s2가 동일한 리터럴을 참조합니다.

String s3=new String("foo");

"foo"리터럴은 먼저 StringPool에 생성 된 다음 string arg 생성자를 통해 String Object가 생성됩니다. 즉, new 연산자를 통한 객체 생성으로 인해 힙에 "foo"가 생성되고 s3가이를 참조합니다.

String s4=new String("foo");

s3와 동일

그래서 System.out.println(s1==s2);// **true** due to literal comparison.

System.out.println(s3==s4);// **false** due to object

비교 (s3 및 s4는 힙의 다른 위치에 생성됨)


1
따옴표가없는 텍스트에는 따옴표 서식을 사용하지 말고 코드에 코드 서식을 사용하십시오.
Marquis of Lorne

12

Strings는 Java에서 특별 String합니다. 불변이며 문자열 상수는 자동으로 객체 로 변환 됩니다.

당신을위한 방법이 없습니다 SomeStringClass cis = "value" 예제를 다른 클래스에 적용 할 .

으로 String선언 되었기 때문에 확장 할 수도 final없습니다. 이는 하위 클래스가 허용되지 않음을 의미합니다.


7

Java 문자열은 흥미 롭습니다. 응답이 몇 가지 흥미로운 점을 다룬 것 같습니다. 여기 내 2 센트입니다.

문자열은 변경할 수 없습니다 (변경할 수 없음).

String x = "x";
x = "Y"; 
  • 첫 번째 줄은 문자열 값 "x"를 포함 할 변수 x를 만듭니다. JVM은 문자열 값 풀에서 "x"가 있는지 확인하고, 존재하는 경우 변수 x를 가리키고, 존재하지 않으면 생성 한 다음 할당을 수행합니다.
  • 두 번째 줄은 "x"에 대한 참조를 제거하고 "Y"가 문자열 값 풀에 있는지 확인합니다. 존재하는 경우 할당하고 그렇지 않은 경우 먼저 할당 한 다음 할당합니다. 문자열 값의 사용 여부에 따라 문자열 값 풀의 메모리 공간이 회수됩니다.

문자열 비교는 비교 대상에 따라 다릅니다.

String a1 = new String("A");

String a2 = new String("A");
  • a1 같지 않음 a2
  • a1a2객체 참조는
  • 문자열이 명시 적으로 선언되면 새 인스턴스가 생성되고 해당 참조는 동일하지 않습니다.

대소 문자를 구분하지 않는 클래스를 사용하려는 것이 잘못된 길에 있다고 생각합니다. 현은 그대로 두십시오. 정말로 관심있는 것은 값을 표시하거나 비교하는 방법입니다. 다른 클래스를 사용하여 문자열 형식을 지정하거나 비교하십시오.

TextUtility.compare(string 1, string 2) 
TextUtility.compareIgnoreCase(string 1, string 2)
TextUtility.camelHump(string 1)

클래스를 구성하고 있으므로 원하는대로 비교를 수행 할 수 있습니다. 텍스트 값을 비교합니다.


컴파일러는 JVM이 아닌 문자열 풀을 생성합니다. 변수는 개체를 포함하지 않으며 개체를 참조합니다. 문자열 리터럴에 대한 문자열 풀 공간은 회수되지 않습니다.
Marquis of Lorne

6

당신은 할 수 없습니다. Java에서 큰 따옴표로 묶인 것은 컴파일러에 의해 특별히 문자열로 인식되며, 불행히도이를 재정의 할 수 없습니다 (또는 확장 java.lang.String-선언 됨 final).


마지막은 여기 빨간 청어입니다. String이 최종이 아니더라도이 경우 String을 확장해도 도움이되지 않습니다.
Darron

1
다행히도 이것을 무시할 수 없다는 뜻이라고 생각합니다. :)
Craig P. Motlin

@Motlin : 하! 당신이 옳을 수도 있습니다. Java가 의도적으로 이와 같은 흥미로운 것을 배제함으로써 어리석은 일을하는 사람을 막을 수 있도록 설계된 곳을 읽은 것 같습니다.
Dan Vinton

6

질문에 답하는 가장 좋은 방법은 "문자열 상수 풀"에 익숙해지는 것입니다. 자바에서 문자열 객체는 불변 (즉, 초기화 된 값은 변경할 수 없음)이므로 문자열 객체를 편집 할 때 기존 객체가 특수 메모리에서 떠 다니는 새로운 편집 된 문자열 객체를 생성하게됩니다. 상수 풀 ". 새 문자열 객체 생성

String s = "Hello";

풀에 문자열 객체 만 생성하고 참조는이를 참조하지만

String s = new String("Hello");

두 개의 문자열 개체를 만듭니다. 하나는 풀에 있고 다른 하나는 힙에 있습니다. 참조는 힙의 개체를 참조합니다.


4

-CaseInsensitiveString이 String처럼 동작하도록하려면 어떻게해야 위의 문장이 괜찮을까요 (String 확장 여부에 관계없이)? 리터럴을 그대로 전달할 수 있도록하는 것은 String에 대해 무엇입니까? 내 이해에서 Java에는 "복사 생성자"개념이 없습니까?

첫 번째 요점부터 충분하다고 말했습니다. "Polish"는 문자열 리터럴이며 CaseInsentiviveString 클래스에 할당 할 수 없습니다.

이제 두 번째 요점 에 대해

새 리터럴을 만들 수는 없지만 "유사한"접근 방식으로 해당 책의 첫 번째 항목을 따를 수 있으므로 다음 진술이 참입니다.

    // Lets test the insensitiveness
    CaseInsensitiveString cis5 = CaseInsensitiveString.valueOf("sOmEtHiNg");
    CaseInsensitiveString cis6 = CaseInsensitiveString.valueOf("SoMeThInG");

    assert cis5 == cis6;
    assert cis5.equals(cis6);

여기에 코드가 있습니다.

C:\oreyes\samples\java\insensitive>type CaseInsensitiveString.java
import java.util.Map;
import java.util.HashMap;

public final class CaseInsensitiveString  {


    private static final Map<String,CaseInsensitiveString> innerPool 
                                = new HashMap<String,CaseInsensitiveString>();

    private final String s;


    // Effective Java Item 1: Consider providing static factory methods instead of constructors
    public static CaseInsensitiveString valueOf( String s ) {

        if ( s == null ) {
            return null;
        }
        String value = s.toLowerCase();

        if ( !CaseInsensitiveString.innerPool.containsKey( value ) ) {
             CaseInsensitiveString.innerPool.put( value , new CaseInsensitiveString( value ) );
         }

         return CaseInsensitiveString.innerPool.get( value );   
    }

    // Class constructor: This creates a new instance each time it is invoked.
    public CaseInsensitiveString(String s){
        if (s == null) {
            throw new NullPointerException();
         }         
         this.s = s.toLowerCase();
    }

    public boolean equals( Object other ) {
         if ( other instanceof CaseInsensitiveString ) {
              CaseInsensitiveString otherInstance = ( CaseInsensitiveString ) other;
             return this.s.equals( otherInstance.s );
         }

         return false;
    }


    public int hashCode(){
         return this.s.hashCode();
    }

// "assert"키워드를 사용하여 클래스 테스트

    public static void main( String [] args ) {

        // Creating two different objects as in new String("Polish") == new String("Polish") is false
        CaseInsensitiveString cis1 = new CaseInsensitiveString("Polish");
        CaseInsensitiveString cis2 = new CaseInsensitiveString("Polish");

        // references cis1 and cis2 points to differents objects.
        // so the following is true
        assert cis1 !=  cis2;      // Yes they're different
        assert cis1.equals(cis2);  // Yes they're equals thanks to the equals method

        // Now let's try the valueOf idiom
        CaseInsensitiveString cis3 = CaseInsensitiveString.valueOf("Polish");
        CaseInsensitiveString cis4 = CaseInsensitiveString.valueOf("Polish");

        // References cis3 and cis4 points to same  object.
        // so the following is true
        assert cis3 == cis4;      // Yes they point to the same object
        assert cis3.equals(cis4); // and still equals.

        // Lets test the insensitiveness
        CaseInsensitiveString cis5 = CaseInsensitiveString.valueOf("sOmEtHiNg");
        CaseInsensitiveString cis6 = CaseInsensitiveString.valueOf("SoMeThInG");

        assert cis5 == cis6;
        assert cis5.equals(cis6);

        // Futhermore
        CaseInsensitiveString cis7 = CaseInsensitiveString.valueOf("SomethinG");
        CaseInsensitiveString cis8 = CaseInsensitiveString.valueOf("someThing");

        assert cis8 == cis5 && cis7 == cis6;
        assert cis7.equals(cis5) && cis6.equals(cis8);
    }

}

C:\oreyes\samples\java\insensitive>javac CaseInsensitiveString.java


C:\oreyes\samples\java\insensitive>java -ea CaseInsensitiveString

C:\oreyes\samples\java\insensitive>

즉, CaseInsensitiveString 개체의 내부 풀을 만들고 거기에서 해당 인스턴스를 반환합니다.

이렇게하면 "=="연산자는 동일한 값을 나타내는 두 개체 참조에 대해 true 를 반환 합니다 .

이것은 유사한 객체가 매우 자주 사용되고 생성 비용이 비쌀 때 유용합니다.

문자열 클래스 문서에는 클래스가 내부 풀을 사용한다고 명시되어 있습니다.

클래스가 완전하지 않습니다. CharSequence 인터페이스를 구현할 때 객체의 내용을 살펴 보려고 할 때 몇 가지 흥미로운 문제가 발생하지만이 코드는 Book의 해당 항목이 어떻게 적용될 수 있는지 보여주기에 충분합니다.

사용하여 해당 통지하는 것이 중요합니다 internalPool의 객체를 참조가 해제되지 않습니다 때문에없는 쓰레기 수집 및 개체의 많은이 생성되는 경우 그 문제가 될 수 있습니다.

집중적으로 사용되고 풀이 "인턴 된"객체로만 구성되기 때문에 String 클래스에서 작동합니다.

가능한 값이 두 개뿐이기 때문에 Boolean 클래스에서도 잘 작동합니다.

마지막으로 이것이 Integer 클래스의 valueOf (int) 가 -128에서 127 int 값으로 제한되는 이유이기도 합니다.


3

첫 번째 예제에서, "silly"라는 문자열을 생성 한 다음 다른 문자열의 복사 생성자에 매개 변수로 전달하여 첫 번째 문자열과 동일한 두 번째 문자열을 만듭니다. 자바 문자열은 불변이기 때문에 (C 문자열에 익숙한 사람들을 자주 괴롭히는 것), 이것은 불필요한 자원 낭비입니다. 두 번째 예제는 불필요한 여러 단계를 건너 뛰기 때문에 대신 사용해야합니다.

그러나 문자열 리터럴은 CaseInsensitiveString이 아니므로 마지막 예제에서 원하는 작업을 수행 할 수 없습니다. 또한 C ++에서 할 수있는 것처럼 캐스팅 연산자를 오버로드 할 수있는 방법이 없으므로 문자 그대로 원하는 작업을 수행 할 방법이 없습니다. 대신 클래스 생성자에 매개 변수로 전달해야합니다. 물론 나는 아마도 String.toLowerCase ()를 사용하고 그것을 끝낼 것입니다.

또한 CaseInsensitiveString은 CharSequence 인터페이스뿐만 아니라 Serializable 및 Comparable 인터페이스를 구현해야합니다. 물론 Comparable을 구현하는 경우 equals () 및 hashCode ()도 재정의해야합니다.


3

String수업에 단어가 있다고 해서 기본 제공 String클래스 의 모든 특수 기능을 사용할 수있는 것은 아닙니다 .


3

CaseInsensitiveStringString포함되어 있지만 은 아닙니다 String. String문자 예 : "예"만 할당 할 수 있습니다 String.


2

CaseInsensitiveString 및 String은 다른 개체입니다. 할 수없는 일 :

CaseInsensitiveString cis = "Polish";

"Polish"는 CaseInsensitiveString이 아니라 String이기 때문입니다. String이 CaseInsensitiveString String을 확장하면 괜찮을 것이지만 분명히 그렇지 않습니다.

그리고 여기서 건설에 대해 걱정하지 마십시오. 불필요한 물건을 만들지 않을 것입니다. 생성자의 코드를 살펴보면 전달한 문자열에 대한 참조를 저장하는 것뿐입니다. 추가로 생성되는 것은 없습니다.

String s = new String ( "foobar") 경우에는 다른 작업을 수행하고 있습니다. 먼저 리터럴 문자열 "foobar"를 만든 다음 새 문자열을 구성하여 복사본을 만듭니다. 해당 사본을 만들 필요가 없습니다.


String을 확장하더라도 작동하지 않습니다. CaseInsensitiveString을 확장하려면 String이 필요합니다.
Darron

두 경우 모두 불가능합니다. 문자열이 내장되어 있거나 최종적으로 선언 되었기 때문입니다
luke

2

그들이 쓰라고 말할 때

String s = "Silly";

대신에

String s = new String("Silly");

위의 두 명령문 모두 String 객체를 생성하지만 새로운 String () 버전은 두 개의 String 객체를 생성하기 때문에 String 객체를 생성 할 때 의미합니다. 하나는 힙에 있고 다른 하나는 문자열 상수 풀에 있습니다. 따라서 더 많은 메모리를 사용합니다.

하지만 당신이 쓸 때

CaseInsensitiveString cis = new CaseInsensitiveString("Polish");

String을 생성하지 않고 CaseInsensitiveString 클래스의 객체를 생성합니다. 따라서 새 연산자를 사용해야합니다.


1

내가 그것을 올바르게 이해했다면, 귀하의 질문은 왜 우리가 직접 값을 할당하여 객체를 만들 수 없다는 것을 의미하며 java의 Wrapper of String 클래스로 제한하지 않습니다.

내가 말하고 싶은 대답을 위해, 순수하게 객체 지향 프로그래밍 언어에는 몇 가지 구조가 있으며, 단독으로 작성된 모든 리터럴은 주어진 유형의 객체로 직접 변환 될 수 있다고 말합니다.

즉, 인터프리터가 3을 확인하면 정수가 이러한 리터럴에 대해 정의 된 유형이기 때문에 Integer 객체로 변환됩니다.

인터프리터가 'a'와 같은 작은 따옴표로 된 것을 발견하면 문자 유형의 객체를 직접 생성하므로 언어가 문자 유형의 기본 객체를 정의하므로 지정할 필요가 없습니다.

유사하게 인터프리터가 ""에서 무언가를 본다면 그것은 기본 유형 즉 문자열의 객체로 간주됩니다. 이것은 백그라운드에서 작동하는 일부 네이티브 코드입니다.

이 답변에 대한 힌트를 얻은 MIT 비디오 강의 과정 6.00 덕분입니다.


0

Java에서 "text"구문은 java.lang.String 클래스의 인스턴스를 만듭니다. 할당 :

String foo = "text";

복사 생성자가 필요없는 간단한 할당입니다.

MyString bar = "text";

MyString 클래스가 java.lang.String 또는 java.lang.String의 수퍼 클래스가 아니기 때문에 무엇을하든 불법입니다.


0

첫째, String이 최종 클래스이기 때문에 String에서 확장되는 클래스를 만들 수 없습니다. 그리고 자바는 다른 클래스와 다르게 문자열을 관리하므로 문자열로만 할 수 있습니다.

String s = "Polish";

그러나 당신의 클래스는 생성자를 호출해야합니다. 그래서 그 코드는 괜찮습니다.


0

Java에 복사 생성자 가 있다고 추가합니다 .

글쎄, 그것은 인수와 같은 유형의 객체를 가진 일반 생성자입니다.


2
언어 구조가 아니라 디자인 패턴입니다. Java를 사용하면 모든 것이 항상 "참조에 의해"되고 각 객체에 하나의 사본 만 있기 때문에 복사 생성자가 흥미로운 용도가 거의 없습니다. 사실, 복사본을 만드는 것은 정말 많은 문제를 일으킬 것입니다.
Bill K

0

대부분의 JDK 버전에서 두 버전은 동일합니다.

String s = new String ( "silly");

String s = "더 이상 어리석은 일이 아닙니다";

문자열은 불변이기 때문에 컴파일러는 문자열 상수 목록을 유지하고 새 상수를 만들려고하면 먼저 문자열이 이미 정의되어 있는지 확인합니다. 그렇다면 기존의 불변 문자열에 대한 참조가 반환됩니다.

명확히하기 위해- "String s ="라고 말하면 스택에서 공간을 차지하는 새 변수를 정의하는 것입니다. 그러면 "No longer silly"또는 new String ( "silly")이라고 말하든 똑같은 일이 발생합니다. 상수 문자열이 응용 프로그램으로 컴파일되고 참조가이를 가리 킵니다.

나는 여기서 구별을 보지 못합니다. 그러나 변경할 수없는 자체 클래스의 경우이 동작은 관련이 없으며 생성자를 호출해야합니다.

업데이트 : 내가 틀렸다! 다운 투표와 첨부 된 코멘트를 바탕으로 나는 이것을 테스트했고 내 이해가 틀렸다는 것을 깨달았습니다. new String ( "Silly")은 실제로 기존 문자열을 재사용하는 대신 새로운 문자열을 생성합니다. 왜 이것이 (이점은 무엇입니까?) 불분명하지만 코드는 말보다 더 크게 말합니다!


0

String은 새 Sring 부분없이 만들 수있는 특수 클래스 중 하나입니다.

그것은 다음과 같다

int x = y;

또는

char c;


0

Java의 문자열은 불변하고 대소 문자를 구분하는 것이 기본 법칙입니다.


0
 String str1 = "foo"; 
 String str2 = "foo"; 

str1과 str2는 모두 동일한 String 객체 인 "foo"에 속합니다. b'coz Java는 StringPool에서 문자열을 관리하므로 새 변수가 동일한 문자열을 참조하는 경우 다른 변수를 생성하지 않고 StringPool에있는 동일한 alerady를 할당합니다. .

 String str1 = new String("foo"); 
 String str2 = new String("foo");

여기서 str1과 str2는 모두 다른 객체에 속합니다. b'coz new String ()은 강제로 새 문자열 객체를 만듭니다.


-1

Java는 코드에서 사용하는 각 문자열 리터럴에 대해 String 개체를 만듭니다. 언제든 ""사용하면 부르는 것과 같습니다new String() .

문자열은 기본 데이터처럼 "작용"하는 복잡한 데이터입니다. 문자열 리터럴은 우리가 그것들이 원시적 인 리터럴 인 척하더라도 실제로 객체입니다 6, 6.0, 'c',. 그래서 "literal" "text"은 value를 가진 새로운 String 객체를 반환합니다 char[] value = {'t','e','x','t}. 따라서

new String("text"); 

실제로 전화와 비슷합니다

new String(new String(new char[]{'t','e','x','t'}));

여기에서 교과서가이 중복을 고려하는 이유를 알 수 있기를 바랍니다.

참고로 다음은 String의 구현입니다. http://www.docjar.com/html/api/java/lang/String.java.html

재미있게 읽을 수 있으며 통찰력을 얻을 수 있습니다. 코드가 매우 전문적이고 규칙을 준수하는 코드를 보여주기 때문에 초보자가 읽고 이해하려고 시도하는 것도 좋습니다.

또 다른 좋은 참조는 Strings에 대한 Java 자습서입니다. http://docs.oracle.com/javase/tutorial/java/data/strings.html


""가 사용될 때 마다 상수 풀에서 동일한 문자열에 대한 참조 입니다.
Marquis of Lorne
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.