【java 基础 9】原来我从没有了解过String类
导读:这两天没有做项目,然后就想着把之前在项目中用到过的东西总结总结。记得之前做今日开讲项目时,在比较学生学号的时候,我最开始用的是“==”,但是,实践证明,这个玩意儿吧,总是很奇怪,有时候对有时候不对。后来就换成了equals,结果就好多了。那时候我就在想,这两个有什么区别,string类型到底是怎么回事?现在总结总结,也祭奠一下当年面试笔试题的那些亡魂!
一、实例分析
首先,看看代码段:
public class stringTest {
	private static String getA()
	{
		return "a";
	}
	public static void testString()
	{
		String a="a";
		final String c="a";
		String b=a+"b";
		String d=c+"b";
		String e=getA()+"b";
		String compare="ab";
		System.out.print(b==compare);
		System.out.print(d==compare);
		System.out.print(e==compare);
	}
}
我先说一下,我最开始得出的答案:true,true,true。原因如下:
1,因为a变量代表了一个常量定值“a”,然后b在编译的时候就会得到b="ab",所以结果是true;
2,因为C变量用了final关键字修饰,代表这个变量不会被更改,那么d 就会是一个固定的值“ab”,而==比较的是地址值,所以true;
3,因为getA()方法是静态方法嘛,这个我觉得跟 2 的原因差不多,所以就是true。
对于我的答案,我只能借用我宇哥的一句台词,拿出你的红笔。。。。。。(画个大大的 × )
运行结果输出:
对此,我竟无言以对!
解析:
1,false:compare是个常量,而b不是。b=a+"b",a不是一个常量,尽管a作为一个局部变量,指向一个常量。但是,它的引用上并未进行“强制约束”是不可被改变的。它只会在这段代码中不会改变,但是在运行的时候,则不一定。在“字节码增强”技术(话说,这个好像是java 8的东西)面前,代码被切入,就可能会发生改变。所以,编译器时不会将b在编译的时候,优化为“ab”的。在运行时,会被编译为:
StringBuilder temp=new StringBuilder();
temp.append(a).append("b");
String b=temp.toString();
2,true,我解释正确!请看上面。因为final进行修饰为不可改变,所以代码在编译时被优化为"ab",结果true
3,false:这个e值的内容来源于一个方法和一个常量的叠加。虽然方法内部返回了一个常量的引用,但是,编译器不会去看方法内部做了什么,如果编译器非要知道方法内部返回什么,那么则需要采用递归。一旦采用递归,深度就不可控,同时也并不是递归后就一定能够确保返回一个指定的常量。(即使是常量,这也是通过对引用拷贝返回,这个引用还可能发生变化)所以,编译器不会做出优化,结果false!
备注:编译器优化一定是在编译阶段能确定优化后,不会影响整体功能,类似于final引用,这个引用只能被赋值一次,但是它无法确定赋值的内容是什么,只有在编译阶段能确定这个final引用赋值的内容,编译器才有可能进行编译时优化。而在编译阶段能确定的内容,只能来自于常量池,例如int、long、string等常量。(顿时想到了当年学习C++时的编译时多态和运行时多态)
看了上面的分析,再来一个代码段:
public static void main(String[] agrs)
{
String a="a";
String b=a+"b";
String c="ab";
String d=new String(b); System.out.println(b==c);
System.out.println(c==d);
System.out.println(c==d.intern());
System.out.println(b.intern()==d.intern());
}
经过上一个代码段,这个我全对了,但是,只有前面两个是自己经过分析,后面两个一半分析,一半感觉(之前总结JVM溢出时,有查过这个intern()的方法)
intern():JVM会在这个常量池中通过equals方法查找是否存在等值的String,如果存在,则直接返回常量池中这个String对象的地址,如果没有找到,则会创建等值的字符串,然后再返回这个新创建空间的地址。只要是同样的字符串,当电泳intern()方法时,都会得到常量池中对应的String引用,所以,两个字符串通过intern()操作后用等号是可以匹配的。
二、代码总结
对于每一个代码段,我都自己分析了一下。其实我会得出错误的结果,一方面是由于对string类本身的不理解,另外也有对于java内存分配运行机制不了解,还有一个也是对于“==”和equals的不理解。因为有些答案,如果换成equals就对了。从这也反映出,自己对于基础功底的忽略和总结,接下来要继续努力学习啦。之前做的项目没有好好总结,感觉自己都废了!
练武不练功,到老一场空!
【java 基础 9】原来我从没有了解过String类的更多相关文章
- java基础复习:final,static,以及String类
		2.final 1)为啥String是final修饰的呢? 自己答: 答案: 主要是为了“效率” 和 “安全性” 的缘故.若 String允许被继承, 由于它的高度被使用率, 可能会降低程序的性能,所 ... 
- JAVA基础学习之路(八)[1]String类的基本特点
		String类的两种定义方式: 直接赋值 通过构造方法赋值 //直接赋值 public class test2 { public static void main(String args[]) { S ... 
- JAVA基础学习之路(九)[2]String类常用方法
		字符与字符串: 1.将字符数组变为字符串(构造方法) public String(char[] value) Allocates a new String so that it represents ... 
- Java基础知识二次学习--第六章 常用类
		第六章 常用类 时间:2017年4月26日16:14:49~2017年4月26日16:56:02 章节:06章_01节~06章_06节 视频长度:20:57+1:15+8:44+1:26+11:2 ... 
- 夯实Java基础系列3:一文搞懂String常见面试题,从基础到实战,更有原理分析和源码解析!
		目录 目录 string基础 Java String 类 创建字符串 StringDemo.java 文件代码: String基本用法 创建String对象的常用方法 String中常用的方法,用法如 ... 
- Java 基础(三)| IO流之使用 File 类的正确姿势
		为跳槽面试做准备,今天开始进入 Java 基础的复习.希望基础不好的同学看完这篇文章,能掌握泛型,而基础好的同学权当复习,希望看完这篇文章能够起一点你的青涩记忆. 一.什么是 File 类? java ... 
- Java基础知识回顾之二 ----- 修饰符和String
		前言 在上一篇中,回顾了Java的基本数据类型 ,这篇就来回顾下Java中的一些修饰符以及String. 修饰符介绍 Java修饰符主要分为两类: 访问修饰符 非访问修饰符 其中访问修饰符主要包括 p ... 
- Java基础知识笔记第八章:常用的实体类
		String类 String类位于lang包下 java会默认导入lang包下的类,所以可以直接使用,注意String是final类所以不能有子类 构造String对象: 常量对象:String常量也 ... 
- Java源码赏析(五)再识 String 类
		在 Java源码赏析(三)初识 String 类 中,我们已经大概理解了String的接口,接下来我们描述一下String的常用工具方法. /** * 为了精简的String结构,之前提到的方法省 ... 
随机推荐
- kafka基础三
			消费者消费消息过程(一) 消费者组 消费者是以消费者组consumer group的方式进行消息消费的,一个消费者组是由一个或者多个消费者组成的,共同消费一个topic,在每个分区同一时间只能由消费者 ... 
- top 进程管理
			top 动态查看进程 前五行解释: 第一行参数说明: top - 07:06:19 当前时间 up 10 min, 系统运行时间,格式为时:分 1 user, 当前登录用户数 load av ... 
- react中的context的基础用法
			context提供了一种数据共享的机制,里面有两个关键概念——provider,consumer,下面做一些key features描述. 参考网址:https://react.docschina.o ... 
- 【学习笔记】六:面向对象的程序设计——理解JS中的对象属性、创建对象、JS中的继承
			ES中没有类的概念,这也使其对象和其他语言中的对象有所不同,ES中定义对象为:“无序属性的集合,其属性包含基本值.对象或者函数”.现在常用的创建单个对象的方法为对象字面量形式.在常见多个对象时,使用工 ... 
- 解决 Cocos2d-x 3.2 error C1041: 无法打开程序数据库vc120.pdb
			单个项目解决方案 解决方案是为项目添加 /FS (Force Synchronous PDB Writes) 编译选项,具体位置在: 一劳永逸的解决方案 直接修改cocos的项目模板templates ... 
- ios 自定义消息提示框
			自定义提示框,3秒钟后自动消失.如上图显示效果. 提示框加载代码: - (void)viewDidLoad { [super viewDidLoad]; //将view背景颜色变更为黄色 self.v ... 
- matlab均方根误差
			Matlab均方根误差的计算 http://blog.sina.com.cn/s/blog_6210f654010308kv.html 
- 重置Mysql的root密码及用户权限设置
			一.重置Mysql的root密码 方法一: 直接进入localhost/phpmyadmin修改用户root的权限,设置密码: 方法二: 进入mysql控制台:mysql->use mysql ... 
- POJ 2449 Remmarguts' Date
			Time Limit: 4000MS Memory Limit: 65536K Total Submissions: 30725 Accepted: 8389 Description &quo ... 
- Codeforces C 	 The Game of Efil (暴力枚举状态)
			http://codeforces.com/gym/100650 阅读题,边界的cell的邻居要当成一个环形的来算,时间有8s,状态最多2^16种,所以直接暴力枚举就行了.另外一种做法是逆推. #in ... 
