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


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. BZOJ3529 [Sdoi2014]数表 【莫比乌斯反演】

    3529: [Sdoi2014]数表 Time Limit: 10 Sec Memory Limit: 512 MB Submit: 2151 Solved: 1080 [Submit][Status ...

  2. Codeforces Round #534 (Div. 2) D. Game with modulo(取余性质+二分)

    D. Game with modulo 题目链接:https://codeforces.com/contest/1104/problem/D 题意: 这题是一个交互题,首先一开始会有一个数a,你最终的 ...

  3. HDU 5881--Tea 思维规律

    感谢http://blog.csdn.net/black_miracle/article/details/52567718 题意:有一壶水, 体积在 L和 R之间, 有两个杯子, 你要把水倒到两个杯子 ...

  4. IDEA无法编译java8的lambda表达式提示Error:(16, 48) java: -source 1.5 中不支持 lambda 表达式

    在idea中新建了一个java8的项目,但是写lambda表达式提示语法错误,提示如下错误信息: Error:(16, 48) java: -source 1.5 中不支持 lambda 表达式 (请 ...

  5. 51nod 1076 2条不相交的路径

    给出一个无向图G的顶点V和边E.进行Q次查询,查询从G的某个顶点V[s]到另一个顶点V[t],是否存在2条不相交的路径.(两条路径不经过相同的边)   (注,无向图中不存在重边,也就是说确定起点和终点 ...

  6. 培训补坑(day7:线段树的区间修改与运用)(day6是测试,测试题解以后补坑QAQ)

    补坑咯~ 今天围绕的是一个神奇的数据结构:线段树.(感觉叫做区间树也挺科学的.) 线段树,顾名思义就是用来查找一段区间内的最大值,最小值,区间和等等元素. 那么这个线段树有什么优势呢? 比如我们要多次 ...

  7. Django-Django的form表单

    注册页面如果用ajax来做,视图views里面判断会很复杂,需要判断各种字段,我们用form来做   form_obj,实例化form_post(form_obj)对象,一定要加上(request.P ...

  8. 正则表达式 re模块 collections模块

    根据手机号码一共11位并且是只以13.14.15.18开头的数字这些特点,我们用python写了如下代码: while True: phone_number = input('please input ...

  9. container_of分析--可用good【转】

    转自:http://blog.csdn.net/tigerjibo/article/details/8299589 版权声明:本文为博主原创文章,未经博主允许不得转载. 1.container_of宏 ...

  10. HTTP===如何理解网关

    首先举个例子: 假设你的名字叫小不点(很小),你住在一个大院子里,你的邻居有很多小伙伴,父母是你的网关.当你想跟院子里的某个小伙伴玩,只要你在院子里大喊一声他的名字,他听到了就会回应你,并且跑出来跟你 ...