美文网首页
Java编程思想笔记---String

Java编程思想笔记---String

作者: 东方小貔貅 | 来源:发表于2020-09-28 10:44 被阅读0次

    String

    1、String对象是不可变的。
    2、String类中每一个看起来会修改String值得方法,实际上都是创建一个全新的String对象,以包含修改后的字符串内容。最初的String对象丝毫未动。
    3、方法调用,String为参
    public class Test01 {
        public static void main(String[] args) {
            String oldStr = "HelloWorld";
            System.out.println(oldStr);//HelloWorld
            String newStr = upCase(oldStr);
            System.out.println(newStr);//HELLOWORLD
            System.out.println(oldStr);//HelloWorld
        }
        public static String upCase(String temp){
            return temp.toUpperCase();
        }
    }
    

    3.1. 调用upCase(),String对象作为参数时,都会复制一份引用,而该引用所指对象其实一直待在单一的物理位置上。
    3.2 upCase()方法中,
    1)引用名称temp,只有运行upCase()的时候,局部引用temp才存在;
    2)upCase()运行结束,temp就消失了;
    3)upCase()的返回值,也只是最终结果的引用

    4、“+” 与 StringBuilder
    public class Test02 {
        public static void main(String[] args) {
            String str = "love" ;
            String newStr = "I " + str + " code" + " very much" ;
            System.out.println(newStr);//I love code very much
        }
    }
    

    4.1 该代码工作可能为,"I"与str连接后生成一个新的字符串,然后该新字符串再与"code"相连生成一个新的String对象,以此类推。得到最终String。该工作方式行得通,但会产生一大堆需要垃圾回收的中间对象。
    4.2 反编译得出结论,上诉代码,编译器创建了一个StringBuilder对象,用以构造最终的String。编译器会为你的代码自动优化

    5、编译器会将"+"优化成StringBuilder
    public class Test03 {
        public String useString(String[] fields){
            String str = "";
            for(int i=0 ; i<fields.length ; i++){
                str += fields[i];
            }
            return str;
        }
        public String useStringBuilder(String[] fields){
            StringBuilder sb = new StringBuilder();
            for(int i=0 ; i<fields.length ; i++){
                sb.append(fields[i]);
            }
            return sb.toString();
        }
    }
    

    5.1 编译器会将"+"优化成StringBuilder,反编译得出:
    5.2 useString(),StringBuilder是在循环内构造的,每循环一次,就会创建一个新的StringBuilder对象
    5.3 useStringBuilder(),只生成了一个StringBuilder对象。而且,如果提前知道字符串的大概长度,可以显示的创建StringBuilder并指定大小,这样可以避免多次重新分配缓冲。
    注:StringBuilder调用append()时,若写成append(a+":"+c),那么编译器会为你创建另外一个StringBuilder对象来处理括号内的字符串操作

    6、无意识递归

    6.1 java中每个类根本上继承自Object,每个类都有toString()方法,并且覆写了该方法。
    如ArrayList.toString(),它会遍历ArrayList中包含的对象,调用每个元素的toString()方法

    public class Test04 {
        public static void main(String[] args) {
            List<Animal> list = new ArrayList<>();
            for(int i=0 ; i<5 ; i++){
                list.add(new Animal(i));
            }
            System.out.println(list);//[老鼠, 牛, 老虎, 张飞, 张飞]
        }
    }
    
    class Animal{
        private String name;
    
        public Animal(int i){
            switch(i){
                case 0: this.name = "老鼠";
                    return;
                case 1: this.name = "牛";
                    return;
                case 2: this.name = "老虎";
                    return;
                default: this.name = "张飞";
            }
        }
        public String toString(){
            return this.name;
        }
    }
    

    6.2 如果你希望toString()方法打印出对象的内存地址,也许你会考虑用this关键字,例子中Animal类改为

    class Animal{
        //其它省略...
        public String toString(){
            return this.name + ",classAddress=" + this;
        }
    }
    

    6.3 然后你就会看到异常,java.lang.StackOverflowError。
    当执行 this.name + ",classAddress=" + this 时,Animal类型转换成了String类型。
    编译器看到一个String对象后面跟着一个"+",而后面不是String对象,于是编译器试着将this转成一个String。于是又调用了this上的toString()方法,就发生了递归调用。
    6.4 正确的打印对象的内存地址,应该调用Object.toString()。所以不能使用this,要使用super.toString()。
    正确代码为:

    public class Test04 {
        public static void main(String[] args) {
            List<Animal> list = new ArrayList<>();
            for(int i=0 ; i<3 ; i++){
                list.add(new Animal(i));
            }
            System.out.println(list);
            //[老鼠,classAddress=com.test01.thinking.mystring.Animal@5594a1b5, 
            // 牛,classAddress=com.test01.thinking.mystring.Animal@79b4d0f, 
            // 老虎,classAddress=com.test01.thinking.mystring.Animal@6b2fad11]
        }
    }
    
    class Animal{
        private String name;
    
        public Animal(int i){
            switch(i){
                case 0: this.name = "老鼠";
                    return;
                case 1: this.name = "牛";
                    return;
                case 2: this.name = "老虎";
                    return;
                default: this.name = "张飞";
            }
        }
        public String toString(){
            return this.name + ",classAddress=" + super.toString();
        }
    }
    

    相关文章

      网友评论

          本文标题:Java编程思想笔记---String

          本文链接:https://www.haomeiwen.com/subject/dyhduktx.html