您的位置:首页 > 编程语言 > Java开发

Java final String类的详细用法还有特性说明,自己也在学习.

2016-08-01 10:38 344 查看

String 方法

package com.evangelsoft.crosslink;

import java.io.UnsupportedEncodingException;
import java.lang.Character.UnicodeBlock;
import java.nio.charset.Charset;
import java.util.Locale;

public class StringTest {

public static void main(String[] args) throws UnsupportedEncodingException {
//      constructor();
//      commonMethod();
OtherMethod();
}

/*
* String 构造函数Demo.
*/
public static void constructor() throws UnsupportedEncodingException{
byte[] b = { 'A', 'l', 'e', 'x'};
char[] c = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' };

//String(byte[] bytes): 通过byte数组构造字符串对象。
String strByte = new String(b);
Print.info("strByte", strByte);//Alex

/*
* String(byte[] bytes, int offset, int length)
*   通过使用平台的默认字符集解码指定的 byte 子数组,构造一个新的 String。
*   offset=指定byte 子数组的x下标, length=指定"截取"x位.
*        即: b,offset=2,length=2 从offset开始"截取"length位。
*/
String strByte_sub = new String(b, 1, 3);
Print.info("strByte_sub", strByte_sub);//lex

// String(char[] value): 通过char数组构造字符串对象。
String strChar = new String(c);
Print.info("strChar", strChar);//0123456789

// String(char[] value, int offset, int count)
//   同String(byte[] bytes, int offset, int length)一样.
String strChar_sub = new String(c, 2, 5);
Print.info("strChar_sub", strChar_sub);//23456

/*
* String(byte[] bytes, String charsetName)
*  通过使用指定的 charset 解码指定的 byte 数组,构造一个新的 String。
*  抛出:UnsupportedEncodingException - 如果指定的字符集不受支持
*/
String strCharset = new String("阿哈".getBytes(), "UTF-8");
Print.info("strCharset", strCharset);//阿哈

/*
* String(byte[] bytes, int offset, int length, String charsetName)
*  通过使用指定的字符集解码指定的 byte 子数组,构造一个新的 String。
*  参数:
*      bytes - 要解码为字符的 byte
*      offset - 要解码的第一个 byte 的索引
*      length - 要解码的 byte 数
*      charsetName - 受支持 charset 的名称

*  抛出:
*        UnsupportedEncodingException - 如果指定的字符集不受支持
IndexOutOfBoundsException -
如果offset和length参数索引字符超出bytes数组的范围
*/
String strCharset_sub = new String(
"byte数组指定charset".getBytes(),4,12, "UTF-8");
Print.info("strCharset_sub", strCharset_sub);//数组指定

// String(String original): 构造一个original的副本,即拷贝一个original。
String copyOriginal = new String(strByte); //Alex

/*  String(StringBuffer buffer):
*      分配一个新的字符串,它包含字符串缓冲区参数中当前包含的字符序列。
*/
String strBuff = new String(new StringBuffer(10).append(c));
Print.info("strBuff", strBuff);//0123456789

/*
* String(StringBuilder builder)
*      分配一个新的字符串,它包含字符串生成器参数中当前包含的字符序列。
*/
String strBuild = new String(new StringBuilder(10).append(c));
Print.info("strBuild", strBuild);//0123456789

}

/**
* String 方法摘要
*/
public static void commonMethod() throws UnsupportedEncodingException{

/*
* char charAt(int index)
*
* 参数:
index - char 值的索引。
返回:
此字符串指定index处的char值. 第一个char值位于索引0处。
抛出:
IndexOutOfBoundsException -
如果 index 参数为负或小于此字符串的长度。
*/
Print.info("charAt()", "charAt方法Demo".charAt(6));//方

/*
*  int compareTo(String anotherString) 按字典顺序比较两个字符串。
*    如果这两个字符串相等,则结果为 0;compareTo
*    只在方法 equals(Object) 返回 true 时才返回 0。
*
*    不相等时,从两个字符串第0个字符开始比较,返回第一个不相等的字符差。
*      即 : this.charAt(k) - anotherString.charAt(k)
*    另一种情况,较长字符串的前面部分恰巧是较短的字符串,返回它们的长度差。
*      即 : this.length()-anotherString.length()
*
*  int compareTo(Object o)  这方法功能跟compareTo(String anotherString)的是一样的.
*      参数:Object o
*      抛出:ClassCastException
*/
String str = "A";
String anotherStr = "lex";

//'A'-'l' = -43 'A'在字符集里是65,'l'是108, 字符集与运算符操作就会变成Unicode码.即Unicode码对应的数字。
Print.info("compareTo()", str.compareTo(anotherStr));//-43
Print.info("compareTo()", "true".compareTo("trues"));//-1
Print.info("compareTo()", "Equal".compareTo("Equal"));//0

//String concat(String str) 将指定字符串连接到此字符串的结尾。
Print.info("concat()", str.concat(anotherStr));//Alex

//boolean contentEquals(StringBuffer sb) :将该String对象与StringBuffer对象sb进行比较。

// static String copyValueOf(char[] data) == String(char[] value)
// static String copyValueOf(char[] data, int offset, int count) == String(char[] value, int offset, int count)
// 这两个方法  返回指定数组中表示该字符序列的 String。与==后面构造函数一样功能。

Print.info("copyValueOf()",
String.copyValueOf(new char[] { 'A', 'l', 'e', 'x' }));// Alex
Print.info("copyValueOf()-Sub",
String.copyValueOf(new char[] { 'A', 'l', 'e', 'x' }, 0, 3));// Ale

// boolean endsWith(String suffix) 测试此字符串是否以指定的后缀结束。
Print.info("endsWith()", "endsWith".endsWith("h"));// true

/*
* boolean equals(Object anObject) 将此字符串与指定的对象比较。
* anObject该参数不为null,并且是与此对象表示相同字符序列的String对象时,结果为true。
* 即: 两个对象的字符串值比较,字符串值相等 返回true, 否则false.
*/
Object equals = "equals";
Print.info("equals()", "equals".equals(equals));// true
Print.info("equals()", "1".equals(1));// false "1"字符串 1是int类型 不相等

/*
* boolean equalsIgnoreCase(String anotherString)
*    将此 String 与另一个 String 比较,不考虑大小写。
*/
Print.info("equalsIgnoreCase()", "equals".equalsIgnoreCase("EQUALS"));// true

// byte[] getBytes() 使用平台的默认字符集将此 String 编码为 byte 序列,
//  并将结果存储到一个新的 byte 数组中。
Print.info("getBytes()", new String("getBytes".getBytes()));

/* byte[] getBytes(Charset charset)
* byte[] getBytes(String charsetName)
*  使用指定的字符集将此 String 编码为 byte 序列,
*  并将结果存储到一个新的 byte 数组中。功能差不多演示参数字符串的。
*  异常抛出: UnsupportedEncodingException
*/
Print.info("getBytes(Charset)", new String("getBytes".getBytes(Charset.defaultCharset())));
Print.info("getBytes(String)", new String("getBytes".getBytes("GBK")));

/*
* void getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin)
*   将字符从此字符串复制到目标字符数组。
* 参数:
srcBegin - 字符串中要复制的第一个字符的索引。
srcEnd - 字符串中要复制的最后一个字符之后的索引。
dst - 目标数组。
dstBegin - 目标数组中的起始偏移量。
抛出:
IndexOutOfBoundsException - 如果下列任何一项为 true:
srcBegin 为负。
srcBegin 大于 srcEnd
srcEnd 大于此字符串的长度
dstBegin 为负
dstBegin +(srcEnd-srcBegin) 大于 dst.length

*/
char[] dst = {'i','f',' ','h','e','r'};
String src = "you";
src.getChars(0, src.length(), dst, 3);
Print.info("getChars()", String.copyValueOf(dst));//if you

/*int indexOf(int ch) 返回指定字符在此字符串中第一次出现处的索引。
*int indexOf(int ch, int fromIndex) 返回在此字符串中第一次出现指定字符处的索引,从指定的索引开始搜索。
*
*参数:
ch - 一个字符(Unicode码对应的数字)。
fromIndex - 开始搜索的索引。
*
*int indexOf(String str) 返回指定子字符串在此字符串中第一次出现处的索引。
*int indexOf(String str, int fromIndex) 返回指定子字符串在此字符串中第一次出现处的索引,从指定的索引开始。
*
* 参数:
*      str - 要搜索的子字符串。
fromIndex - 开始搜索的索引位置。
All indexOf method 返回:
在此对象表示的字符序列中第一次出现该字符的索引;如果未出现该字符,则返回 -1。

*/
String s ="write once, run anywhere!";
char ch = 'r';
Print.info("indexOf(int ch)", s.indexOf(ch) ); // 1
Print.info("indexOf(int ch, int)" , s.indexOf(ch,2) ); // 12
Print.info("indexOf(String)" , s.indexOf("run")); //12
Print.info("indexOf(String, int)" , s.indexOf("run", 13)); //-1

/*
int lastIndexOf(int ch)
返回指定字符在此字符串中最后一次出现处的索引。
int lastIndexOf(int ch, int fromIndex)
参数:
ch - 一个字符(Unicode码对应的数字)。
fromIndex - 开始搜索的索引。
fromIndex 的值没有限制。如果它大于等于此字符串的长度,
则与它小于此字符串长度减 1 的效果相同:Math.min(fromIndex,this.length()) -1
将搜索整个字符串。如果它为负,则与它为 -1 的效果相同:返回 -1。

返回指定字符在此字符串中最后一次出现处的索引,从指定的索引处开始进行反向搜索。
int lastIndexOf(String str)
返回指定子字符串在此字符串中最右边出现处的索引。
int lastIndexOf(String str, int fromIndex)
返回指定子字符串在此字符串中最后一次出现处的索引,从指定的索引开始反向搜索。
参数:
str - 要搜索的子字符串。
fromIndex - 开始搜索的索引位置。

*/

String last ="abcdefg run";
Print.info("lastIndexOf(int ch)", last.lastIndexOf(ch) ); // 8
Print.info("lastIndexOf(int ch, int)" , last.lastIndexOf(ch, 100) ); // 8
Print.info("lastIndexOf(String)" , last.lastIndexOf(" ")); //7
Print.info("lastIndexOf(String, int)" , last.lastIndexOf(" ", 2)); // -1

/*
* String intern() 返回字符串对象的规范化表示形式。
*
* 当调用 intern 方法时,如果池已经包含一个等于此String对象的字符串
* (用 equals(Object) 方法确定), 则返回池中的字符串。
* 否则将此String对象添加到池中, 并返回此 String 对象的引用。
*
*  返回:
*      一个字符串,内容与此字符串相同,但一定取自具有唯一字符串的池。
*/
Print.info("intern()" , "intern".intern());

//boolean isEmpty() this.length() 为 0 时返回 true。
Print.info("isEmpty()" , "".isEmpty()); // true 空字符在Unicode码是0所以,默认的长度为0;

// int length() 返回此字符串的长度。
Print.info("length()" , "length".length()); //6

/*
* String replace(char oldChar, char newChar)
*   返回一个新的字符串,它是通过用newChar替换此字符串中出现的所有oldChar得到的。
*   如果oldChar 在此 String 对象表示的字符序列中没有出现,则返回对此 String 对象的引用
*
* String replace(CharSequence target, CharSequence replacement)
使用指定的字面值替换序列替换此字符串所有匹配字面值目标序列的子字符串。
参数:
target - 要被替换的 char 值序列
replacement - char 值的替换序列
抛出:
NullPointerException - 如果 target 或 replacement 为 null。

*/
Print.info("replace(char, char)" , "No".replace('N','Y')); //YO
Print.info("replace(CharSequence, CharSequence)" , "Say, NO".replace("NO", "Yes")); //Say, Yes

/*
*  String replaceAll(String regex, String replacement)
使用给定的 replacement 替换此字符串所有匹配给定的正则表达式的子字符串。
调用此方法的 str.replaceAll(regex, repl) 形式与以下表达式产生的结果完全相同:
Pattern.compile(regex).matcher(str).replaceAll(repl)
参数:
regex - 用来匹配此字符串的正则表达式
replacement - 用来替换每个匹配项的字符串
抛出:
PatternSyntaxException - 如果正则表达式的语法无效
*/
Print.info("replaceAll()" , "2016-07-29".replaceAll("-","/")); //  2016/07/29

/*
String replaceFirst(String regex, String replacement)
使用给定的 replacement 替换此字符串匹配给定的正则表达式的第一个子字符串。
与此方法结果相同Pattern.compile(regex).matcher(str).replaceFirst(repl)
参数:
regex - 用来匹配此字符串的正则表达式
replacement - 用来替换每个匹配项的字符串
抛出:
PatternSyntaxException - 如果正则表达式的语法无效

*/

Print.info("replaceFirst()" , "2016-07-29".replaceFirst("-", "/")); // 2016/07-29

/*
*  String[] split(String regex) 根据给定正则表达式的匹配拆分此字符串。
String[] split(String regex, int limit) 根据匹配给定的正则表达式来拆分此字符串。
*/
String[] split = "2016-07-29".split("-"); //以"-"作为分隔符来分割split字符串返回的是数组.
Print.info("split(String)", split[0] + ":" + split[1] + ":" + split[2]); //2016:07:29
Print.info("split(String, int)" , "startsWith".startsWith("W", 6));//true

/*
*  boolean startsWith(String prefix) 测试此字符串是否以指定的前缀开始。
boolean startsWith(String prefix, int toffset)
测试此字符串从指定索引开始的子字符串是否以指定前缀开始.
PS:此方法区分大小写。
*/
Print.info("startsWith(String)" , "startsWith".startsWith("s"));//true
Print.info("startsWith(String, int)" , "startsWith".startsWith("W", 6));//true

//String substring(int beginIndex) 返回一个新的字符串,它是此字符串的一个子字符串。
//String substring(int beginIndex, int endIndex) 返回一个新字符串,它是此字符串的一个子字符串。
Print.info("substring(int)" , "substring".substring(3));//string
Print.info("substring(int, int)" , "substring".substring(0, 3));//sub

// char[] toCharArray() 将此字符串转换为一个新的字符数组。
String newCharArray = "new CharArray" ;
for (char c : newCharArray.toCharArray()) {
System.out.print(c);
}
Print.info("" ,"toCharArray()");//new CharArray: toCharArray()

// String trim() 返回字符串的副本,忽略前导空白和尾部空白。
// String toString() 返回此对象本身(它已经是一个字符串!)。
// String toLowerCase() 使用默认语言环境的规则将此 String 中的所有字符都转换为小写。
// String toLowerCase(Locale locale) 使用给定 Locale 的规则将此 String 中的所有字符都转换为小写。
// String toUpperCase() 使用默认语言环境的规则将此 String 中的所有字符都转换为大写。
// String toUpperCase(Locale locale) 使用给定 Locale 的规则将此 String 中的所有字符都转换为大写。
Print.info("trim()" ,"  Al ex  ".trim());//Al ex
Print.info("toString()" ,"return String".toString());//return String
Print.info("toLowerCase()" ,"LOWSER".toLowerCase());//lowser
Print.info("toLowerCase(Locale)" ,"LOWSER".toLowerCase(Locale.ENGLISH));//lowser
Print.info("toUpperCase()" ,"upper".toUpperCase());//UPPER
Print.info("toUpperCase(Locale)" ,"upper".toUpperCase(Locale.getDefault()));//UPPER

//static String valueOf(boolean b) 返回 boolean 参数的字符串表示形式。
/*
* 这个调式的时候是false, 但是输出到控制台是true,照理应该是true的.
* 因为首先String.valueOf(false)返回的是字符串"false" 之后 == "false"
* 是在创建对象但是字符串有个特性就是先找分字符串常量池内如果有就直接返回,无就new一个
*
*/

/**
* Mark 字符区常量池知识点。
*/
Print.info("valueOf(boolean)", String.valueOf(false) == "false");//true

//static String valueOf(char c) 返回 char 参数的字符串表示形式。
Print.info("valueOf(char)", String.valueOf((char) 65) == ("A"));// false
//static String valueOf(char[] data) 返回 char 数组参数的字符串表示形式。
Print.info("valueOf(char[])" ,String.valueOf(new char[]{'a','l','e','x'}));//lowser

/*
* /static String valueOf(char[] data, int offset, int count)
*      返回 char 数组参数的特定子数组的字符串表示形式。
*  参数:
data - 字符数组。
offset - String 值的初始偏移量。
count - String 值的长度。
返回:
一个字符串,它表示在字符数组参数的子数组中包含的字符序列。
抛出:
IndexOutOfBoundsException -
如果 offset 为负,count 为负,
或者 offset+count 大于 data.length。
*/

char[] exo = new char[]{'a','l',' ','e','x','o'};
Print.info("valueOf(char[], int , int)", String.valueOf(exo, 3, 3));// lowser

//static String valueOf(double d) 返回 double 参数的字符串表示形式。
Print.info("valueOf(double)" ,String.valueOf(3.1423).equals(3.1423));// false

//static String valueOf(float f) 返回 float 参数的字符串表示形式。
Print.info("valueOf(float)" ,String.valueOf((float) 88.66) == "88.66");//false

//static String valueOf(long l) 返回 long 参数的字符串表示形式。
Print.info("valueOf(long)" ,String.valueOf(Long.MAX_VALUE).equals(Long.MAX_VALUE));//"9223372036854775807L".equals(9223372036854775807L); false

//static String valueOf(int i) 返回 int 参数的字符串表示形式。

final String one = "1";
Print.info("valueOf(int)" ,String.valueOf(one) == "1");//true

//static String valueOf(Object obj) 返回 Object 参数的字符串表示形式。
Print.info("valueOf(Object)" ,String.valueOf((Object) "埃索达").equals("埃索达"));//true
}

/**
* String Other 方法
*/
public static void OtherMethod(){

/*
*  int hashCode() 返回此字符串的哈希码。
*      String 对象的哈希码根据以下公式计算:
s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1]
*/
Print.info("hashCode()","Alex".hashCode());//2043454

//static String format(Locale l, String format, Object... args) 使用指定的语言环境、格式字符串和参数返回一个格式化字符串。
//static String format(String format, Object... args) 使用指定的格式字符串和参数返回一个格式化字符串。

/*
* boolean matches(String regex) 告知此字符串是否匹配给定的正则表达式。
*  调用此方法的 str.matches(regex) 形式与以下表达式产生的结果完全相同:
Pattern.matches(regex, str)
参数:
regex - 用来匹配此字符串的正则表达式
返回:
当且仅当此字符串匹配给定的正则表达式时,返回 true
抛出:
PatternSyntaxException - 如果正则表达式的语法无效
*/
Print.info("matches()","Alex".matches("[a-zA-z]\\w*"));//true

/*
* int offsetByCodePoints(int index, int codePointOffset)
* 返回此 String 中从给定的 index 处偏移 codePointOffset 个代码点的索引。
* 参数:
index - 要偏移的索引
codePointOffset - 代码点中的偏移量
返回:
String 的索引
抛出:
IndexOutOfBoundsException -
如果index 为负或大于此 String 的长度;
或者codePointOffset为正,且以index开头子字符串的代码点比codePointOffset少;
如果codePointOffset为负,且index前面子字符串的代码点比codePointOffset的绝对值少。
作用:
以码位偏移值计算出位置,多数情况只是简单的加法。
*/
String codePoint = "Alex";
Print.info("offsetByCodePoints()",codePoint.offsetByCodePoints(0, 1));//true

/*
* boolean regionMatches(boolean ignoreCase, int toffset, String other, int ooffset, int len)
*  将此 String 对象的子字符串与参数other的子字符串进行比较
* 参数:
ignoreCase - 如果为 true,则比较字符时忽略大小写。
toffset - 此字符串中子区域的起始偏移量。
other - 字符串参数。
toffset - 字符串参数中子区域的起始偏移量。
len - 要比较的字符数。
返回:
如果此字符串的指定子区域匹配字符串参数的指定子区域,
则返回 true;否则返回 false。
是否完全匹配或考虑大小写取决于 ignoreCase 参数。
*/
Print.info("offsetByCodePoints(boolean, int, String, int, int)",
"offsetByCodePoints".regionMatches(true, 8, "CODE", 0, 3));//true

/*
* boolean regionMatches(int toffset, String other, int ooffset, int len)
*  将此 String 对象的子字符串与参数 other 的子字符串进行比较.
* 参数:
toffset - 字符串中子区域的起始偏移量。
other - 字符串参数。
ooffset - 字符串参数中子区域的起始偏移量。
len - 要比较的字符数。
返回:
如果此字符串的指定子区域完全匹配字符串参数的指定子区域,
则返回 true;否则返回 false。
*/
Print.info("offsetByCodePoints(int, String, int, int)",
"offsetByCodePoints".regionMatches(8, "CODE", 0, 3));//false
/*
* CharSequence subSequence(int beginIndex, int endIndex)
*  返回一个新的字符序列,它是此序列的一个子序列。
*  参数:
beginIndex - 起始索引(包括)。
endIndex - 结束索引(不包括)。
抛出:
IndexOutOfBoundsException -
如果 beginIndex 或 endIndex 为负,
如果 endIndex 大于 length() 或 beginIndex 大于 startIndex

*/
String sub = "oldnew subSequence";
Print.info("subSequence()",
sub.subSequence(3, "oldnew subSequence".length()));// new subSequence

/*
* public int codePointAt(int index)
*  返回指定索引处的字符(Unicode 代码点)。
*  索引引用char值(Unicode 代码单元),其范围从0到length()-1。
*
* 参数:
index - char 值的索引
返回:
index 处字符的代码点值
抛出:
IndexOutOfBoundsException -
如果 index 参数为负或小于此字符串的长度。
*/
Print.info("codePointAt()",
"演示codePointAt".codePointAt(0));//28436   (Unicode代码)=演

/*
* public int codePointBefore(int index)
*  返回指定索引之前的字符(Unicode 代码点)。
*  索引引用char值(Unicode 代码单元),其范围从1到length。
参数:
index - 应返回的代码点之后的索引
返回:
给定索引前面的 Unicode 代码点。
抛出:
IndexOutOfBoundsException -
如果 index 参数小于 1 或大于此字符串的长度。
*/
Print.info("codePointBefore()",
"演示codePointBefore".codePointBefore(1));//28436   (Unicode代码)=演

Print.info("Unicode Code To String",
String.valueOf((char)28436));//演

/*
public int codePointCount(int beginIndex, int endIndex)
返回此 String 的指定文本范围中的 Unicode 代码点数。
文本范围始于指定的 beginIndex,一直到索引 endIndex - 1 处的 char。
因此,该文本范围的长度(用 char 表示)是 endIndex-beginIndex。
该文本范围内每个未配对的代理项计为一个代码点。

参数:
beginIndex - 文本范围的第一个 char 的索引。
endIndex - 文本范围的最后一个 char 之后的索引。
返回:
指定文本范围中 Unicode 代码点的数量
抛出:
IndexOutOfBoundsException -
如果 beginIndex 为负,或 endIndex 大于此 String 的长度,
或 beginIndex 大于 endIndex。
*/
Print.info("codePointCount()",
"演示codePointCount".codePointCount(1,3));//2
}

}


下面是摘抄别人的自己也在这文章学习到很多,摘抄地址

有兴趣的可以看看以下知识点。

String 特性与常量池详解

  1.String使用private final char value[]来实现字符串的存储,也就是说String对象创建之后,就不能再修改此对象中存储的字符串内容,就是因为如此,才说String类型是不可变的(immutable)。String类有一个特殊的创建方法,就是使用”“双引号来创建.例如new String(“i am”)实际创建了2个

  String对象,一个是”i am”通过”“双引号创建的,另一个是通过new创建的.只不过他们创建的时期不同,

  一个是编译期,一个是运行期!java对String类型重载了+操作符,可以直接使用+对两个字符串进行连接。运行期调用String类的intern()方法可以向String Pool中动态添加对象。

  

  例1

  String s1 = “sss111”;

  //此语句同上

  String s2 = “sss111”;

  System.out.println(s1 == s2); //结果为true

  例2

  String s1 = new String(“sss111”);

  String s2 = “sss111”;

  System.out.println(s1 == s2); //结果为false

  例3

  String s1 = new String(“sss111”);

  s1 = s1.intern();

  String s2 = “sss111”;

  System.out.println(s1 == s2);//结果为true

  例4

  String s1 = new String(“111”);

  String s2 = “sss111”;

  String s3 = “sss” + “111”;

  String s4 = “sss” + s1;

  System.out.println(s2 == s3); //true

  System.out.println(s2 == s4); //false

  System.out.println(s2 == s4.intern()); //true

  

  结果上面分析,总结如下:

   1.单独使用”“引号创建的字符串都是常量,编译期就已经确定存储到String Pool中;

  2,使用new String(“”)创建的对象会存储到heap中,是运行期新创建的;

  3,使用只包含常量的字符串连接符如”aa” + “aa”创建的也是常量,编译期就能确定,已经确定存储到String Pool中;

  4,使用包含变量的字符串连接符如”aa” + s1创建的对象是运行期才创建的,存储在heap中;

  还有几个经常考的面试题:

  

  String s1 = new String(“s1”) ;

  String s2 = new String(“s1”) ;

  上面创建了几个String对象?

  答案:3个 ,编译期Constant Pool中创建1个,运行期heap中创建2个.(用new创建的每new一次就在堆上创建一个对象,用引号创建的如果在常量池中已有就直接指向,不用创建)

  String s1 = “s1”;

  String s2 = s1;

  s2 = “s2”;

  s1指向的对象中的字符串是什么?

  答案: “s1”。(永远不要忘了String不可变的,s2 = “s2”;实际上s2的指向就变了,因为你不可以去改变一个String,)

String是一个特殊的包装类数据。可以用:

String str = new String(“abc”);

String str = “abc”;

两种的形式来创建,第一种是用new()来新建对象的,它会在存放于堆中。每调用一次就会创建一个新的对象。

而第二种是先在栈中创建一个对String类的对象引用变量str,然后通过符号引用去字符串常量池里找有没有”abc”,如果没有,则将”abc”存放进字符串常量池,并令str指向”abc”,如果已经有”abc” 则直接令str指向“abc”。

比较类里面的数值是否相等时,用equals()方法;当测试两个包装类的引用是否指向同一个对象时,用==,下面用例子说明上面的理论。

String str1 = “abc”;

String str2 = “abc”;

System.out.println(str1==str2); //true

可以看出str1和str2是指向同一个对象的。

String str1 =new String (“abc”);

String str2 =new String (“abc”);

System.out.println(str1==str2); // false

用new的方式是生成不同的对象。每一次生成一个。

因 此用第二种方式创建多个”abc”字符串,在内存中其实只存在一个对象而已. 这种写法有利与节省内存空间. 同时它可以在一定程度上提高程序的运行速度,因为JVM会自动根据栈中数据的实际情况来决定是否有必要创建新对象。而对于String str = new String(“abc”);的代码,则一概在堆中创建新对象,而不管其字符串值是否相等,是否有必要创建新对象,从而加重了程序的负担。

另 一方面, 要注意: 我们在使用诸如String str = “abc”;的格式定义类时,总是想当然地认为,创建了String类的对象str。担心陷阱!对象可能并没有被创建!而可能只是指向一个先前已经创建的 对象。只有通过new()方法才能保证每次都创建一个新的对象。

由于String类的immutable性质,当String变量需要经常变换其值时,应该考虑使用StringBuffer类,以提高程序效率。

1. 首先String不属于8种基本数据类型,String是一个对象。

因为对象的默认值是null,所以String的默认值也是null;但它又是一种特殊的对象,有其它对象没有的一些特性。

new String()和new String(””)都是申明一个新的空字符串,是空串不是null;

String str=”kvill”;String str=new String (”kvill”)的区别

还有另一编文章关于Java堆、栈、常量池以及相关String的详细讲解,有兴趣的可以看看,可以对JVM机制了解多一点。

最后免责声明,如有问题请指出共同学习。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息