1. 우선 String은 8가지 기본 데이터 유형에 속하지 않습니다.
객체의 기본값이 null이기 때문에 String의 기본값도 null이지만 특수 객체이고 다른 객체에 없는 특성이 있습니다.
2. new String()과 new String("")은 모두 null이 아닌 빈 문자열을 선언합니다.
3.
String str=new String ("kvill"); 차이점:
여기서는 힙이나 스택에 대해 이야기하지 않고 상수 풀의 간단한 개념을 간략하게 소개합니다.
상수 풀은 컴파일 타임에 결정되어 컴파일된 풀에 저장되는 풀을 말합니다. 클래스 파일의 일부 데이터. 여기에는 클래스, 메서드, 인터페이스 등의 상수와 문자열 상수가 포함됩니다.
예 1 보기:
String s0="kvill"; String s1="kvill"; String s2="kv" + "ill"; System.out.println( s0==s1 ); System.out.println( s0==s2 );
결과는 다음과 같습니다.
true
true
우선, Java가 다음을 보장한다는 결과를 알아야 합니다. 문자열 상수의 복사본은 하나만 있습니다.
예제에서 s0과 s1의 "kvill"은 모두 문자열 상수이므로 컴파일 타임에 결정되므로 s0==s1은 true이고 "kv" 및 "ill"도 문자 문자열 상수입니다. 문자열은 여러 문자열 상수로 연결되며 그 자체가 문자열 상수여야 하므로 s2도 컴파일 타임에 문자열 상수로 구문 분석되므로 s2는 상수 풀 "에 대한 참조"의 "kvill"이기도 합니다.
따라서 s0==s1==s2;
new String()으로 생성된 문자열은 상수가 아니며 컴파일 타임에 결정될 수 없으므로 new String()으로 생성된 문자열은 다음을 포함하지 않습니다. 상수 풀에는 자체 주소 공간이 있습니다.
예제 2 보기:
String 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 );
결과는 다음과 같습니다.
false
false
false
예제 2에서 s0은 여전히 상수에서 "kvill"을 적용한 것입니다. pool이며 s1은 사용할 수 없습니다. 컴파일 타임에 결정되므로 런타임에 생성된 새 개체 "kvill"에 대한 참조입니다. s2에는 newString("ill")의 후반부가 있으므로 시간에 결정할 수 없습니다. 컴파일 시간이므로 새로 생성된 개체 "kvill"의 응용 프로그램이기도 합니다. 이 내용을 이해하면 왜 이런 결과가 나오는지 이해할 수 있습니다.
4. String.intern():
한 가지 더 추가하겠습니다. 클래스 파일의 상수 풀은 런타임 중에 JVM에 의해 로드되며 확장될 수 있습니다. String의 intern() 메소드는 상수 풀을 확장하는 메소드로, String 인스턴스 str이 intern() 메소드를 호출하면 Java는 상수 풀에 동일한 유니코드를 가진 문자열 상수가 있는지 확인하여 반환합니다. 그렇지 않은 경우 상수 풀에 str과 동일한 유니코드 문자열을 추가하고 해당 참조를 반환합니다.
예제 3:
String s0= "kvill"; String s1=new String("kvill"); String s2=new String("kvill"); System.out.println( s0==s1 ); System.out.println( "**********" ); s1.intern(); s2=s2.intern(); //把常量池中"kvill"的引用赋给s2 System.out.println( s0==s1); System.out.println( s0==s1.intern() ); System.out.println( s0==s2 );
결과는 다음과 같습니다. 🎜>false
**********
false //s1.intern()이 실행되더라도 반환 값은 s1에 할당되지 않습니다.
true //s1.intern임을 나타냅니다. ()는 풀의 "kvill"에 대한 상수 참조를 반환합니다
true
마지막으로 또 다른 오해를 풀겠습니다.
누군가 "String 클래스를 String 클래스에 저장하려면 String.intern() 메서드를 사용하세요"라고 말했습니다. 전역 문자열 테이블, 동일한 값을 가진 유니코드 문자열이 이미 이 테이블에 있으면 이 메서드는 테이블에 이미 있는 문자열의 주소를 반환합니다. 테이블에 동일한 값을 가진 문자열이 없으면 그가 상수 풀로 언급한 글로벌 스트링 테이블을 내가 이해한다면, 그의 마지막 문장인 "테이블에 같은 값을 가진 문자열이 없으면 테이블에 자신의 주소를 등록하라"는 문장이 틀린 것이다.
예 4 참조:
String s1=new String("kvill"); String s2=s1.intern(); System.out.println( s1==s1.intern() ); System.out.println( s1+" "+s2 ); System.out.println( s2==s1.intern() );
结果为:
false
kvill kvill
true
在这个类中我们没有声名一个"kvill"常量,所以常量池中一开始是没有"kvill"的,当我们调用s1.intern()后就在常量池中新添加了一个"kvill"常量,原来的不在常量池中的"kvill"仍然存在,也就不是"将自己的地址注册到常量池中"了。
s1==s1.intern()为false说明原来的"kvill"仍然存在;
s2现在为常量池中"kvill"的地址,所以有s2==s1.intern()为true.
5. 关于equals()和==:
这个对于String简单来说就是比较两字符串的Unicode序列是否相当,如果相等返回true;而==是比较两字符串的地址是否相同,也就是是否是同一个字符串的引用。
6. 关于String是不可变的
这一说又要说很多,大家只要知道String的实例一旦生成就不会再改变了,比如说:String str="kv"+"ill"+" "+"ans";
就是有4个字符串常量,首先"kv"和"ill"生成了"kvill"存在内存中,然后"kvill"又和" " 生成 "kvill "存在内存中,最后又和生成了"kvill ans";并把这个字符串的地址赋给了str,就是因为String的"不可变"产生了很多临时变量,这也就是为什么建议用StringBuffer的原因了,因为StringBuffer是可改变的。
更多Java中的String对象数据类型全面解析相关文章请关注PHP中文网!