大头儿子和小头爸爸的战斗--java字符和字符串
故事背景
一座普普通通的小屋里,住着大头儿子、小头爸爸和围裙妈妈。在他们普普通通的生活中,总是响起充满欢乐的笑声。最温暖的家又成了他们每个人的爱的源泉。
《大头儿子和小头爸爸》是孩子居首(大头),妈妈居中,爸爸最末(小头);爸爸主外,妈妈主内(围裙),他们是中国现代家庭教育典型的缩影。
java中的大头儿子和小头爸爸
java中也有一对冤家对头,他们就是字符char和字符串String。来看看他们的表现吧:
System.out.println("h"+"i");
System.out.println('h'+'i');
会打印出什么呢?结果可能出乎你的意外:
hi
209
为什么会出现209这个结果呢?
编译器在计算常量表达式'h'+'i'时,是通过我们熟知的拓宽原始类型转换将两个具有字符型数值的操作数('h'和'i')提升为int 数值而实现的。从char 到int 的拓宽原始类型转换是将16 位的char 数值零扩展到32 位的int。对于'h',char 数值是104,而对于'i',char 数值是105,因此表达式'h'+'i'等价于int常量104 + 105,或209。
有三种方式避免出现char的连接问题。第一种最简单:
System.out.println("" + 'h' + 'i');
第二种:使用函数
System.out.printf("%c%c", 'h', 'i');
或者
System.out.println(String.format("%c%c", 'h','i'));
第三种,利用api拼装:
StringBuffer sb = new StringBuffer();
sb.append('h');
sb.append('i');
System.out.println(sb);
也会你会认为这比较简单,那我们就见识一个比较复杂点的吧!
private static Random rnd = new Random();
public static void main(String[] args) {
StringBuffer word = null;
switch(rnd.nextInt(2)) {
case 1: word = new StringBuffer('P');
case 2: word = new StringBuffer('G');
default: word = new StringBuffer('M');
}
word.append('a');
word.append('i');
word.append('n');
System.out.println(word);
}
乍一看,这个程序可能会在一次又一次的运行中,以相等的概率打印出Pain,Gain 或 Main。看起来该程序会根据随机数生成器所选取的值来选择单词的第一个字母:0 选M,1 选P,2 选G。它实际上既不会打印Pain,也不会打印Gain。也许更令人吃惊的是,它也不会打印Main,并且它的行为不会在一次又一次的运行中发生变化,它总是在打印ain。这又是为什么呢?
多个问题,纠结在一起导致了这个问题:
1.Random.nextInt(int)的规范描述道:“返回一个伪随机的、均等地分布在从0(包括)到指定的数值(不包括)之间的一个int 数值”[Java-API]。这意味着表达式rnd.nextInt(2)可能的取值只有0和1,Switch语句将永远也到不了case2 分支,这表示程序将永远不会打印Gain。nextInt 的参数应该是3 而不是2。
2. case中没有任何break 语句。不论switch 表达
式为何值,该程序都将执行其相对应的case 以及所有后续的case[JLS 14.11]。因此,尽管每一个case 都对变量word 赋了一个值,但是总是最后一个赋值胜出,覆盖了前面的赋值。最后一个赋值将总是最后一种情况(default),即new StringBuffer{'M'}。这表明该程序将总是打印Main,而从来不打印Pain或Gain。
3.在本例中,编译器会选择接受int 的构造器,通过拓宽原始类型转换把字符数值'M'转换为一个int 数值77[JLS 5.1.2]。换句话说,new StringBuffer('M')返回的是一个具有初始容量77 的空的字符串缓冲区。该程序余下的部分将字符a、i 和n 添加到了这个空字符串缓冲区中,并打印出该字符串缓冲区那总是ain 的内容。
修改如下:
private static Random rnd = new Random();
public static void main(String[] args) {
System.out.println("PGM".charAt(rnd.nextInt(3)) + "ain");
}
参考资料
【1】java解惑
【2】https://baike.baidu.com/item/%E5%A4%A7%E5%A4%B4%E5%84%BF%E5%AD%90%E5%92%8C%E5%B0%8F%E5%A4%B4%E7%88%B8%E7%88%B8/2346537?fromtitle=%E5%A4%A7%E5%A4%B4%E5%84%BF%E5%AD%90%E5%B0%8F%E5%A4%B4%E7%88%B8%E7%88%B8&fromid=3076860&fr=aladdin
大头儿子和小头爸爸的战斗--java字符和字符串的更多相关文章
- java字符统计+字符串压缩
要实习了.突然发现自己好像什么都不会,就去看看题吧.在网上看到一个字符串压缩的题.看了一眼,感觉用python很简单.一个for循环+字典就可以搞定. 但是呢,主要还是java.下面就用java来实现 ...
- Java 字符与字符串
字符 // 定义字符 char c1 = 'a'; char c2 = '1'; char c3 = '中'; // 自动装箱 Character c = c1; // 自动拆箱 c1 = c; // ...
- java字符,字符串,数字之间的转换
string 和int之间的转换 string转换成int :Integer.valueOf("12") int转换成string : String.valueOf(12) ch ...
- 【JAVA编码专题】 JAVA字符编码系列三:Java应用中的编码问题
这两天抽时间又总结/整理了一下各种编码的实际编码方式,和在Java应用中的使用情况,在这里记录下来以便日后参考. 为了构成一个完整的对文字编码的认识和深入把握,以便处理在Java开发过程中遇到的各种问 ...
- 关于JAVA字符编码:Unicode,ISO-8859-1,GBK,UTF-8编码及相互转换
我们最初学习计算机的时候,都学过ASCII编码. 但是为了表示各种各样的语言,在计算机技术的发展过程中,逐渐出现了很多不同标准的编码格式, 重要的有Unicode.UTF.ISO-8859-1和中国人 ...
- 小伙子又乱码了吧-Java字符编码原理总结
前提 配合前面阅读的I/O和NIO的资料,现在总结一下关于字符集和乱码问题的原理和解决方案.参考资料: 码表ASCII Unicode GBK UTF-8 字符编码笔记ASCII,Unicode和UT ...
- java字符编码详解
引用自:http://blog.csdn.net/jerry_bj/article/details/5714745 GBK.GB2312.iso-8859-1之间的区别 GB2312,由中华人民共和国 ...
- JAVA字符编码三:Java应用中的编码问题
第三篇:JAVA字符编码系列三:Java应用中的编码问题 这部分采用重用机制,引用一篇文章来完整本部分目标. 来源: Eceel东西在线 问题研究--字符集编码 地址:http://china.e ...
- 【字符编码】Java字符编码详细解答及问题探讨
一.前言 继上一篇写完字节编码内容后,现在分析在Java中各字符编码的问题,并且由这个问题,也引出了一个更有意思的问题,笔者也还没有找到这个问题的答案.也希望各位园友指点指点. 二.Java字符编码 ...
随机推荐
- Atcoder E - Meaningful Mean(线段树+思维)
题目链接:http://arc075.contest.atcoder.jp/tasks/arc075_c 题意:问数组a有多少子区间平均值为k 题解:一开始考虑过dp,但是显然不可行,其实将每一个数都 ...
- zoj 3261 Connections in Galaxy War(并查集逆向加边)
题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3261 题意:有很多颗星球,各自有武力值,星球间有一些联系通道,现 ...
- POJ 2230 Watchcow 欧拉图
Watchcow Time Limit: 3000MS Memory Limit: 65536K Total Submissions: 8800 Accepted: 3832 Specia ...
- react页面内嵌微信二维码 和 自定义样式 以及 微信网页共用unionId问题
在react页面内嵌“微信二维码”,实现PC端通过微信扫码进行登录.首先去微信开放平台注册一个账号,创建一个网站应用,提交网站备案审核,获取appid和appsecret:其他开发流程根据微信文档来进 ...
- 告别组件之教你使用原生js和css写移动端轮播图
在工作中由于项目需要要写一个轮播图,本想使用组件直接调用实现快速开发,但是一想到自己经常使用组件但是让自己手写的话确实一点都不会. 一个不会手写组件的前端程序员不是一个好程序员!于是打算自己手写一个. ...
- Java SPI详解
1.什么是SPI SPI全称Service Provider Interface,是Java提供的一套用来被第三方实现或者扩展的接口,它可以用来启用框架扩展和替换组件. SPI的作用就是为这些被扩展的 ...
- python读取大文件只能读取部分的问题
最近准备重新研究一下推荐系统的东西,用到的数据集是Audioscrobbler音乐数据集.我用python处理数据集中artist_data.txt这个文件的时候,先读取每一行然后进行处理: with ...
- C#客户端程序Visual Stadio远程调试
一,需求来源 在开发过程中,可能会要使用Win7 ,Win8 ,Win10等不同版本的系统去做兼容性调试,也有时候会去针对特别的显卡,无线网卡等等硬件设备的机器做优化,有一种较优的方案,那就是使用Vi ...
- Apache JMeter (二)性能测试 入门实例
上一节我们说了关于Jmeter环境的配置,接下来讲一个测试的实例. 1.运行Jmeter 进入Jmeter程序所在目录,运行"bin/jmeter.bat" Jmeter支持中文, ...
- 初始mqtt服务
MQTT入门 概念 mqtt意为消息队列遥测传输,是IBM开发的一个即时通讯协议.由于其维护一个长连接以轻量级低消耗著称,所以常用于移动端消息推送服务开发. 协议格式 mqtt协议控制报文的格式包含三 ...