1. 우선, 문자열은 8가지 기본 데이터 유형에 속하지 않습니다.
객체의 기본값이 null이기 때문에 String의 기본값도 null이지만 이는 특수한 객체이며 다른 객체에는 없는 특성을 가지고 있습니다.
2. new String() 및 new String("")은 모두 null이 아닌 빈 문자열인 새로운 빈 문자열을 선언합니다.
3. 문자열 str="kvill";
String str=new String ("kvill");의 차이점:
여기서는 힙이나 스택에 대해 이야기하지 않고 상수 풀이라는 간단한 개념만 소개하겠습니다.
상수 풀은 컴파일 타임에 결정되어 컴파일된 풀에 저장되는 풀을 의미합니다. 클래스 파일의 일부 데이터. 여기에는 클래스, 메서드, 인터페이스 등의 상수와 문자열 상수가 포함됩니다.
예제 1을 보세요:
다음과 같이 코드 코드를 복사합니다 .
문자열 s0="kvill";
문자열 s1="kvill";
문자열 s2="kv" + "ill";
System.out.println( s0==s1 );
System.out.println( s0==s2 );
결과는 다음과 같습니다.
진실
진실
먼저, Java에서는 문자열 상수의 복사본이 하나만 존재하도록 보장한다는 점을 알아야 합니다.
예제에서 s0과 s1의 "kvill"은 모두 문자열 상수이므로 컴파일 타임에 결정되므로 s0==s1은 true이고 "kv"와 "ill"도 문자열 상수입니다. 여러 문자열 상수인 경우 그 자체가 문자열 상수여야 하므로 s2도 컴파일 타임에 문자열 상수로 구문 분석되므로 s2도 상수 풀 Quote에 있는 "kvill" 중 하나입니다.
그래서 우리는 s0==s1==s2;
new String()으로 생성된 문자열은 상수가 아니며 컴파일 타임에 결정될 수 없습니다. 따라서 new String()으로 생성된 문자열은 상수 풀에 포함되지 않으며 자체 주소 공간을 갖습니다.
예제 2를 보세요:
다음과 같이 코드 코드를 복사합니다 .
문자열 s0="kvill";
String s1=new String("kvill");
String s2="kv" + new String("ill");
System.out.println( s0==s1 );
System.out.println( s0==s2 );
System.out.println( s1==s2 );
결과는 다음과 같습니다.
거짓
거짓
거짓
예제 2에서 s0은 여전히 상수 풀에서 "kvill"의 응용 프로그램입니다. s1은 컴파일 타임에 결정될 수 없기 때문에 런타임에 생성된 새 개체 "kvill"에 대한 참조입니다. s2에는 newString의 후반부가 있습니다. ("ill"), 또한 컴파일 타임에 확인할 수 없으므로 새로 생성된 개체 "kvill"의 응용 프로그램이기도 합니다. 이를 이해하면 이러한 결과가 나오는 이유를 알 수 있습니다.
4. 문자열.인턴():
한 가지 점을 더 추가하겠습니다. 존재합니다. 클래스 파일의 상수 풀은 런타임 중에 JVM에 의해 로드되며 확장될 수 있습니다. String의 intern() 메소드는 상수 풀을 확장하는 메소드로, String 인스턴스 str이 intern() 메소드를 호출하면 Java는 상수 풀에 동일한 유니코드를 가진 문자열 상수가 있는지 확인하여 반환합니다. 그렇지 않은 경우 상수 풀에 str과 동일한 유니코드 문자열을 추가하고 해당 참조를 반환합니다. 예 3을 보면 명확해질 것입니다.
다음과 같이 코드 코드를 복사합니다 .
문자열 s0= "크빌";
String s1=new String("kvill");
String s2=new String("kvill");
System.out.println( s0==s1 );
System.out.println( "**********" );
s1.인턴();
s2=s2.intern(); //상수 풀에 있는 "kvill"의 참조를 s2에 할당합니다.
System.out.println(s0==s1);
System.out.println( s0==s1.intern() );
System.out.println( s0==s2 );
결과는 다음과 같습니다.
거짓
**********
false //s1.intern()이 실행되더라도 반환값은 s1에 할당되지 않습니다.
true //s1.intern()이 상수 풀의 "kvill"에 대한 참조를 반환함을 나타냅니다.
진실
마지막으로 또 다른 오해를 풀겠습니다.
누군가 "String.intern() 메서드를 사용하여 String 클래스를 전역 문자열 테이블에 저장합니다. 동일한 값을 가진 유니코드 문자열이 이미 이 테이블에 있으면 이 메서드는 이미 테이블에 있는 문자열을 반환합니다. 주소, 테이블에 같은 값을 가진 문자열이 없으면 테이블에 자신의 주소를 등록하세요. "그가 상수 풀이라고 말한 전역 문자열 테이블을 이해하면 그의 마지막 문장은 "If there is no string with the table"입니다. 테이블에 같은 값이 있으면 테이블에 자신의 주소를 등록하는 것은 잘못된 것입니다.
예제 4를 보세요:
다음과 같이 코드 코드를 복사합니다 .
String s1=new String("kvill");
문자열 s2=s1.intern();
System.out.println( s1==s1.intern() );
System.out.println( s1+" "+s2 );
System.out.println( s2==s1.intern() );
결과는 다음과 같습니다.
거짓
크빌 크빌
진실
이 클래스에서는 "kvill" 상수를 선언하지 않았기 때문에 처음에는 상수 풀에 "kvill"이 없었습니다. s1.intern()을 호출했을 때 새로운 "kvill" 상수가 상수 풀에 추가되었습니다. 상수 풀에 없는 "kvill"이 여전히 존재하는 것으로 나타났는데, 이는 "자신의 주소를 상수 풀에 등록"하고 있지 않음을 의미합니다.
s1==s1.intern()은 false입니다. 이는 원래 "kvill"이 여전히 존재함을 나타냅니다.
s2는 이제 상수 풀의 "kvill" 주소이므로 s2==s1.intern()은 true입니다.
5. equals() 및 == 정보:
String의 경우 이는 단순히 두 문자열의 유니코드 시퀀스가 동일한지 비교하고 동일하면 true를 반환하며 ==는 두 문자열의 주소가 동일한지, 즉 참조인지 비교하는 것입니다. 같은 문자열에.
6. 문자열은 변경할 수 없습니다.
String 인스턴스가 일단 생성되면 변경되지 않는다는 점을 알고 있는 한 이에 대해 할 말이 많습니다. 예를 들면 다음과 같습니다. String str="kv"+"ill"+" "+"ans";
문자열 상수는 4개가 있는데, 먼저 "kv"와 "ill"이 메모리에 저장되는 "kvill"을 생성하고, "kvill"이 "kvill"을 생성하여 메모리에 저장된다. "kvill ans"와 결합되어 "kvill ans"를 생성하고 이 문자열의 주소를 str에 할당합니다. String의 "불변성"은 많은 임시 변수를 생성하므로 StringBuffer를 사용하는 것이 좋습니다. 변하기 쉬운.