String类源码学习

String类源码学习

一、初始String类:

  1. String类是final类型的,表示该类不能被继承。如下图所示:
    在这里插入图片描述
  2. 这是一个字符数组,且是final的,用于存储字符串的内容。
    本质:String是用char[ ]实现的。
 /** The value is used for character storage. */
    private final char value[];
<blockquote><pre>
 *     String str = "abc";
 * </pre></blockquote><p>
 * is equivalent to:
 * <blockquote><pre>
 *     char data[] = {'a', 'b', 'c'};
 *     String str = new String(data);
  1. 因为String实现了Serializable接口,所以支持序列化和反序列化。Java的序列化机制是通过在运行时判断类的serialVersionUID来验证版本一致性的。在进行反序列化时,JVM会把传来的字节流中的serialVersionUID与本地相应实体(类)的serialVersionUID进行比较,如果相同就认为是一致的,可以反序列化,否则会出现序列化版本不一致的异常(InvalidCastException)。
/** use serialVersionUID from JDK 1.0.2 for interoperability */
    private static final long serialVersionUID = -6849794470754667710L;

    /**
     * Class String is special cased within the Serialization Stream Protocol.
     *
     * A String instance is written into an ObjectOutputStream according to
     * <a href="{@docRoot}/../platform/serialization/spec/output.html">
     * Object Serialization Specification, Section 6.2, "Stream Elements"</a>
     */
    private static final ObjectStreamField[] serialPersistentFields =
        new ObjectStreamField[0];

二、构造方法:
String的底层是由char[ ]实现的:通过一个char[]类型的value属性。

  1. 使用字符数组、字符串构造一个String
/**
     * Allocates a new {@code String} so that it represents the sequence of
     * characters currently contained in the character array argument. The
     * contents of the character array are copied; subsequent modification of
     * the character array does not affect the newly created string.
     *
     * @param  value
     *         The initial value of the string
     */
    public String(char value[]) {
        this.value = Arrays.copyOf(value, value.length);
    }
  1. 使用字节数组构造一个String:
  public String(byte bytes[], Charset charset) {
        this(bytes, 0, bytes.length, charset);
    }
  1. 使用StringBuffer和StringBuilder 构造一个String
/**
     * Allocates a new string that contains the sequence of characters
     * currently contained in the string buffer argument. The contents of the
     * string buffer are copied; subsequent modification of the string buffer
     * does not affect the newly created string.
     *
     * @param  buffer
     *         A {@code StringBuffer}
     */
    public String(StringBuffer buffer) {
        synchronized(buffer) {
            this.value = Arrays.copyOf(buffer.getValue(), buffer.length());
        }
    }
 /**
     * Allocates a new string that contains the sequence of characters
     * currently contained in the string builder argument. The contents of the
     * string builder are copied; subsequent modification of the string builder
     * does not affect the newly created string.
     *
     * <p> This constructor is provided to ease migration to {@code
     * StringBuilder}. Obtaining a string from a string builder via the {@code
     * toString} method is likely to run faster and is generally preferred.
     *
     * @param   builder
     *          A {@code StringBuilder}
     *
     * @since  1.5
     */
    public String(StringBuilder builder) {
        this.value = Arrays.copyOf(builder.getValue(), builder.length());
    }

三、String 中常用的方法:

/*String a = "abc";//放在常量池里面
		String b = "abc";
		String c = new String("abc");//在对内存开辟空间
		System.out.println(a == b);//true
		System.out.println(a == c);//false
*/	
		//测试String_StringBuilder_StringBuffer速度:
		long start = System.currentTimeMillis();
		//String s ="abc" + "de";// 等同于 String s ="abcde";
		String s1 = "abc";
		s1 += "de";
		//StringBuffer sb = new StringBuffer().append("abc").append("de");
		//StringBuilder sdr = new StringBuilder().append("abc").append("de");
		long end = System.currentTimeMillis();
		System.out.println(end - start) ;
		
		//String类中常用的方法:
		String str = new String(" wuxia is Perfect....");
		System.out.println(str.length());//1.返回字符串的长度
		System.out.println(str.isEmpty());//2.判断是否为空
		System.out.println(str.substring(1, 4));//3.左闭右开,返回子串
		System.out.println(str.charAt(2));//4.返回下标为2的字符
		System.out.println(str.toUpperCase());//5.转大写
		System.out.println(str.toLowerCase());//6.转小写
		System.out.println(str.trim());//7.去掉两端空格,注意中间的没有去掉
		char[] cha = str.toCharArray();//8.转为 字符数组 char[]
		System.out.print("转为数组:[");
		for(int i = 0;i < cha.length ; i ++) {
			if(i == cha.length - 1) {
				System.out.print(cha[i]+"]");
			}else {
				System.out.print(cha[i] +",");
			}
		}
		System.out.println();
		System.out.println(str.concat("专业有可能骗人,但是认知和格局是不会骗人的!"));//9.拼接字符串
		System.out.println(str.replace("...", "!!!"));//10.替换字符串
		System.out.println(str.contains("w"));//11.判断是否包含某个字符串
		System.out.println(str.matches("."));//12.是否匹配给定的正则表达式
		String[] strs = str.split(" ");//13.按照字符分成分割,返回String数组
		System.out.print("转为数组:[");
		for(int i = 0;i < strs.length ; i ++) {
			if(i == strs.length - 1) {
				System.out.print(strs[i]+"]");
			}else {
				System.out.print(strs[i] +"|");
			}
		}
		System.out.println();
		
		String str1 = "ABC";
		byte[] bytes = str1.getBytes();//14.将字符串转成字节数组
		for(int i = 0;i < bytes.length ; i ++) {
			if(i == bytes.length - 1) {
				System.out.print(bytes[i]+"]");
			}else {
				System.out.print(bytes[i] +"|");
			}
		}
		System.out.println();
		System.out.println(str1.equals("你好,吴霞"));//15.
		System.out.println(str1.contentEquals(new StringBuffer("你好,吴霞")));
		System.out.println(str1.equalsIgnoreCase("abc"));
		System.out.println(str1.compareTo("abc"));
		System.out.println(str1.compareToIgnoreCase("abc"));
		System.out.println(str1.regionMatches(1, "c", 1, 1));
		System.out.println(str1.substring(1));//重新new 了 一个String 避免了内存泄露,但牺牲了性能
		System.out.println(str1.replaceFirst("A", "吴霞"));
		System.out.println(str1.replaceAll("AB", "你好"));
		
		char[] c = {'w','c'};
		//valueOf
		System.out.println(str.valueOf("qqq"));
		System.out.println(str.copyValueOf(c));//new String(data);
		
		//intern()方法
		/**
		When the intern method is invoked, if the pool already contains a
	     * string equal to this {@code String} object as determined by
	     * the {@link #equals(Object)} method, then the string from the pool is
	     * returned. Otherwise, this {@code String} object is added to the
	     * pool and a reference to this {@code String} object is returned.*/
		String s = new String("intern");
		System.out.println(s.intern());//重要,当该方法被调用时,如果对象池包含这个字符串,则返回
										//对象池的实例,否则添加字符串到对象池并返回该字符串的引用
		String s2 = new String("java1");
		String s3 = new String("吴霞");
		String s4 = "吴霞";
		System.out.println("java1" == s2);//false  
		System.out.println("java1" == s2.intern());//true  思考:为什么?
		System.out.println(s3 == s3.intern());//false  思考:为什么? s3是堆上的引用,s3.intern()是从常量池返回的
		System.out.println(s3.intern() == s3);//false  思考:为什么?
		System.out.println(s4 == s3.intern());//true  思考:为什么?
		
		//String 对 "+"的重载 ,"+"是java 唯一一个重载运算符
		//反编译后: 
		String a = "abc";
		String a1 =a + "def";
		System.out.println(a1);
		
		int i = 5;
		String i1 = "" + i;//相当于  String i1 =(new StringBuilder()).append(i).toString();
		String i2 = String.valueOf(i);//调的是 Integer.toString(i); toString(i) 是new 的一个新对象
		String i3 = Integer.toString(i);
		System.out.println( i2 == i1);//false
		System.out.println( i2 == i3);//false

猜你喜欢

转载自blog.csdn.net/baidu_35160588/article/details/88426838