String常见题分析
2015-09-03 21:36
381 查看
1. 例1
1.1 代码
package com.ilaoda.day0903; /** * 字符串的常见题1 * @author iLaoda * */ public class Test1 { public static void main(String[] args) { String s1 = "hello"; String s2 = "world"; System.out.println(s1 + s2 == "helloworld"); // false System.out.println("hello" + "world" == "helloworld"); // true } }
1.2 答案
false true
1.3 解释
静态区 常量池中的内容不能重复String s1 = "hello";
会在栈中声明s1,并将"hello"存进常量池中,同时s1存"hello"在常量池中的地址
String s2 = "world";
会在栈中声明s2,并将"world"存进常量池中,同时s2存"world"在常量池中的地址
System.out.println(s1 + s2 == "helloworld");
s1 + s2:会产生一个新的地址空间,里面存的是不知道的地址
helloworld:此时发现常量池中没有"helloworld"字符串,就立马创建,并将创建
后的字符串地址与s1 + s2后不知名的地址做一比较,发现不想等。所以false
System.out.println("hello" + "world" == "helloworld");
hello:常量池中有,不用创建
world:常量池中有,不用创建
"hello" + "world":相加后为helloworld,发现常量池中已经有helloworld,直接拿来用。
与后面的helloworld比较之后地址相等(实际就是自己跟自己比较地址,因为内容不能重复)
2. 例2
2.1 代码
package com.ilaoda.day0903; /** * 字符串的常见题2 * @author iLaoda */ public class Test2 { public static void main(String[] args) { final String s1 = "hello"; final String s2 = "world"; System.out.println(s1 + s2 == "helloworld"); System.out.println("hello" + "world" == "helloworld"); } }
2.2 答案
true true
2.3 解释
final String s1 = "hello";final修饰,表示是常量,此时与栈无关。直接是在常量池中存入"hello"。可以把s1本身就理解为常量,不要理解为引用
String s2 = "world";
final修饰,表示是常量,此时与栈无关。直接是在常量池中存入"world"。可以把s2本身理解为常量,不要理解为引用
s1 + s2 == "helloworld"就相等于"hello" + "world" == "helloworld"是一个样子
3. 例3
3.1
String s1 = "abc"; String s2 = new String("abc"); //这句话创建了几个对象
答案: 1个
解释:第一句已经在常量池中创建一个“abc”,执行第二句时,在堆中new String,发现常量池中已经有“abc”,直接让堆中的new stirng再指向常量池中的“abc”,所以就创建了一个对象。
3.2
String s1 = new String("abc"); //这句话创建了几个对象
答案:两个
解释:在堆中new String,堆内开辟了空间,创建了一个对象。发现常量池中没有“abc”,这时再在常量池中创建一个字符串对象。所以两个。
我觉得这两句话挺重要的:1. 常量池中的内容不能重复 2.字符串常量池中的内容也作为字符串对象存在
3.3
String s1 = new String("abc"); // 创建两个对象 String s2 = new String("abc"); // 创建1个对象
4. 关于final修饰的成员变量和局部变量初始化赋值的几种形式
以下代码没有执行,但是都没有报错。说明语法上没有问题。package com.ilaoda.day0904; /** * 关于final修饰的成员变量和局部变量初始化赋值的几种形式 * @author iLaoda * */ public class Test3 { /** * final修饰的成员变量,可以用以下三种方式初始化赋值: * 1. 声明的时候直接赋值 * 2. 构造方法中赋值 * 3. 构造代码快赋值(其实也是构造方法赋值) */ //1. 声明的时候直接赋值 final int a1 = 1; final int a2; final int a3; //3. 构造代码快赋值(其实也是构造方法赋值) { a2 = 2; } public Test3(int a3) { this.a3 = a3; } // 2. 构造方法中赋值 Test3 test3 = new Test3(5); /** * final修饰的局部变量,可以用以下三种方式初始化赋值: */ public static void haha(int a) { //1. 可以在声明的时候初始化赋值 final int a1 = 1; final int a2; //2. 或者表达式给它赋值。 a2 = a1 + 5; final int a3 = a; } public static void main(String[] args) { //3. 在第一次使用的通过方法 haha(3); } }
5. 输出的结果为多少呢?
5.1 代码
package com.ilaoda.day0905; /** * @author iLaoda */ class C { C() { System.out.print("C"); } } class A { /** * * 对父类中的c成员进行初始化,调用了C类的无参构造 * 因为A类中有C类的成员,在Test创建 */ C c = new C(); A() { this("A"); System.out.print("A"); } A(String s) { System.out.print(s); } } class Test extends A { /** * 执行父类的带参构造前要先对父类中的对象进行初始化, */ Test() { super("B"); System.out.print("B"); } public static void main(String[] args) { new Test(); } }
5.2 答案
CBB
6. 输出结果为多少?
6.1 代码
package com.ilaoda.day0905; /** * 输出结果为多少 * @author iLaoda * */ public class Test2 { static { int x = 5; } static int x, y; // 0 0 public static void main(String args[]) { x--; // x=-1; myMethod(); System.out.println(x + y + ++x); // 从下面可知第一个x为1,y为1 // ++x为2 // 所以:结果为3 } public static void myMethod() { y = x++ + ++x; //真正计算时: y = -1 + 1 = 0 // 第一个 x 进行加运算时为:-1, x++后为:0 // 第二个 x 进行加运算时,这时x已经为0。所以 ++x后,x为1 // 因此 y = 0+1 = 1 } }
6.2 答案
3
相关文章推荐
- 冒泡排序2.0
- javascript组件化
- HDU 3650 Hot Expo(气球染色 , 贪心 )
- [Oracle] Transporting Tablespace
- 【转】Python3.x移除了callable内建函数
- zoj3777(状态压缩)
- HDU 3650 Hot Expo(气球染色 , 贪心 )
- hdu 1067 Gap+BFS+hash
- 二叉树的创建(前序中序创建二叉树、中序后序创建二叉树)
- 利用深度优先搜索算法寻找割点
- ESXi5.5如何命令行升级到ESXi6.0
- postgresql配置的一些问题
- hdu 3336 count the string(KMP+dp)
- 连续子数组最大和
- STL中各个容器的底层数据结构
- 20150903 Java学习笔记之继承性
- CentOS执行SU时 Authentication failure
- C++标准库bind函数
- javascript Date类型 学习笔记
- 【树链剖分】 HDU 4729 An Easy Problem for Elfness 二分