Java五道输出易错题解析(进来挑战下)
转自:http://blog.csdn.net/lanxuezaipiao/article/details/41985243
收集了几个易错的或好玩的Java输出题,分享给大家,以后在编程学习中稍微注意下就OK了。
1. 看不见的空格?
下面的输出会正常吗?
package basic;
public class IntegerTest {
public static void main(String[] args) {
System.out.println(Integer.parseInt("1"));
System.out.println(Integer.parseInt("2"));
}
}
解析:将上面代码复制下(不要自己手敲)在自己的环境里运行看看,是不是输出下面错误来了:
1
Exception in thread "main" java.lang.NumberFormatException: For input string: "2"
at java.lang.NumberFormatException.forInputString(Unknown Source)
at java.lang.Integer.parseInt(Unknown Source)
at java.lang.Integer.parseInt(Unknown Source)
at basic.IntegerTest.main(IntegerTest.java:7)
竟然说第二条语句有问题,表面上完全看不出来任何问题是不是!
实际上这里的错误原因涉及到一个概念 — 零宽度空格,可能有人接触过,但相信更多的人甚至都没听过,什么是零宽度空格?它实际上是一个Unicode字符,是一个空格,关键是它没有宽度,因此我们一般肉眼看不到。但可以在vim下看到,上面的第二条语句中的2前面就有一个零宽度空格,放到vim中打开后你会发现是下面这样的语句:
System.out.println(Integer.parseInt("<feff>2"));
Unicode规范中定义,每一个文件的最前面分别加入一个表示编码顺序的字符,这个字符的名字叫做”零宽度非换行空格“(ZEROWIDTHNO-BREAKSPACE),用FEFF
表示。这正好是两个字节,而且FF比FE大1。因此下面的语句会输出65279,刚好是FEFF
。
System.out.println((int)"2".charAt(0));
2. 类静态成员初始化
下面的程序能编译通过么?如果通过,说结果并解释,不能编译,说错误原因。
class A
{
public static int X;
static { X = B.Y + 1;}
}
public class B
{
public static int Y = A.X + 1;
static {}
public static void main(String[] args) {
System.out.println("X = "+A.X+", Y = "+B.Y);
}
}
解析:这个程序能正确运行,类的运行过程如下:
首先加载主类B,初始化静态成员Y,发现需要类A的信息,于是加载类A,初始化静态成员X,也用到B类信息,由于此时B类的Y还未成功加载因此这里是默认值0,从而得到A类的X为1,然后返回到B类,得到Y为2。
3. 装箱拆箱的实际过程
关于自动装箱,相信大部分人都明白是怎么一回事,但真的完全明白了嘛?
先看下面的代码:
Short s1 = 1;
Short s2 = s1;
System.out.println(s1 == s2);
谁都知道当然打印true了。现在加一句试试:
Short s1 = 1;
Short s2 = s1;
s1++;
System.out.println(s1 == s2);
还是true吗?No,这次输出成了false。WHY?难道s1和s2引用的不是同一个对象吗?有这些疑问的说明你对自动装箱拆箱的过程还不是非常清楚,实际上上面的代码可以翻译为下面的代码(实际执行过程,要掌握):
Short s1 = new Short((short)1);
Short s2 = s1;
short tempS1 = s1.shortValue();
tempS1++;
s1 = new Short(tempS1);
System.out.println(s1 == s2);
哦,原来如此,这下明白了,因此我们在使用自动装箱的时候小心点为妙。
4. 你自以为是的异常
先来两句代码:
NullTest myNullTest = null;
System.out.println(myNullTest.getInt());
相信很多人看到这段代码时,都会自以为是的说:NullPointerException
。果真如此吗?你还没看到NullTest
这个类是如何定义的呢。现在看看这个类的定义:
class NullTest {
public static int getInt() {
return 1;
}
}
由于getInt()是静态方法,他只和类相关,和具体的对象无关,类完成加载时,即可通过类名.getInt()进行调用,因此这里就算对象实例为NULL也会正常输出1.
记住:类变量和类方法的使用,仅仅依赖引用的类型。即使引用为null,仍然可以调用。从良好实践的角度来看,明智的做法是使用NullTest.getInt()
来代替myNullTest.getInt()
,但谁不不能保证不会碰到这样的代码,因此还是小心为妙。
5. 变长参数和数组,如何变通?
变长参数特性带来了一个强大的概念,可以帮助开发者简化代码。不过变长参数的背后是什么呢?Basically,就是一个数组。
public void calc(int... myInts) {}
calc(1, 2, 3);
编译器会将前面的代码翻译成类似这样:
int[] ints = {1, 2, 3};
calc(ints);
不过这里有两点需要注意:
- 当心空调用语句,这相当于传递了一个null作为参数。
calc();
等价于
int[] ints = null;
calc(ints); - 当然,下面的代码会导致编译错误,因为两条语句是等价的:
public void m1(int[] myInts) { ... }
public void m1(int... myInts) { ... }
参考资料
Java五道输出易错题解析(进来挑战下)的更多相关文章
- Java五道输出易错题解析(避免小错误)
收集了几个易错的或好玩的Java输出题,分享给大家,以后在编程学习中稍微注意下就OK了. 1. 看不见的空格? 下面的输出会正常吗? package basic; public class Integ ...
- 【笔试题】Java 易错题精选
笔试题 Java 易错题精选 1.写出下列程序的运行结果( )String 不变性Java 值传递 public class Test { public static void main(String ...
- 10道C++输出易错笔试题收集
下面这些题目都是我之前准备笔试面试过程中积累的,大部分都是知名公司的笔试题,C++基础薄弱的很容易栽进去.我从中选了10道简单的题,C++初学者可以进来挑战下,C++大牛也可以作为娱乐玩下(比如下面的 ...
- 杭电OJ2039——三角形(c++)(易错题:数据类型不确定)
三角形 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submis ...
- hibernate错题解析
01 Hibernate错题分析 解析: 此题目考查的是对Hibernate中交叉连接的理解.HQL支持SQL风格的交叉连接查询,交叉连接适用于两个类之间没有定义任何关联时.在where字句中,通 ...
- JAVA程序改错 (易错题)
JAVA程序改错 1. abstract class Name { private String name; public abstract boolean isStupidName(String n ...
- java考试易错题大全
常见的Java问题 1.什么是Java虚拟机?为什么Java被称作是"平台无关的编程语言"? Java虚拟机是一个可以执行Java字节码的虚拟机进程.Java源文件被编译成能被Ja ...
- Java易错题(1)
检查程序,是否存在问题,如果存在指出问题所在,如果不存在,说明输出结果. public class HelloB extends HelloA { public HelloB() { } { Syst ...
- java易错题----静态方法的调用
class A{ public static String s="A.s"; } class B extends A{ public static String s="B ...
随机推荐
- cmake 没有那个目录
问题:bash: /usr/bin/cmake: 没有那个文件或目录 因为直接使用cmake系统回到默认的/usr/bin中去寻找,但是src中安装的cmake是在/usr/local/bin中,所以 ...
- 如何在Linux上编译c++文件
1. 打开Linux客户端,新建一个c++文件 2. 写如下代码,退出保存 3.对.cpp文件进行编译并输出结果.
- static class 静态类(Java)
一般情况下是不可以用static修饰类的.如果一定要用static修饰类的话,通常static修饰的是匿名内部类. 在一个类中创建另外一个类,叫做成员内部类.这个成员内部类可以静态的(利用static ...
- fastDFS 安装 配置 使用
fastDFS 安装 配置 使用 关于安装 本文采用的是源码的安装方式,其他安装方式请自行百度 简单介绍 1.背景 FastDFS是一款开源的.分布式文件系统(Distributed File Sys ...
- DEV中svg图标的使用
0.开始之前 先看看使用效果 在操作栏的使用: 在菜单中的使用 1.简述SVG图标 中文名:可缩放矢量图形 外文名:Scalable Vector Graphics 外语缩写:SVG 开发商:万维网联 ...
- ACM 数塔
在讲述DP算法的时候,一个经典的例子就是数塔问题,它是这样描述的: 有如下所示的数塔,要求从顶层走到底层,若每一步只能走到相邻的结点,则经过的结点的数字之和最大是多少? 已经告诉你了,这是个DP的题 ...
- Docker端口映射实现
默认情况下,容器可以主动访问到外部网络的连接,但是外部网络无法访问到容器. 容器访问外部实现 容器所有到外部网络的连接,源地址都会被NAT成本地系统的IP地址.这是使用 iptables 的源地址伪装 ...
- Python安装与使用的常见问题
1. Python安装问题 到Python官网下载Python最新版本 Windows x86-64 executable installer (64为操作系统选择这个) Windows x86 ex ...
- Linux系统网络性能实例分析
由于TCP/IP是使用最普遍的Internet协议,下面只集中讨论TCP/IP 栈和以太网(Ethernet).术语 LinuxTCP/IP栈和 Linux网络栈可互换使用,因为 TCP/IP栈是 L ...
- android 原生camera——设置模块修改
, 此篇博客是记一次客户需求修改,从上周五到现在正好一周时间,期间的各种酸爽,就不说了,还是来看大家关注的技术问题吧. 首先看下以前效果和修改后的效果: 修改前:修改后: 不知道有没有看明白,我在简单 ...