java中常见的关于String的题目
来源:互联网 发布:球球大作战辅助软件 编辑:程序博客网 时间:2024/04/30 10:05
在看题目之前,首先来看一张图片:
该图截自JDK API,相信大家已经看到我在图中用红色圈圈,圈出来的部分,对,String类是被定义为final的,是不可变类,本文不针对这点做过多阐述,有兴趣的可以参阅这篇文章:J2SE基础夯实系列之String字符串不可变的理解,不可变类,final关键字到底修饰了什么
下面看一些具体的问题:
1.String s1 = "ab";
String s2 = new String("ab");
System.out.println(s1 == s2);
System.out.println(s1.equals(s2));
这段代码的输出会是啥呢?
答案是:
false
true
这个问题首先要注意的是==与equals的区别
==是比较是s1与s2是否是同一个对象,上面的s1与s2不是同一个对象,s1的“ab”是在String pool中,而s2的“ab”是在堆中,二者并不是同一个对象,所以输出false
equals呢是比较s1与s2中的内容是否相同,显然二者相同,所以输出true
- 2.
- String s = new String("abc");
- String s1 = "abc";
- String s2 = new String("abc");
- System.out.println(s == s1);
- System.out.println(s == s2);
- System.out.println(s1 == s2);
第一句执行后内存中有两个对象,而不是一个(可以参考这篇文章:java中String s = new String("abc")创建了几个对象?!)。一个由new String("abc")中的"abc"在String Pool里生成一个值为"abc"的对象;第二个由new在堆里产生一个值为"abc"的对象,该对象完全是String Pool里的"abc"的一个拷贝。变量s最后指向堆中产生的"abc"对象;
第二句执行时,s1先去String Pool找是否有值为"abc"的对象,很显然在上一步中java已经在String Pool里生成一个"abc"对象了,所以s1直接指向String Pool中的这个"abc";
第三句中又有一个new,在java中凡遇到new时,都会在堆里产生一个新的对象。因此,该句执行后堆里又多了一个"abc"对象,这与执行第一句后生成的"abc"是不同的两个对象,s2最后指向这个新生成的对象。
因此,执行后面的打印语句的结果是三个false
3.
String str2 = new String("abc");
if(str1 == str2)
{
System.out.println("str1 == str2");
}
if(str1.equals(str2))
{
System.out.println("str1 equals str2");
}
String str3 = "abc";
String str4 = "abc";
if(str3 == str4)
{
System.out.println("str3 == str4");
}
if(str3.equals(str4))
{
System.out.println("str3 equals str4");
}
if(str1 == str4)
{
System.out.println("str1 equals str4");
}
if(str1.equals(str4))
{
System.out.println("str1 equals str4");
}
运行结果为:
str1 equals str2
str3 == str4
str3 equals str4
str1 equals str4
为什么会出现这样的结果。。。这需要引入一些概念,其实很类似C++ 或C#之类,差别只是小小的。。。
首先了解一个对象在内存中创建的区域:
1.heap(即堆区):它是负责创建对象的,所有的创建出来的对象都是放在堆区的。所有new操作的创建的实例都存储在这里,包括用new String 创建的String。
2.stack(即栈区):它是负责存放局部变量,和成员变量的。所有的成员变量和局部变 量都放在这个区内,然后他通过一个引用指向栈区的对象或data segment(静态代码)区的静态数据。
3.data segment(静态代码区):在这个区主要存放的是静态常量,和字符串常量(字符串池)。在类一开始被加载的时候此常量就被初始化放在这个区内,而且被全局所共享,所有的访问直接指向他即可。
4.code segment(代码区):它是存放代码的区,所有的执行代码都放在此区内。通过对象的调用指向此区。
4.String s = "a" + "b" + "c" + "d" + "e";问此语句共创建了几个对象
答案是:创建了一个对象
可以尝试运行这段程序
String s1 = "a"; String s2 = s1 + "b"; String s3 = "a" + "b"; System.out.println(s2 == "ab"); System.out.println(s3 == "ab"); String s = "a" + "b" + "c" + "d"; System.out.println(s == "abcd");
运行结果为:
- false
- true
- true
第一条语句打印的结果为false,第二条语句打印的结果为true,这说明javac编译可以对字符串常量直接相加的表达式进行优化,不必要等到运行期去进行加法运算处理,而是在编译时去掉其中的加号,直接将其编译成一个这些常量相连的结果。题目中的代码被编译器在编译时优化后,相当于直接定义了一个”abcd”的字符串,所以,题目中的代码应该只创建了一个String对象。
写如下两行代码,String s = "a" + "b" + "c" + "d";
System.out.println(s == "abcd");最终打印的结果应该为true
在文章最后贴上这些类型题目的一个代码^_^:
public class Test{ public static void main(String[] args){ String s1 = "a"; String s2 = s1 +"b"; String s3 = "a" + "b"; System.out.println("s2 == \"ab\" " + (s2 == "ab")); System.out.println("s3 == \"ab\" " + (s3 == "ab")); String s4 = "ab"; String s5 = new String("ab"); String s6 = new String("ab"); System.out.println("s4 == s5 " + (s4 == s5)); System.out.println("s4.equals(s5) " + (s4.equals(s5))); System.out.println("s4 == s3 " + (s4 == s3)); System.out.println("s2 == s5 " + (s2 == s5)); System.out.println("s5 == s6 " + (s5 == s6));}}
输出结果是:
- java中常见的关于String的题目
- java的常见题目
- java中String的常见用法
- java中String类的常见用法
- java中String的常见用法
- JAVA中String类的常见操作
- (转)java中String的常见用法
- Java中字String的常见用法
- 杭电ACM中一部分关于string的题目
- java面试题中常见的关于String类问题总结
- Java面试常见的题目
- java面试的常见题目
- Java笔试、面试中常见的题目记录
- 关于Java中HashMap的常见应用
- java中String的字符串方法典型题目
- 关于Java中String内存的学习
- 关于java中String 的内存解析
- 关于java中string.length()的问题
- 【IOS】动画总结:UIView动画(Animations)
- Linux基本配置和管理 5 ---- RPM软件包管理
- PBOC卡片应用分析(一)
- metaq部署
- myeclipse配置tomcat
- java中常见的关于String的题目
- 2014迅雷校园招聘笔试题答案
- NoSQL代表: Mongo DB(芒果数据库)
- Linux下安装Erlang
- 二叉树的先序,中序,后序遍历的非递归算法
- [Linux/Unix C 编程] perror函数,strerror函数,errno
- Android桌面组件开发之实时文件夹(Live_Folders)
- iOS 获取本机可以存放文件的路径
- Java过滤器实现原理