这个谜题要问的是一个悦耳的问题,下面的程序将打印什么呢?


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的更多相关文章

  1. samtools常用命令详解

    samtools的说明文档:http://samtools.sourceforge.net/samtools.shtmlsamtools是一个用于操作sam和bam文件的工具合集.包含有许多命令.以下 ...

  2. Objective-C 代码块(block)的使用

    代码块本质上是和其他变量类似.不同的是,代码块存储的数据是一个函数体.使用代码块是,你可以像调用其他标准函数一样,传入参数数,并得到返回值. 脱字符(^)是块的语法标记.按照我们熟悉的参数语法规约所定 ...

  3. SQL SERVER 简介及应用 - 数据库系统原理

    SQL SERVER 是一个分布式的关系型数据库管理系统(RDBMS),具有客户 - 服务器体系结构,一般发行的版本有企业版.标准版.个人版.开发版. SQL SERVER 提供的服务 MS SQL ...

  4. 简单的block

    int multi = 7;                int (^myBlock)(int) = ^(int num){            return num * multi;       ...

  5. javascript:正则大全

    :replace函数,为写自己的js模板做准备 待完善 function 1,声明&用法 //数组: var arr=[];//字面量 var arr=new Array();//构造函数 / ...

  6. Python list方法总结

    1. 向列表的尾部添加一个新的元素 append(...) L.append(object) -- append object to end 1 2 3 4 >>> a = ['sa ...

  7. samtools常用命令详解(转)

    转自:samtools常用命令详解 samtools的说明文档:http://samtools.sourceforge.net/samtools.shtml samtools是一个用于操作sam和ba ...

  8. Redis安装及基本配置

    一.Redis介绍 1.Redis是一个key-value存储系统 2.官方站点http://redis.io 3.Redis和Memcached类似,但支持数据持久化 4.支持更多value类型,除 ...

  9. Python核心编程--学习笔记--6--序列(下)列表、元组

    11 列表 类似于C语言的数组,但是列表可以包含不同类型的任意对象.列表是可变类型. 创建列表——手动赋值.工厂函数: >>> aList = [12, 'abc'] >> ...

随机推荐

  1. CodeForces 167B - Wizards and Huge Prize 期望概率dp

    初步分析:把赢了的巡回赛的a值加起来就是最后的剩余空间 这个明显的是状态转移的dp啊,然而他的状态比较骚是个数组,表示剩余空间,f(i,j,b),i表示比到第几场,j表示赢了几场,b就是里面的核心状态 ...

  2. 设计一个JavaScript框架需要编写哪些模块

    在这个js框架随处乱跑的时代,你是否考虑过写一个自己的框架?下面的内容也许会有点帮助. 一个框架应该包含哪些内容? 1. 语言扩展 大部分现有的框架都提供了这部分内容,语言扩展应当是以ECMAScri ...

  3. codeforces 1015B

    B. Obtaining the String time limit per test 1 second memory limit per test 256 megabytes input stand ...

  4. AngularJS+BootStrap的一些插件

    插件网址:http://jquerypluginplus.com/ 树  1.angular-bootstrap-nav-tree http://jquerypluginplus.com/angula ...

  5. centos7装机时更改网卡名为eth0操作

  6. phpAdmin 修改密码后拒绝登陆

    phpMyadmin没配置正确,打开 phpMyadmin 目录找到config.inc.php文件,查找到$cfg['Servers'][$i]['password']='';这行,在''中输入你正 ...

  7. 全局axios默认值 和 自定义实例默认值

    首先说了一下情况, 登录后成功返回token 然后在带着token去继续下面的请求, 奇怪的是都是当前页面起作用,刷新和跳转之后就token 就消失了. 查了 axios文档发现 被自己坑了 我设置了 ...

  8. UVALIVE 3939 Plucking fruits

    并查集解决.代码跑的有够慢.应该可以通过边权排序优化. #include <map> #include <set> #include <list> #include ...

  9. Launcher3无图标问题

    MTK8382/8121平台. 机器(8寸,默认竖屏)第一次烧录完成后,以横放姿势启动,发现Launcher没有图标,而竖屏启动是没有这个问题的.在测试过程中发现,在设置中clear data后也会有 ...

  10. 虚拟机VMware 安装CentOS6.5

    对linux完全小白的情况下,也能依据下面的文章,一步一步安装使用成功! CentOS 6.5 下载http://www.linuxdown.net/CentOS/2014/0928/3371.htm ...