转自:http://blog.csdn.net/lanxuezaipiao/article/details/41985243

收集了几个易错的或好玩的Java输出题,分享给大家,以后在编程学习中稍微注意下就OK了。

1. 看不见的空格?

下面的输出会正常吗?

  1. package basic;
  2. public class IntegerTest {
  3. public static void main(String[] args) {
  4. System.out.println(Integer.parseInt("1"));
  5. System.out.println(Integer.parseInt("2"));
  6. }
  7. }

解析:将上面代码复制下(不要自己手敲)在自己的环境里运行看看,是不是输出下面错误来了:

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中打开后你会发现是下面这样的语句:

  1. System.out.println(Integer.parseInt("<feff>2"));

Unicode规范中定义,每一个文件的最前面分别加入一个表示编码顺序的字符,这个字符的名字叫做”零宽度非换行空格“(ZEROWIDTHNO-BREAKSPACE),用FEFF表示。这正好是两个字节,而且FF比FE大1。因此下面的语句会输出65279,刚好是FEFF

  1. System.out.println((int)"2".charAt(0));

2. 类静态成员初始化

下面的程序能编译通过么?如果通过,说结果并解释,不能编译,说错误原因。

  1. class A
  2. {
  3. public static int X;
  4. static { X = B.Y + 1;}
  5. }
  6. public class B
  7. {
  8. public static int Y = A.X + 1;
  9. static {}
  10. public static void main(String[] args) {
  11. System.out.println("X = "+A.X+", Y = "+B.Y);
  12. }
  13. }

解析:这个程序能正确运行,类的运行过程如下:

首先加载主类B,初始化静态成员Y,发现需要类A的信息,于是加载类A,初始化静态成员X,也用到B类信息,由于此时B类的Y还未成功加载因此这里是默认值0,从而得到A类的X为1,然后返回到B类,得到Y为2。

3. 装箱拆箱的实际过程

关于自动装箱,相信大部分人都明白是怎么一回事,但真的完全明白了嘛?

先看下面的代码:

  1. Short s1 = 1;
  2. Short s2 = s1;
  3. System.out.println(s1 == s2);

谁都知道当然打印true了。现在加一句试试:

  1. Short s1 = 1;
  2. Short s2 = s1;
  3. s1++;
  4. System.out.println(s1 == s2);

还是true吗?No,这次输出成了false。WHY?难道s1和s2引用的不是同一个对象吗?有这些疑问的说明你对自动装箱拆箱的过程还不是非常清楚,实际上上面的代码可以翻译为下面的代码(实际执行过程,要掌握):

  1. Short s1 = new Short((short)1);
  2. Short s2 = s1;
  3. short tempS1 = s1.shortValue();
  4. tempS1++;
  5. s1 = new Short(tempS1);
  6. System.out.println(s1 == s2);

哦,原来如此,这下明白了,因此我们在使用自动装箱的时候小心点为妙。

4. 你自以为是的异常

先来两句代码:

  1. NullTest myNullTest = null;
  2. System.out.println(myNullTest.getInt());

相信很多人看到这段代码时,都会自以为是的说:NullPointerException。果真如此吗?你还没看到NullTest
这个类是如何定义的呢。现在看看这个类的定义:

  1. class NullTest {
  2. public static int getInt() {
  3. return 1;
  4. }
  5. }

由于getInt()是静态方法,他只和类相关,和具体的对象无关,类完成加载时,即可通过类名.getInt()进行调用,因此这里就算对象实例为NULL也会正常输出1.

记住:类变量和类方法的使用,仅仅依赖引用的类型。即使引用为null,仍然可以调用。从良好实践的角度来看,明智的做法是使用NullTest.getInt()来代替myNullTest.getInt(),但谁不不能保证不会碰到这样的代码,因此还是小心为妙。

5. 变长参数和数组,如何变通?

变长参数特性带来了一个强大的概念,可以帮助开发者简化代码。不过变长参数的背后是什么呢?Basically,就是一个数组。

  1. public void calc(int... myInts) {}
  2. calc(1, 2, 3);

编译器会将前面的代码翻译成类似这样:

  1. int[] ints = {1, 2, 3};
  2. calc(ints);

不过这里有两点需要注意:

  • 当心空调用语句,这相当于传递了一个null作为参数。

    calc();

    等价于

    int[] ints = null;

    calc(ints);
  • 当然,下面的代码会导致编译错误,因为两条语句是等价的:

    public void m1(int[] myInts) { ... }

    public void m1(int... myInts) { ... }

参考资料

Java五道输出易错题解析(进来挑战下)的更多相关文章

  1. Java五道输出易错题解析(避免小错误)

    收集了几个易错的或好玩的Java输出题,分享给大家,以后在编程学习中稍微注意下就OK了. 1. 看不见的空格? 下面的输出会正常吗? package basic; public class Integ ...

  2. 【笔试题】Java 易错题精选

    笔试题 Java 易错题精选 1.写出下列程序的运行结果( )String 不变性Java 值传递 public class Test { public static void main(String ...

  3. 10道C++输出易错笔试题收集

    下面这些题目都是我之前准备笔试面试过程中积累的,大部分都是知名公司的笔试题,C++基础薄弱的很容易栽进去.我从中选了10道简单的题,C++初学者可以进来挑战下,C++大牛也可以作为娱乐玩下(比如下面的 ...

  4. 杭电OJ2039——三角形(c++)(易错题:数据类型不确定)

    三角形 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submis ...

  5. hibernate错题解析

    01 Hibernate错题分析   解析: 此题目考查的是对Hibernate中交叉连接的理解.HQL支持SQL风格的交叉连接查询,交叉连接适用于两个类之间没有定义任何关联时.在where字句中,通 ...

  6. JAVA程序改错 (易错题)

    JAVA程序改错 1. abstract class Name { private String name; public abstract boolean isStupidName(String n ...

  7. java考试易错题大全

    常见的Java问题 1.什么是Java虚拟机?为什么Java被称作是"平台无关的编程语言"? Java虚拟机是一个可以执行Java字节码的虚拟机进程.Java源文件被编译成能被Ja ...

  8. Java易错题(1)

    检查程序,是否存在问题,如果存在指出问题所在,如果不存在,说明输出结果. public class HelloB extends HelloA { public HelloB() { } { Syst ...

  9. java易错题----静态方法的调用

    class A{ public static String s="A.s"; } class B extends A{ public static String s="B ...

随机推荐

  1. windows server 2008 R2 禁用ipv6和隧道适配器

    在windows server 2008 R2操作系统下部署weblogic web application,部署完成后进行测试,发现测试页的地址使用的是隧道适配器的地址,而不是静态的ip地址,而且所 ...

  2. js 当前时间刷新

    <p>每隔1秒钟,打印当前时间</p> <div id="time"></div> <script> function ...

  3. SCNN车道线检测--(SCNN)Spatial As Deep: Spatial CNN for Traffic Scene Understanding(论文解读)

    Spatial As Deep: Spatial CNN for Traffic Scene Understanding 收录:AAAI2018 (AAAI Conference on Artific ...

  4. c# datatable增加列并赋值

    DataView dv = DataObj.GetBmfzr("03").Tables[0].DefaultView; dv.Sort = "bmbh"; Da ...

  5. 原生js移动端列表无缝间歇向上滚动

    在项目开发中尤其是在项目的活动页面的开发中,经常需要将用户的购买信息或中奖信息等以列表的形式展示在页面当中,并可以使其自动间歇向上滚动来达到在有限的区域内展示所有信息的目的.通常的做法是通过将列表父元 ...

  6. Redis学习汇总

    [Redis教程目录] 1.redis是什么 2.redis的作者何许人也 3.谁在使用redis 4.学会安装redis 5.学会启动redis 6.使用redis客户端 7.redis数据结构 – ...

  7. 反射获取 Class

    原文链接:https://www.codemore.top/cates/Backend/post/2018-04-26/reflect-class 类 Java中每个类型要么是引用类型,要么是原生类型 ...

  8. 通过内核修改centos密码

    在开机启动的时候按键盘上的"E"键会进入如下界面. 选择相应的内核,再次按"E",出现下图,选择第二项,再次按"E"键 经过第二步,这个画面 ...

  9. PHP date() 函数

    实例 格式化本地日期和时间,并返回格式化的日期字符串: <?php // Prints the dayecho date("l") . "<br>&qu ...

  10. RDO Stack: Install newton in the dashboard can't create images

    Issue: When you want to create an image in RDO stack newton version, you may encounter following err ...