>Java >java지도 시간 >Java의 String 클래스 예제 튜토리얼 요약

Java의 String 클래스 예제 튜토리얼 요약

零下一度
零下一度원래의
2017-05-22 11:03:081358검색

여기서 String 클래스와 관련된 모든 측면을 요약해야 하기 때문에 SCJP 질문도 몇 가지 제공합니다. 부족한 점 있으면 댓글로 알려주시면 감사하겠습니다.
1. 고정 모드:
문자열 개체가 생성된 후에는 해당 값을 변경할 수 없습니다.

String str1="hello";//创建一个对象hello,不会变;
System.out.println(str1);
str1+=" world!";//两个字符串对象粘粘,系统其实创建了一个新的对象,把Str1的指向改了,指向新的对象;hello就                     //变成了垃圾;
System.out.println(str1);

//이렇게 계속 생성하면 시스템 효율성에 영향을 미치게 됩니다. 문자열 개체의 값을 자주 변경하려면 StringBuffer를 사용하여 설명하세요. >

StringBuffer sb=new StringBuffer("[");
sb.append("hehe");
sb.append("]");//append();不会制造垃圾,真正在改sb的值;
System.out.println(sb);

2. Object Pool


먼저 Object obj = new Object();

obj는 객체에 대한 참조라는 점을 이해해야 합니다. 스택에 위치하며 new Object()는 힙에 위치하는 객체입니다.

obj는 수소 풍선에 묶인 밧줄이고, new Object()는 수소 풍선인 것을 알 수 있습니다. 밧줄을 잡고 있는 것처럼 객체의 참조를 통해 객체에 접근합니다. 수소 풍선이 도망가는 것을 방지합니다.

Stirng 객체를 생성하는 두 가지 주요 방법이 있습니다:

java 代码
String str1 = new String("abc");    
Stirng str2 = "abc";

두 명령문 모두 String 객체에 대한 참조를 반환하지만 jvm은 둘 다 처리합니다. 첫 번째 유형의 경우 jvm은 즉시 힙에 String 객체를 생성한 다음 해당 객체의 참조를 사용자에게 반환합니다. 두 번째 유형의 경우 JVM은 먼저 내부적으로 유지 관리되는 문자열 풀에서 String의 equals 메소드를 사용하여 String 객체가 객체 풀에 저장되어 있는지 확인합니다. 그렇다면 기존 String 객체가 사용자에게 반환됩니다.

대신에 새로운 String 객체가 힙에 다시 생성됩니다. 객체 풀에 그러한 String 객체가 없으면 jvm은 힙에 새로운 String 객체를 생성하고 해당 참조를 사용자에게 반환하며 참조를 추가합니다. 문자열 똥
l in. 참고: 첫 번째 방법을 사용하여 객체를 생성할 때 프로그램이 String의 인턴 메소드를 호출하지 않는 한 jvm은 객체를 문자열 풀에 적극적으로 넣지 않습니다. 다음 예를 살펴보세요.
java code
String str1 = new String("abc"); //jvm은 힙에 String 객체를 생성합니다.

//jvm은 문자열에서 찾을 수 없습니다. pool 값이 "abc"인 문자열이므로
//힙에 String 객체를 생성하고 해당 객체의 참조를 문자열에 추가합니다. pool
//현재 힙에는 두 개의 String 객체가 있습니다.

Stirng str2 = "abc";   //并没有创建对象,因为对象池里已经有"abc" 了
  
 if(str1 == str2){   
         System.out.println("str1 == str2");   
 }else{   
         System.out.println("str1 != str2");   
 }

//인쇄 결과는 str1 != str2입니다. 왜냐하면 둘은 힙에 있는 두 개의 서로 다른 객체이기 때문입니다.

 String str3 = "abc";

//이때 jvm은 다음을 발견했습니다. 문자열 풀 "abc" 객체에는 이미 문자열이 있습니다. 왜냐하면 "abc"는 "abc"와 같기 때문입니다.

//그러므로 str2가 가리키는 객체를 str3에 직접 반환합니다. 즉, str2와 str3은 str2와 str3을 가리키는 참조입니다. 동일한 객체


if(str2 == str3){   
         System.out.println("str2 == str3");   
  }else{   
         System.out.println("str2 != str3");   
  }

//인쇄 결과는 str2 == str3

3. String / StringBuffer / StringBuilder

String 클래스는 문자열 상수이므로 변경할 수 없습니다. StringBuffer는 문자열 변수이며 해당 개체를 확장하고 수정할 수 있습니다.

StringBuffer sb=new StringBuffer("[");//创建StringBuffer对象
sb.append("hehe");//把hehe加入字符串,变成 "[hehe"
sb.append("]");//append();不会制造垃圾,真正在改sb的值;
System.out.println(sb);
String str = sb.toString();//把"[hehe]",赋值给一个字符串对象str

StringBuilder, 가변 문자 시퀀스입니다. 이 클래스는 StringBuffer 호환 API를 제공하지만 동기화를 보장하지는 않습니다. 이 클래스는 문자열 버퍼가 단일 스레드에서 사용될 때(매우 일반적임) StringBuffer에 대한 드롭인 대체품으로 사용되도록 설계되었습니다. 대부분의 구현에서 StringBuffer보다 빠르므로 가능하면 이 클래스를 선호하는 것이 좋습니다.

StringBuilder sb=new StringBuilder("[");//创建StringBuilder对象
sb.append("hehe");//把hehe加入字符串,变成 "[hehe"
sb.append("]");//append();不会制造垃圾,真正在改sb的值;
System.out.println(sb);
String str = sb.toString();//把"[hehe]",赋值给一个字符串对象str

4. String 클래스에서 일반적으로 사용되는 메서드
String 클래스에는 시퀀스의 개별 문자 확인, 문자열 비교, 문자열 검색, 하위 문자열 추출 및 생성에 사용할 수 있는 메서드가 포함되어 있습니다. strings 모든 문자를 복사하여 대문자 또는 소문자로 변환합니다. 외울 필요는 없고, 필요할 때

API를 찾아보면 많이 사용하면 익숙해질 것입니다.


java.lang.String
 char charAt (int index) 返回index所指定的字符
 String concat(String str) 将两字符串连接
 boolean endsWith(String str) 测试字符串是否以str结尾
 boolean equals(Object obj) 比较两对象
 char[] getBytes 将字符串转换成字符数组返回
 char[] getBytes(String str) 将指定的字符串转成制服数组返回
 boolean startsWith(String str) 测试字符串是否以str开始
 int length() 返回字符串的长度
 String replace(char old ,char new) 将old用new替代
 char[] toCharArray 将字符串转换成字符数组
 String toLowerCase() 将字符串内的字符改写成小写
 String toUpperCase() 将字符串内的字符改写成大写
 String valueOf(Boolean b) 将布尔方法b的内容用字符串表示
 String valueOf(char ch) 将字符ch的内容用字符串表示
 String valueOf(int index) 将数字index的内容用字符串表示
 String valueOf(long l) 将长整数字l的内容用字符串表示
 String substring(int1,int2) 取出字符串内第int1位置到int2的字符串
[java] view plain copy
import java.util.Collections;  
import java.util.Comparator;  
import java.util.LinkedList;  
import java.util.List;  
public class StringUsage {  
 // 几个欧不太用的方法。  
 public static void main(String[] args) {  
  // 判断字符串首/尾。  
  String contentS = "test String again. test ";  
  System.out.println(contentS);  
  System.out.println("contentS.startsWith(/"test/")/t"  
    + contentS.startsWith("test"));  
  System.out.println("contentS.endsWith(/"test/")/t"  
    + contentS.endsWith("test"));  
  // 忽略大小写的字符串比较方法。  
  System.out  
    .println("contentS.compareToIgnoreCase(contentS.toUpperCase()))/t"  
      + contentS.compareToIgnoreCase(contentS.toUpperCase()));  
  // 不区分大小写的字符串比较。  
  Comparator<String> cmprStr = String.CASE_INSENSITIVE_ORDER;  
  List<String> lstStr = new LinkedList<String>();  
  // 准备数据。  
  lstStr.add("test");  
  lstStr.add("Test");  
  lstStr.add("tEst");  
  lstStr.add("rest");  
  lstStr.add("sest");  
    
  // 不区分大小写的排序。  
  Collections.sort(lstStr, cmprStr);  
  System.out.println(lstStr);  
  // 区分大小写的排序。  
  Collections.sort(lstStr);  
  System.out.println(lstStr);  
  System.out.println("/ntest String.valueOf()");  
    
  // 用 valueOf 处理 null 对象的字符串转换。  
  try {  
   String ss = null;  
   System.out.println(ss);  
   System.out.println(String.valueOf(null)); // 比较奇怪的地方  
  } catch (RuntimeException e1) {  
      e1.printStackTrace();  
  }  
    
  BigDecimal db = null;  
  try {  
   System.out.println(((BigDecimal)db).toString());  
  } catch (Exception e) {  
   e.printStackTrace();  
  }  
  try {  
   System.out.println(String.valueOf(db));  
  } catch (Exception e) {  
   e.printStackTrace();  
  }  
  db = new BigDecimal("100.00");  
  try {  
   System.out.println(((BigDecimal)db).toString());  
  } catch (Exception e) {  
   e.printStackTrace();  
  }  
 }  
}

5. SCJP 질문

String a="Hello World!";
String b="Hello World!";
a=b?  a和b是否相等 ? 为什么?
String a=new String("Hello World!");
String b="Hello World!";
a=b?  a和b是否相等 ? 为什么?

설명:
첫째, String은 8가지 기본 데이터 유형에 속하지 않습니다. 객체입니다.

객체의 기본값이 null이기 때문에 String의 기본값도 null이지만 이는 특수한 객체이며 다른 객체에는 없는 특성을 가지고 있습니다.


2. new String()과 new String("")은 모두 null이 아닌 빈 문자열을 선언합니다.

3.
String str=new String (“kvill”); 차이점:
여기에서는 힙이나 스택에 대해 이야기하지 않고 상수 풀의 간단한 개념을 간략하게 소개합니다.
상수 풀은
컴파일 중에 결정되어 컴파일된 .class 파일에 저장되는 일부 데이터를 의미합니다. 여기에는 클래스, 메서드, 인터페이스 등의 상수와 문자열 상수가 포함됩니다.
예 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”的应用,s1因为无法在编译期确定,所以是运行时创
建的新对象”kvill”的引用,s2因为有后半部分new String(“ill”)所以也无法在编译
期确定,所以也是一个新创建对象”kvill”的应用;明白了这些也就知道为何得出此结果了。  
4. String.intern():  
再补充介绍一点:存在于.class文件中的常量池,在运行期被JVM装载,并且可以扩充。String的intern()方法就是扩充常量池的一个方法;当一个String实例str调用intern()
方法时,Java查找常量池中是否有相同Unicode的字符串常量,如果有,则返回其的引用,如果没有,则在常量池中增加一个Unicode等于str的字符串并返回它的引用;看例3就清楚了。 
例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.intern()方法则可以将一个String类的保存到一个全局Strin
g表中,如果具有相同值的Unicode字符串已经在这个表中,那么该方法返回表中已有字符串的地址,如果在表中没有相同值的字符串,则将自己的地址注册到表中“如果我把
他说的这个全局的String表理解为常量池的话,他的最后一句话,“如果在表中没有相同值的字符串,则将自己的地址注册到表中”是错的:  

看例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"常量,所以s1.intern()同new String("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是可 font-family: Arial;font-size:12px;">改变的。</span> <span style="color: rgb(51, 51, 153); font-family: Arial;font-size:12px;"> </span> <span style="color: rgb(51, 51, 153); font-family: Arial;font-size:12px;">

【相关推荐】

1. java中String是对象还是类?详解java中的String

2. 分享Java中String类的实例教程

3. Java中String类的常用方法是什么?总结Java中String类的常用方法

4. 分享java String部分源码解读

위 내용은 Java의 String 클래스 예제 튜토리얼 요약의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.