java基础:String

JAVA基础之String

一.概述

1.1 简介:java

    String是一个复制类型,在java项目中使用最多。在java中String变量值都是存放的String在堆空间中的地址。本文讲解下String的地址相关常量池和intern。express

2.2 String的组成:数组

    

    a.数组被放在堆空间。this

    b.数组不能改变大小,每一次改变大小都会从新分配空间(地址改变)。spa

2.4 经常使用的方法code

    能够去下载帮助文档(chm文件)查看。对象

二.案例

2.1 初始化
ci

    a.    ==要相等,必须在class文件在加载时,能让JVM解析并生成的char[]在常量池中。
文档

    b.    =初始化,JVM直接解析,而后从常量池中寻找相同的值地址空间,并返回;若是没有值,则建立并返回。
字符串

    c.    new初始化时,将变量值存放为new String()开辟的堆空间地址,而后在堆空间地址中存放常量池中一样值的char[]地址,若是没有则建立并返回

    d. 只有JVM在解析的时候,可以准确的知道=右值的准确地址(包括能够经过final引用查找到其值,不包括引用地址),则其地址空间都相等。

public static void main(String[] args) {
		final String o1="a";
		String o = "a";
		String a = "a1";
		String b = "a" + 1;
		String c = o + 1;
		String c1 = o1 + 1;
		String d = new String("a1");
		/**
		 * String a: 右值是肯定的基础变量,没有引用、new等初始化方式,在加载的时候、JVM解析class文件,a直接存放char[]的地址
		 * String b: 虽然右值使用了+,可是JVM直接将其整合为char[],放在堆空间
		 * String c: 引用,JVM只有在加载后,运行时才能去人地址
		 * String c1:虽然使用的是引用,可是有final,JVM能够直接解析
		 * String d: d指向的是,new 在运行时分配堆空间。
		 */
		System.out.println(a == b); // true
		System.out.println(a == c); // false
		System.out.println(a == c1); // true
		System.out.println(a == d); // false
		System.out.println(a.intern());
		System.out.println(a.hashCode()); // 3056
		System.out.println(b.hashCode()); // 3056
	}

2.2 intern

    源码解释:

Returns a canonical representation for the string object.
A pool of strings, initially empty, is maintained privately by the class String.
When the intern method is invoked, if the pool already contains a string equal to this String object as determined by the equals(Object) method, then the string from the pool is returned. Otherwise, this String object is added to the pool and a reference to this String object is returned.
It follows that for any two strings s and t,  s.intern() == t.intern() is true if and only if s.equals(t) is true.
All literal strings and string-valued constant expressions are interned. String literals are defined in section 3.10.5 of theThe Java™ Language Specification.
返回一个标准的String对象。
String池,开始是空的,用来保存私有的String类。
1.用intern()时:若是这String池里面有一个可以equals(objects)《即,有一个相同值的char[]》,则返回这个char[];若是没有,则添加建立一个,并返回。
2.两个String字符串 s和t,只有在s.equals(t)<值相同>的状况下,t.intern()==s.intern()为true。

    案例:

public static void main(String[] args) {
		String a = "a1";
		/*
		 * intern 返回String常量池中地址;相同Unicode的地址引用 将一个 String 类的保存到一个全局 String 表中 ,
		 * 若是具备相同值的 Unicode 字符串已经在这个表中,那么该方法返回表中已有字符串的地址,
		 * 若是在表中没有相同值的字符串,则将本身的地址注册到表中
		 */

		System.out.println("============== 基础变量 ===============");
		String c00 = "a".intern() + 1; // 方法在,runtime确认
		String c01 = "a" + 1;			//加载时,确认地址
		System.out.println(a == c00); // false
		System.out.println(a == c01);// true
		System.out.println(a == c00.intern());	//(true) runtime方法运行、返回指向的常量池地址

		System.out.println("============== final 引用 ===============");
		final String b1 = "a"; // 运行时确认值
		String c10 = b1.intern() + 1;
		String c11 = b1 + 1;
		System.out.println(a == c10); // false
		System.out.println(a == c11); // true
		System.out.println(a == c01.intern());	//true runtime方法运行、返回指向的常量池地址
		System.out.println("============== 引用 ===============");
		String b2 = a; // 运行时确认值
		String c20 = b2.intern() + 1;
		String c21 = b2 + 1;
		System.out.println(a == c20); // false
		System.out.println(a == c21); //

		System.out.println("==============final new 初始化===============");
		final String b3 = new String("a"); // NEW 运行时确认值
		String c30 = b3.intern() + 1;
		String c31 = b3 + 1;
		System.out.println(a == c30); // false
		System.out.println(a == c31); // false

		System.out.println("============== new ===============");
		String b4 = new String("a"); // final new 运行时确认值
		String c40 = b4.intern() + 1;
		String c41 = b4 + 1;
		System.out.println(a == c40); // false
		System.out.println(a == c41); // true

		System.out.println("============== method ===============");
		final String b5 = getB3(); // 方法运行时确认值
		String c50 = b5.intern() + 1; // 对于引用,可是运行时JVM才知道其值
		String c51 = b5 + 1; // 对于引用,可是运行时JVM才知道其值
		System.out.println(a == c50); // false
		System.out.println(a == c51); // true (说明在同一个常量池)

		System.out.println("============== final method ===============");
		final String b6 = getB4(); // final方法,运行时确认
		String c60 = b6.intern() + 1; // 对于引用,可是运行时JVM才知道其值
		String c61 = b6 + 1; // 对于引用,可是运行时JVM才知道其值
		System.out.println(a == c60); // false
		System.out.println(a == c60); // true (说明在同一个常量池)

	}

	public static String getB3() {
		return "a";
	}

	public final static String getB4() {
		return "a";
	}
相关文章
相关标签/搜索