谜题12:ABC
这个谜题要问的是一个悦耳的问题,下面的程序将打印什么呢?
public class ABC{
public static void main(String[] args){
String letters = "ABC";
char[] numbers = {‘1’, ‘2’, ‘3’};
System.out.println(letters + " easy as " + numbers);
}
}
可能大家希望这个程序打印出ABC easy as 123。遗憾的是,它没有。如果你运行它,就会发现它打印的是诸如ABC easy as [C@16f0472之类的东西。为什么这个输出会如此丑陋?
尽管char是一个整数类型,但是许多类库都对其进行了特殊处理,因为char数值通常表示的是字符而不是整数。例如,将一个char数值传递给println方法会打印出一个Unicode字符而不是它的数字代码。字符数组受到了相同的特殊处理:println的char[]重载版本会打印出数组所包含的所有字符,而String.valueOf和StringBuffer.append的char[]重载版本的行为也是类似的。
然而,字符串连接操作符在这些方法中没有被定义。该操作符被定义为先对它的两个操作数执行字符串转换,然后将产生的两个字符串连接到一起。对包括数组在内的对象引用的字符串转换定义如下[JLS 15.18.1.1]:
如果引用为null,它将被转换成字符串"null"。否则,该转换的执行就像是不用任何参数调用该引用对象的toString方法一样;但是如果调用toString方法的结果是null,那么就用字符串"null"来代替。
那么,在一个非空char数组上面调用toString方法会产生什么样的行为呢?数组是从Object那里继承的toString方法[JLS 10.7],规范中描述到:“返回一个字符串,它包含了该对象所属类的名字,‘@’符号,以及表示对象散列码的一个无符号十六进制整数”[Java-API]。有关Class.getName的规范描述到:在char[]类型的类对象上调用该方法的结果为字符串"[C"。将它们连接到一起就形成了在我们的程序中打印出来的那个丑陋的字符串。
有两种方法可以订正这个程序。你可以在调用字符串连接操作之前,显式地将一个数组转换成一个字符串:
System.out.println(letters + " easy as " + String.valueOf(numbers));
或者,你可以将System.out.println调用分解为两个调用,以利用println的char[]重载版本:
System.out.print(letters + " easy as ");
System.out.println(numbers);
请注意,这些订正只有在你调用了valueOf和println方法正确的重载版本的情况下,才能正常运行。换句话说,它们严格依赖于数组引用的编译期类型。
下面的程序说明了这种依赖性。看起来它像是所描述的第二种订正方式的具体实现,但是它产生的输出却与最初的程序所产生的输出一样丑陋,因为它调用的是println的Object重载版本,而不是char[]重载版本。
class ABC2{
public static void main(String[] args){
String letters = "ABC";
Object numbers = new char[] { ‘1’, ‘2’, ‘3’ };
System.out.print(letters + " easy as ");
System.out.println(numbers);
}
}
总之,char数组不是字符串。要想将一个char数组转换成一个字符串,就要调用String.valueOf(char[])方法。某些类库中的方法提供了对char数组的类似字符串的支持,通常是提供一个Object版本的重载方法和一个char[]版本的重载方法,而之后后者才能产生我们想要的行为。
对语言设计者的教训是:char[]类型可能应该覆写toString方法,使其返回数组中包含的字符。更一般地讲,数组类型可能都应该覆写toString方法,使其返回数组内容的一个字符串表示。
谜题12:ABC的更多相关文章
- samtools常用命令详解
samtools的说明文档:http://samtools.sourceforge.net/samtools.shtmlsamtools是一个用于操作sam和bam文件的工具合集.包含有许多命令.以下 ...
- Objective-C 代码块(block)的使用
代码块本质上是和其他变量类似.不同的是,代码块存储的数据是一个函数体.使用代码块是,你可以像调用其他标准函数一样,传入参数数,并得到返回值. 脱字符(^)是块的语法标记.按照我们熟悉的参数语法规约所定 ...
- SQL SERVER 简介及应用 - 数据库系统原理
SQL SERVER 是一个分布式的关系型数据库管理系统(RDBMS),具有客户 - 服务器体系结构,一般发行的版本有企业版.标准版.个人版.开发版. SQL SERVER 提供的服务 MS SQL ...
- 简单的block
int multi = 7; int (^myBlock)(int) = ^(int num){ return num * multi; ...
- javascript:正则大全
:replace函数,为写自己的js模板做准备 待完善 function 1,声明&用法 //数组: var arr=[];//字面量 var arr=new Array();//构造函数 / ...
- Python list方法总结
1. 向列表的尾部添加一个新的元素 append(...) L.append(object) -- append object to end 1 2 3 4 >>> a = ['sa ...
- samtools常用命令详解(转)
转自:samtools常用命令详解 samtools的说明文档:http://samtools.sourceforge.net/samtools.shtml samtools是一个用于操作sam和ba ...
- Redis安装及基本配置
一.Redis介绍 1.Redis是一个key-value存储系统 2.官方站点http://redis.io 3.Redis和Memcached类似,但支持数据持久化 4.支持更多value类型,除 ...
- Python核心编程--学习笔记--6--序列(下)列表、元组
11 列表 类似于C语言的数组,但是列表可以包含不同类型的任意对象.列表是可变类型. 创建列表——手动赋值.工厂函数: >>> aList = [12, 'abc'] >> ...
随机推荐
- MySQL使用笔记(六)条件数据记录查询
By francis_hao Dec 17,2016 条件数据记录查询 mysql> select field1,field2-- from table_name where 条件; 其中 ...
- TSP问题之状压dp法
首先,我们先来认识一下什么叫做TSP问题 旅行商问题,即TSP问题(Traveling Salesman Problem)又译为旅行推销员问题.货郎担问题,是数学领域中著名问题之一.假设有一个旅行商人 ...
- source改变当前路径
转摘自:http://hi.baidu.com/homappy/item/90e416525d2faf958c12edb7 Shell 脚本执行有三种方法 bash 脚本名 sh 脚本名 chmod ...
- JavaScript 页面间传值
转自:http://blog.csdn.net/qq380107165/article/details/7330612 一:JavaScript静态页面值传递之URL篇 能过URL进行传值,把要传递的 ...
- 转:增强学习(二)----- 马尔可夫决策过程MDP
1. 马尔可夫模型的几类子模型 大家应该还记得马尔科夫链(Markov Chain),了解机器学习的也都知道隐马尔可夫模型(Hidden Markov Model,HMM).它们具有的一个共同性质就是 ...
- git分支开发,分支(feature)同步主干(master)代码,以及最终分支合并到主干的操作流程
由于rebase执行速度慢,分支同步主干代码时,分支的每次提交都可能和主干产生冲突,需要解决的次数太多,影响提交效率. 同时,为了保证主干提交线干净(可以安全回溯),所以采用下面所说的merge法. ...
- Apache多网站虚拟目录域名
一台服务器安装了Apache,如何绑定多个域名或网站呢? 最简单高效的方法如下: 1. 先打开Apache的配置文件httpd.conf,在这个文件, 找到这句:“#Include etc/extra ...
- swift对比object-c
http://www.cocoachina.com/bbs/read.php?tid=204294 WWDC 2014上苹果再次惊世骇俗的推出了新的编程语言SWIFT( 雨燕 ), 这个消息会前没有半 ...
- 关于might_sleep的一点说明---CONFIG_DEBUG_ATOMIC_SLEEP【转】
转自:http://blog.chinaunix.net/uid-23769728-id-3157536.html 这个函数我在看代码时基本上是直接忽略的(因为我知道它实际上不干什么事),不过因为内核 ...
- Google的C++开源代码项目
Google的C++开源代码项目 http://www.open-open.com/lib/view/open1413873531356.html v8 - V8 JavaScript Engin ...