String对象的几个理解

来源:互联网 发布:手机淘宝网上怎么直播 编辑:程序博客网 时间:2024/06/13 18:04
一、关于String对象
关于String对象,bbs上争论不休。
现在倾向的解释是:String s = “abc”;这个语句中s是一个引用,它指向对象”abc”。这样一来,下面的语句:
String s1 = “abc”;
String s2 = “abc”;只产生了一个对象,即:”abc”。
而String s = new String(“abc”);这个语句中s是一个对象。下面的语句:
String s1 = new String(“abc”);
String s2 = new String(“abc”);就产生了两个对象,它们是s1和s2。
有了上面的解释,我们就不难理解,为什么我们优先在代码中使用前一种表达方式,因为前一种方式是引用,不论你在代码中要使用多少个相同的引用,只产生一个对象。而后一种方式则即使多个对象的内容一样,它们也是不同的对象,有各自的内存开销;这就大大的增加了我们内存的开销。
同样,下面的代码以及它们的运行结果也就能解释了。
String s1 = "abc";
String s2 = "abc";
String s3 = new String("abc");
代码:System.out.println(s1==s2);
运行结果:true
代码:System.out.println(s1=="abc");
运行结果:true
代码:System.out.println(s1.equals(s2));
运行结果:true
代码:System.out.println(s1==s3);
运行结果:false
代码:System.out.println(s3.equals("abc"));
运行结果:true

二、String与StringBuffer的区别
既然语句:String s = “abc”;中的s是一个引用。那么,在下面的语句:
String s = “abc”;
s = s+”d”;中,就应该有三个对象:”abc”、”d”和”abcd”。引用s先是指向对象”abc”,后指向对象”abacd”。
这样,我们就能看出String和StringBuffer的区别来。对于下面的代码:
String s = “”;
for(int i=0;i<10;i++){
        s = s+i;
}
我们将产生10多个对象。而下面的代码:
StringBuffer sb = new StringBuffer();
for(int i=0;i<10;i++){
       sb.append(i);
}
只产生一个对象。
所以,在String对象需要进行相加的时候,使用StringBuffer要明显比使用String优越,特别是在循环相加的时候。
 
三、其他基本类型与String的转化
在实际的编码过程中,经常要将其他的基本类型转化为String类型,如上面的我们所常用到的例子:
String s = “”;
for(int i=0;i<10;i++){
        s = s+i;
}
中,s = s+i;语句中就需要将整型数据i转化为字符串,然后再与s相加。
其实,除了s = s+1;的这种转化方式,还有一种我们大家所不常用到的转化方式,如下:
s = s+Integer.toString(1);
经过大家对对上面两种转化方法所耗时间的测试,结果发现后面一种转化方式所耗的时间大大低于前面一种转化方式所耗的时间
所以大家在编码的过程中,不妨使用后面的一种转化方式。
 
四、Object类的toString()的重载
toString()方法是Object类的一个公有方法,Object类是Java所有类的父类。因此,任何其他的Java类都能重写该方法,为己所用。例如,所有的基本类型的包装类,如:Integer、Float、Double等等,都重写了toString()方法,功能是将该类型转化为String类型。
对toString()的重写一般用来提供一些关于这类的基本信息。如对于一个复数类,如下:
public class Complex{
        private double real;
        private double image;
        ……
}
它的toString()方法可以写为:
public String toString(){
        String ri = “”;
        if(this.image<0){
               ri = ri+”-”+Double.toString(Math.abs(this.image))+”i”;
        }
        else{
               ri = ri+”+”Double.toString(this.image)+”i”;
        }
        return Double.toString(this.real)+ri;
}
上面的这个toString()方法刚好表达了一个复数的数学表达式,这恰恰是我们在对复数做完运算以后希望得到的结果。
又如,对于一个员工类:Employee。我们最常用的、最希望看到的常常是他们的姓名,如下:
public class Employee{
        private String firstName;
        private String secodeName;
        ……
        public String toString(){
               return this.firstName+this.secodeName;
       }
……
}
所以,在一些类中,重写toString()方法是很有用的,可作为显示数据,也可用在调试语句中。
 
五、逃逸字符的问题
逃逸字符:在HTML编程中遇到“>”或“<”的话,浏览器会将它们作为HTML的保留字符,如标签的开始符和结束符来看待,这样就会出现一些错误。又如在JDBC编程中的sql语句中,如果出现了“””或者“’”等引号字符,也会出错,sql语句会把它们当作一个sql语句的开始或结束符。还有,如URL语句中的“?”等字符,也会造成URL表达式的混乱,等等。遇到了上面的这些情况,我们都自己找一些特殊字符对它们加以替换,然后用完后又替换回来,这些特殊的字符就是逃逸字符。但是去找逃逸字符比较麻烦,而且容易出错,易出现把逃逸字符张冠李戴的情况。
鉴于此,Jakarta Commons包为我们提供了一套关于逃逸字符的解决方案,使用这个方案,我们不需要自己亲自去查找逃逸字符,只需要调用Jakarta Commons包的API即可,如下所示:
String s = "There is always < (less) or > (more) than you want.";
String s1 = StringEscapeUtils.escapeHtml(s);
System.out.println(s1);
String s2 = StringEscapeUtils.unescapeHtml(s1);
System.out.println(s2.equals(s));
System.out.println(s2);
输出结果:
There is always &lt; (less) or &gt; (more) than you want.
true
There is always < (less) or > (more) than you want.
是不是很简单,我们只需要在上面的代码中引入Jakarta Commons的相应的包即可。
 
六、中英文拆字的问题
关于中英文混合句子拆字的问题,在bbs上看到一个解决方法,觉得很有意思。我们都知道,Java采用的是Unicode编码,所有的字符都占有一个字,两个字节。那么我们在一个中英文混合的句子中,怎么抽取出来一个个的汉语词语和英语单词呢?
下面就是一个简单的解决方法:
String s = "我是中ab国人";
        byte[] bt = s.getBytes();
        int i=0;
       while(i<bt.length){
               String ss;
               if(bt[i]<0){
                      ss = new String(bt,i,2);
                      i += 2;
               }
               else{
                      ss = new String(bt,i,1);
                      i++;
               }
               System.out.println(ss);
        }
输出结果为:



a
b


附:Java里面所有的字符(包括String, char)都是unicode编码的(例外的是,Character是32bit编码的,当然Java语言本身提供了转换机制),我们看到的每个字符,无论是中文还是英文(或者别的什么语言的字符),都可以用一个char来表示,所以,下面的代码段是一样的效果:
        String s = "我是中ab国人";
        for(int i = 0; i < s.length(); i ++)
            System.out.println(s.charAt(i));

关于那个Integer.toString(i)比""+i快的问题,应该是调用静态方法的原因,省了时间。
根据the Java Programming Language(4th Edition)
One special type of implicit conversion involves both the primitive and reference types: string conversion. Whenever a + operator has at least one String operand, it is interpreted as the string concatenation operator and the other operand, if not a String, is implicitly converted into aString. Such conversions are predefined for all primitive types.
因此,在这里+符号表示concatenation操作,右端的i作为非String类型的operand必须按照预先定义的方式进行转换。
查阅the Java Language Specification(3rd Edition),可以知道转换的细节:
A value x of primitive type T is first converted to a reference value as if by giving it as an argument to an appropriate class instance creation expression:
If T is byte, short, or int, then use new Integer (x).
所以""+i在执行时,由编译器隐式地调用new Integer(i),先生成一个Integer对象,再调用这个对象的toString()方法,得到+运算符需要的String对象;
Integer.toString(i)是一个static方法,由i直接获得String对象,不需要生成Integer对象,因此快许多。
0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 报考驾照时电话填错了怎么办 邢台开三轮车驾证扣12分怎么办 新c1驾照扣满6分怎么办 b2驾照酒驾降级后再次酒驾怎么办 我b2驾照扣了9分怎么办 开别人的车出了事故怎么办 骑摩托车行驶证年检过期了怎么办 在两个城市车船税交重复了怎么办 车子被撞对方全责不赔钱怎么办 驾驶证暂扣期间该审证了怎么办 号码预约被不小心取消了怎么办 老婆出轨要跟我离婚我不想离怎么办 老婆要离婚我不想离电话拉黑怎么办 驾驶证到期换证体检有色弱怎么办 在长沙雨花区考的驾照丢了怎么办 两个户口注销了一个驾证怎么办 车管所发的初始密码弄丢了怎么办? 网上预约驾照考试密码忘记了怎么办 车是温州牌照掉了行驶证怎么办? 触犯了刑法第80条伪造印章怎么办 使用假行驶证被交警查扣车怎么办 摩托车被交警扣了没行驶证怎么办 摩托车行驶证丢了被交警抓到怎么办 摩托车没有行驶证被交警扣了怎么办 有小车执照要大在执照怎么办 报考的南京驾照不退学费怎么办 驾照报名可以退吗?不退怎么办 科目三学时已满公里数未满怎么办 预约驾照考试收不到验证码怎么办 a2驾照违章被扣24分怎么办 出车祸后划分赔偿对方不鉴字怎么办 驾驶证过期了被交警抓到怎么办 摩托车驾驶证6年到期在增驾怎么办 驾照年检时色盲图过不了怎么办 驾驶证扣12分超过两年怎么办 驾驶证被注销后超过两年怎么办 a2照驾驶证年审过期一个月怎么办 车被别人追尾行驶证过期怎么办 骑魔头车没驾照车祸保险拒赔怎么办 行驶证过了两个多月没年检怎么办 驾照没满一年扣了3分怎么办