java字符串知多少
public
class
stringTest
{
String str = "1234";
private void ChangeOne(String s)
{
s = "4321";
}
private void ChangeTwo(stringTest st)
{
st.str = "5678";
}
//传入类的对象
private void ChangeThree(stringTest st)
{
st = null;
}
private void ChangeFour(String str)
{
String str2 = str;
str = "hello";
System.out.println("str is " + str);
System.out.println("str2 is "+ str2);
}
private void ChangeFive(StringBuffer sb)
{
sb = new StringBuffer("Test");
System.out.println(sb.toString());
//这里打印结果为Test,但传进来的StringBuffer对象不会改变,出方法后仍为原来的值
}
private void ChangeSix(StringBuffer sb)
{
sb.append("world ");
}
private void ChangeSeven()
{
StringBuffer sb1 = new StringBuffer("sb1 ");
StringBuffer sb2 = new StringBuffer();
sb2 = sb1;
sb2.append("add sb2");
System.out.println(sb1.toString());
//打出的结果为 sb1 add sb2 ,此处赋值方式为将sb1所指向的地址简单的赋值给sb2
//两个对象指向同一内存地址中的值.
}
private void strTest()
{
String str1 = "helloworld";
String str2 = "helloworld";
String str3 = new String("helloworld");
String str4 = new String("helloworld");
System.out.println("字符串的存储方式!");
System.out.println(str1 == str2);
System.out.println(str1 == str3);
System.out.println(str4 == str3);
//结果为true ,false ,false。每次new一个都会使用不同的内存块。
// str1和str2指向字符串常量 str,而str3,str4指向各自的 new String("str");
String str5 = "hello"+"world";
String str6 = "hello";
String str7 = "world";
String str8 = str6 + str7;
System.out.println("str1 == str5 is: "+(str1 == str5));
System.out.println("str1 == str8 is: "+(str1 == str8));
}
public static void main(String[] args)
{
stringTest st = new stringTest();
System.out.println(st.str);
System.out.println("-----------传入字符串时---------------");
st.ChangeOne(st.str);
System.out.println(st.str);
System.out.println("-----------传入类对象时,更改对象.str时---------------");
st.ChangeTwo(st);
System.out.println(st.str);
System.out.println("-----------将类对象赋为null时---------------");
st.ChangeThree(st);
System.out.println(st.str);
System.out.println("--------------------------------------");
st.ChangeFour(st.str);
System.out.println(st.str);
System.out.println("------------StringBuffer测试---------");
StringBuffer sb = new StringBuffer("Hello ");
st.ChangeFive(sb);
System.out.println(sb.toString());
st.ChangeSix(sb);
System.out.println(sb.toString());
System.out.println("------------StringBuffer测试2---------");
st.ChangeSeven();
st.strTest();
}
}
/**/ /*
//(1) 当 = 的右边全是字符串常量,那么 = 左边的变量(左值)也成为字符串常量。
//(2) 当 = 的右边包含字符串变量(或其它变量),那么 = 左边的变量(左值)也成为字符串变量(StringBuffer().append()的结果)。
1. 每个Thread有自己的 运行栈。Stack
2. 每次函数调用,运行栈顶部上都会为 该函数调用 分配一个Stack Frame. 这也称为Context.
3. 函数调用结束,栈指针回到上一级函数调用的Context, Stack Frame, 刚才分配的顶部Stack Frame 就失效。上一级函数成为当前Stack Frame, Context。
4. 每次函数调用, 参数都会 压栈 压入运行栈。注意,这是非常重要的。
5. 压入运行栈内的 参数,是 Copy 了一份。注意,这也是非常重要的。所以,对参数 赋值,对上一级函数调用来说,是根本没有意义的。
因为只是改变了顶部Stack Frame里面 参数Copy的内容,根本不对上一级 Stack Frame 造成任何影响。
*/
// 关于String str = new String("abc"); String str2 = new String("abc"); 为什么会指向
// 不同的reference,有一种说是利于lock的说法
class ClassLockA1
{
String strLock = new String("lock");
private void startA1()
{
synchronized(strLock)
{
//do something here
}
}
}
class ClassLockA2
{
String strLock = new String("lock");
private void startA2()
{
synchronized(strLock)
{
//do something here
}
}
}
// 上面这情况每个strLock都有不同的reference,具有不同的同步锁,不会相互影响。
// 如果是
class ClassLockB1
{
String strLock = "lock";
private void startA1()
{
synchronized(strLock)
{
//do something here
}
}
}
class ClassLockB2
{
String strLock = "lock";
private void startA2()
{
synchronized(strLock)
{
//do something here
}
}
}
// 这种情况下 两个类的lock都是相同的引用,两个类本身同步。
// 疑问:字符串池是针对同一个应用程序中所有类的不是不同的类有不同的字符串池呢?
// 如果是不同的类不同的字符串池,则上面的线程则仍是不相互干扰的。
{
String str = "1234";
private void ChangeOne(String s)
{
s = "4321";
}
private void ChangeTwo(stringTest st)
{
st.str = "5678";
}
//传入类的对象
private void ChangeThree(stringTest st)
{
st = null;
}
private void ChangeFour(String str)
{
String str2 = str;
str = "hello";
System.out.println("str is " + str);
System.out.println("str2 is "+ str2);
}
private void ChangeFive(StringBuffer sb)
{
sb = new StringBuffer("Test");
System.out.println(sb.toString());
//这里打印结果为Test,但传进来的StringBuffer对象不会改变,出方法后仍为原来的值
}
private void ChangeSix(StringBuffer sb)
{
sb.append("world ");
}
private void ChangeSeven()
{
StringBuffer sb1 = new StringBuffer("sb1 ");
StringBuffer sb2 = new StringBuffer();
sb2 = sb1;
sb2.append("add sb2");
System.out.println(sb1.toString());
//打出的结果为 sb1 add sb2 ,此处赋值方式为将sb1所指向的地址简单的赋值给sb2
//两个对象指向同一内存地址中的值.
}
private void strTest()
{
String str1 = "helloworld";
String str2 = "helloworld";
String str3 = new String("helloworld");
String str4 = new String("helloworld");
System.out.println("字符串的存储方式!");
System.out.println(str1 == str2);
System.out.println(str1 == str3);
System.out.println(str4 == str3);
//结果为true ,false ,false。每次new一个都会使用不同的内存块。
// str1和str2指向字符串常量 str,而str3,str4指向各自的 new String("str");
String str5 = "hello"+"world";
String str6 = "hello";
String str7 = "world";
String str8 = str6 + str7;
System.out.println("str1 == str5 is: "+(str1 == str5));
System.out.println("str1 == str8 is: "+(str1 == str8));
}
public static void main(String[] args)
{
stringTest st = new stringTest();
System.out.println(st.str);
System.out.println("-----------传入字符串时---------------");
st.ChangeOne(st.str);
System.out.println(st.str);
System.out.println("-----------传入类对象时,更改对象.str时---------------");
st.ChangeTwo(st);
System.out.println(st.str);
System.out.println("-----------将类对象赋为null时---------------");
st.ChangeThree(st);
System.out.println(st.str);
System.out.println("--------------------------------------");
st.ChangeFour(st.str);
System.out.println(st.str);
System.out.println("------------StringBuffer测试---------");
StringBuffer sb = new StringBuffer("Hello ");
st.ChangeFive(sb);
System.out.println(sb.toString());
st.ChangeSix(sb);
System.out.println(sb.toString());
System.out.println("------------StringBuffer测试2---------");
st.ChangeSeven();
st.strTest();
}
}
/**/ /*
//(1) 当 = 的右边全是字符串常量,那么 = 左边的变量(左值)也成为字符串常量。
//(2) 当 = 的右边包含字符串变量(或其它变量),那么 = 左边的变量(左值)也成为字符串变量(StringBuffer().append()的结果)。
1. 每个Thread有自己的 运行栈。Stack
2. 每次函数调用,运行栈顶部上都会为 该函数调用 分配一个Stack Frame. 这也称为Context.
3. 函数调用结束,栈指针回到上一级函数调用的Context, Stack Frame, 刚才分配的顶部Stack Frame 就失效。上一级函数成为当前Stack Frame, Context。
4. 每次函数调用, 参数都会 压栈 压入运行栈。注意,这是非常重要的。
5. 压入运行栈内的 参数,是 Copy 了一份。注意,这也是非常重要的。所以,对参数 赋值,对上一级函数调用来说,是根本没有意义的。
因为只是改变了顶部Stack Frame里面 参数Copy的内容,根本不对上一级 Stack Frame 造成任何影响。
*/
// 关于String str = new String("abc"); String str2 = new String("abc"); 为什么会指向
// 不同的reference,有一种说是利于lock的说法
class ClassLockA1
{
String strLock = new String("lock");
private void startA1()
{
synchronized(strLock)
{
//do something here
}
}
}
class ClassLockA2
{
String strLock = new String("lock");
private void startA2()
{
synchronized(strLock)
{
//do something here
}
}
}
// 上面这情况每个strLock都有不同的reference,具有不同的同步锁,不会相互影响。
// 如果是
class ClassLockB1
{
String strLock = "lock";
private void startA1()
{
synchronized(strLock)
{
//do something here
}
}
}
class ClassLockB2
{
String strLock = "lock";
private void startA2()
{
synchronized(strLock)
{
//do something here
}
}
}
// 这种情况下 两个类的lock都是相同的引用,两个类本身同步。
// 疑问:字符串池是针对同一个应用程序中所有类的不是不同的类有不同的字符串池呢?
// 如果是不同的类不同的字符串池,则上面的线程则仍是不相互干扰的。