Java的String类在开发时经常都会被使用到,由此可见String的重要性。经过这次认真仔细的学习了java的String类。发现了自己以前开发中对String使用的不足,特写此博客来记录自己对String的学习总结。

首先String不属于8种基本数据类型,String是一个对象。 因为对象的默认值是null,所以String的默认值也是null;但它又是一种特殊的对象,有其它对象没有的一些特性。

String实际上是使用字符数组来存储的数据的。从源码可以清晰看到定义的字符数组。

String在java/lang包下面,java默认导入lang包,所以使用String类时不用导入。

1.创建方式

(1)String ok1=new String(“ok”);
(2)String ok2=“ok”;
我相信很多人都知道这两种方式定义字符串,但他们之间的差别又有多少人清楚呢。画出这两个字符串的内存示意图:

      String ok1=new String(“ok”)。首先会在堆内存申请一块内存存储字符串ok,ok1指向其内存块对象。同时还会检查字符串常量池中是否含有ok字符串,若没有则添加ok到字符串常量池中。所以 new String()可能会创建两个对象.
     String ok2=“ok”。 先检查字符串常量池中是否含有ok字符串,如果有则直接指向, 没有则在字符串常量池添加ok字符串并指向它.所以这种方法最多创建一个对象,有可能不创建对象
所以String ok1=new String(“ok”);//创建了两个对象

String ok2=“ok”;//没有创建对象
 
来两题习题看你是否真的明白了
1.下面代码创建了多少个对象?

  1. String temp="apple";
  2. for(int i=0;i<1000;i++)
  3. {
  4. temp=temp+i;
  5. }

答案:1001个

2.下面代码创建了多少个对象?

  1. String temp=new String("apple")
  2. for(int i=0;i<1000;i++)
  3. {
  4. temp=temp+i;
  5. }

答案:1002个

 
2.匹配相等
       使用String类经常需要对两个字符串进行对比,看是否相等。这是又有==和equals两种选择,这两者方法区别很大,可能我们会弄错,下面我们对这两种方法进行详解。
      首先要明白这两种方法的用途:
比较类中的数值是否相等使用equals(),比较两个包装类的引用是否指向同一个对象时用==
equals()是看数值是否相等,比较好理解。而==是看是否属于同一个对象。下面来举例说明==的使用
先明白这个概念:常量池在java用于保存在编译期已确定的,已编译的class文件中的一份数据。主要看编译  期字符串能否确定。
情况一:
  1. String ok="ok";
  2. String ok1=new String("ok");
  3. System.out.println(ok==ok1);//fasle

明显不是同一个对象,一个指向字符串常量池,一个指向new出来的堆内存块,new的字符串在编译期是无法确定的。所以输出false

情况二:
  1. String ok="apple1";
  2. String ok1="apple"+1;
  3. System.out.println(ok==ok1);//true

编译期ok和ok1都是确定的,字符串都为apple1,所以ok和ok1都指向字符串常量池里的字符串apple1。指向同一个对象,所以为true.

情况三:
  1. String ok="apple1";
  2. int temp=1;
  3. String ok1="apple"+temp;
  4. System.out.println(ok==ok1);//false

主要看ok和ok1能否在编译期确定,ok是确定的,放进并指向常量池,而ok1含有变量导致不确定,所以不是同一个对象.输出false

情况四:
  1. String ok="apple1";
  2. final int temp=1;
  3. String ok1="apple"+temp;
  4. System.out.println(ok==ok1);//true

ok确定,加上final后使得ok1也在编译期能确定,所以输出true

情况五:
  1. public static void main(String[] args) {
  2. String ok="apple1";
  3. final int temp=getTemp();
  4. String ok1="apple"+temp;
  5. System.out.println(ok==ok1);//false
  6. }
  7. public static int getTemp()
  8. {
  9. return 1;
  10. }

ok一样是确定的。而ok1不能确定,需要运行代码获得temp,所以不是同一个对象,输出false。

 
3.Intern()方法
前面已经介绍常量池在java用于保存在编译期已确定的,已编译的class文件中的一份数据。
但我们可以通过intern()方法扩展常量池。
         intern()是扩充常量池的一个方法,当一个String实例str调用intern()方法时,java会检查常量池中是否有相同的字符串,如果有则返回其引用,如果没有则在常量池中增加一个str字符串并返回它的引用。
如:
  1. String ok="apple";
  2. String ok1=new String("apple");
  3. System.out.println(ok==ok1);//false
  4. ok1=ok.intern();//获取常量池ok的引用
  5. System.out.println(ok==ok1);//true--指向同一个对象

 
4.String常用方法
(1)length() 字符串的长度 
  例:char chars[]={'a','b'.'c'}; 
    String s=new String(chars); 
    int len=s.length();

(2)charAt() 截取一个字符 
  例:char ch; 
    ch="abc".charAt(1); 返回'b'

(3)getBytes()获取对应字节数组
        例:String ok="apple";
               byte[]bytes=ok.getBytes();
               for(int i=0;i<bytes.length;i++)
                     System.out.println(bytes[i]);//输出字节数组,范围为-128---127
(4)indexOf()和lastIndexOf() 
      indexOf() 查找字符或者子串第一次出现的地方。 
      lastIndexOf() 查找字符或者子串是后一次出现的地方。
(5)substring()  
           它有两种形式,第一种是:String substring(int startIndex) 
         第二种是:String substring(int startIndex,int endIndex)
(6)concat()     连接两个字符串
(7)replace() 替换 
  它有两种形式,第一种形式用一个字符在调用字符串中所有出现某个字符的地方进行替换,形式如下: 
  String replace(char original,char replacement) 
  例如:String s="Hello".replace('l','w'); 
  第二种形式是用一个字符序列替换另一个字符序列,形式如下: 
  String replace(CharSequence original,CharSequence replacement)
(8)trim() 去掉起始和结尾的空格

(9)valueOf() 转换为字符串

(10)toLowerCase() 转换为小写

(11)toUpperCase() 转换为大写

(12)startsWith()和endsWith()  
        startsWith()方法决定是否以特定字符串开始,endWith()方法决定是否以特定字符串结束
更多方法请参考String的API
总结
         String类具有immutable(不能改变)性质,当String变量需要经常变换时,会产生很多变量值,应考虑使用StringBuffer提高效率。在开发时,注意String的创建方法。
 
    转自http://longpo.iteye.com/blog/2199493

最新文章

  1. CSP -- 运营商内容劫持(广告)的终结者
  2. Sublime Text 3 高效编码快捷键
  3. jquery 跨域访问问题 转
  4. mybatis实战教程(mybatis in action)之五:与spring3集成
  5. 原生JavaScript技巧大收集(11~20)-(终于又被我找到这篇文章了)
  6. Tarjan算法详解理解集合
  7. android studio adb
  8. PHP、C++的重载
  9. Android开发之获取系统管理权限,即DevicePolicyManager和DeviceAdminReceiver的使用
  10. ScheduledExecutorService的用法——定时执行两个任务
  11. 提高查询速度:SQL Server数据库优化方案
  12. (转)使用pth文件,让python方便的import自己写的模块
  13. Deep Clone 常用方式总结
  14. Windows Azure HDInsight 现已正式发布!
  15. IE过滤器
  16. springboot接口返回封装与异常控制
  17. Linux机器重启情况查询
  18. lvm语法2
  19. java的四个基本特征
  20. Codeforces Round #424 (Div. 2, rated, based on VK Cup Finals) D. Office Keys time limit per test2 seconds 二分

热门文章

  1. 几行css3代码实现超炫加载动画
  2. php爬虫实践
  3. Log4j和thymeleaf结合导致sql 日志输出不了
  4. linux gpio控制之sysfs接口
  5. hadoop 1.1.2和 hive 0.10 和hbase 0.94.9整合
  6. The declared package &amp;quot;com.dao&amp;quot; does not match the expected package &amp;quot;src.com.dao&amp;quot;
  7. Game Loop的几种实现方式
  8. 【转】JS函数集合大全
  9. Java并发编程基础
  10. (转)SDL1.2到2.0的迁移指南