谜题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'] >> ...
随机推荐
- 【Cf edu 30 B. Balanced Substring】
time limit per test 1 second memory limit per test 256 megabytes input standard input output standar ...
- APP兼容性测试
一.APP兼容性范围以及问题 1.硬件 各个硬件结构 2.软硬件之间 硬件dll库(C++) 软硬件之间的通信,各个厂商提供的ROM 3.软件 浏览器.操作系统.数据库.手机.功能兼容性(功能修改,二 ...
- [CVPR2018]Learning to Adapt Structured Output Space for Semantic Segmentation
学习适应结构化输出空间进行语义分割 在语义分割场景中,虽然物体在外表上不同,但是他们的输出是结构化且共享很多例如空间分布, 局部内容等信息.所以作者提出了multi-level的输出空间adaptat ...
- POJ3682 King Arthur's Birthday Celebration
King Arthur is an narcissist who intends to spare no coins to celebrate his coming K-th birthday. Th ...
- [bzoj3004][SDOI2012]吊灯——樹形DP
Brief Description 給定一棵樹, 判斷是否可以將其分成\(\frac{n}{k}\)個聯通塊, 其中每個聯通塊的大小均爲k. Algorithm Design 我們有一個結論: k可行 ...
- sphinx 分词搭建手册
步奏1. yum install make gcc g++ gcc-c++ libtool autoconf automake imake mysql-devel libxml2-devel expa ...
- KVM基本概念
在kvm技术中,应用到的两个东西:qemu和kvm.其中kvm负责cpu虚拟化和内存虚拟化,但是kvm不能模拟其他设备,qemu是模拟IO设备(网卡,磁盘),kvm加上qemu之后就能实现真正意义上的 ...
- ZigBee MAC层(上)
1. 介绍 ZigBee MAC层,即IEEE 802.15.4 MAC层,这里主要介绍了802.15.4-2003版本 MAC层处理所有对物理无线信道的访问控制,并负责下面的任务 - 为协调器生成网 ...
- /usr/bin/expect介绍
/usr/bin/expect介绍 http://blog.csdn.net/zhu_tianwei/article/details/44180637 概述 我们通过Shell可以实现简单的控制流功能 ...
- C# 后台首次加载时才执行
protected void Page_Load(object sender, EventArgs e) { if (!IsPostBack) { } } 写在 if (!IsPostBack) { ...