zoukankan      html  css  js  c++  java
  • Java中的String类的学习

    一、String类对象的实例化方式

    1.直接使用"" 定义字符串赋值给String类的对象

    2.使用String类中的构造方法:public String(String str);

    public class StringDemo{
        public static void main(String args[]){
            String str="Hello world!";  //直接赋值实例化String类的对象
            String str=new String("Hello world!"); //通过String类的构造方法实例化String类的对象
            System.out.println(str);
        }    
    }

    二、String类对象的比较问题

    1、==操作符——比较两个对象的内存地址,并未比较两个字符串的数值

    public class StringDemo{
        public static void main(String args[]){
            String str1="Hello";
            String str2=new String("Hello");
            String str3=str2;
            System.out.println(str1==str2); //false
            System.out.println(str1==str3); //false
            System.out.println(str2==str3); //true
        }    
    }

    2、equals方法——比较两个字符串的内容(public boolean equals(String other))

    public class StringDemo{
        public static void main(String args[]){
            String str1="Hello";
            String str2=new String("Hello");
            String str3=str2;
            System.out.println(str1.equals(str2)); //true
            System.out.println(str1.equals(str3)); //true
            System.out.println(str2.equals(str3)); //true
        }    
    }

    严格来说,equals比较的是堆内存中的内容

    面试题:请解释String的两种比较方式?

    • "=="比较的是两个字符串的内存地址的数值,属于数值比较
    • equals()比较的是两个字符串的内容

    注意:一个字符串常量是String的匿名对象

    java中String并不是一个基本数据类型,所以Java会自动把一个字符串常量当成一个String类的匿名对象来处理

    public class StringDemo{
        public static void main(String args[]){
            String str="Hello";
            
            System.out.println("Hello".equals(str); //true
        }    
    }

    小技巧:开发中使用以下方式可以避免NullPointException

    例如:

    public class StringDemo{
        public static void main(String args[]){
            String str="null";        
            System.out.println(str.equals("Hello"); 
        }    
    }

    会产生空指针异常NullPointException

    改进: 通过字符串常量调用equals()方法,该常量永远不会是null,所以可以避免空指针异常

    public class StringDemo{
        public static void main(String args[]){
            String str="null";        
            System.out.println("Hello".equals(str)); 
        }    
    }

    3、两种实例化方法的比较

    1)java的共享设计模式

    共享设计是在JVM中为用户提供一个对象池,当用户创建了一个 新的且池中没有的对象时,处理将这个对象分配内存之外,还会在对象池中进行保留,以后如果有其他对象社么了与之一样的内容时候,不会重复申明,而是从对象池中取出内容继续使用,String类正是使用该机制。

    当用户采用直接赋值实例化String对象的时候,如果是第一次定义,则会自动将对象内容保留在字符串对象池中,以后如果其他的字符串对象依然采用直接赋值的话,可以直接通过对象池取出已经保存的内容继续使用,而不会重新开辟新的空间,如以下程序:

    public class StringDemo{
        public static void main(String args[]){
            String str1="Hello";
            String str2="Hello";
            String str3="Hello";         
            System.out.println(str1==str1); //true
            System.out.println(str1==str3); //true
            System.out.println(str2==str3); //true
        }    
    }

    其内存关系为

    2)通过String类的构造方法

    但通过该法创建的String对象的内容不能自动入池,

    但用户可以使用String类中的intern()方法手工入池。例如:

    public class StringDemo{
        public static void main(String args[]){
            String str1=new String("Hello");
            String str2="Hello";
            String str3="Hello";         
            System.out.println(str1==str1); //false
            System.out.println(str1==str3); //false
        }    
    }

    但是:

    public class StringDemo{
        public static void main(String args[]){
            String str1=new String("Hello").intern();
            String str2="Hello";
            String str3="Hello";         
            System.out.println(str1==str1); //true
            System.out.println(str1==str3); //true
        }    
    }

    面试题:String对象的两种实例化方式的区别?

    • 直接赋值:只开辟一个堆内存空间,而且采用共享设计模式,可以自动入池,以备下次对象继续使用
    • 构造方法:开辟两个内存空间,其中一块将成为垃圾,且不会自动入池,但可以采用intern()方法继续手工入池

    4、字符串的内容一旦声明则不可改变

    public class StringDemo{
        public static void main(String args[]){
            String str="Hello";
            str += "World";
            str = str +"!!!"
            System.out.println(str); // 输出为Hello World!!!
        }    
    }

    其内存空间变化如下

     可以看出实际上对于String中的字符串内容并没有发生任何的变化,而最后内容的改变实际上改变的是String对象的内存地址的指向,所以字符串内容依然没有任何变化,但这样会产生大量的垃圾,所以在开发中对以下代码必须要进行回避:

    public class StringDemo{
        public static void main(String args[]){
            String str="";
            for(int x=0; x<1000;x++){
                str += x;
            }
            System.out.println(str); 
        }    
    }

    相当于“断开-连接”1000次,且产生大量的垃圾空间;在实际开发中,可以用StringBuffer来实现上述代码功能,而不产生大量垃圾。

  • 相关阅读:
    先验概率与后验概率、贝叶斯区别与联系
    Linux查看登录用户记录信息
    Discuz常见小问题-如何关闭验证码
    word文档的图片怎么保存到CKEditor上
    word文档的图片怎么保存到umeditor上
    word文档的图片怎么保存到百度Web编辑器上
    word文档的图片怎么保存到百度编辑器上
    word文档的图片怎么保存到百度ueditor上
    word图文混排复制到CuteEditor图片不显示
    word图文混排复制到eWebEditor图片不显示
  • 原文地址:https://www.cnblogs.com/JoannaQ/p/2651789.html
Copyright © 2011-2022 走看看