`

java 优先选择基本类型

    博客分类:
  • java
阅读更多

建议29: 优先选择基本类型

包装类型是一个类,它提供了诸如构造方法、类型转换、比较等非常实用的功能,而且在Java 5之后又实现了与基本类型之间的自动转换,这使包装类型如虎添翼,更是应用广泛了,在开发中包装类型已经随处可见,但无论是从安全性、性能方面来说,还是从稳定性方面来说,基本类型都是首选方案。我们来看一段代码:

  1. public class Client {  
  2.      public static void main(String[] args) {  
  3.           Client cilent = new Client();  
  4.           int i=140;  
  5.           //分别传递int类型和Integer类型  
  6.           cilent.f(i);  
  7.           cilent.f(Integer.valueOf(i));  
  8.      }  
  9.      public void f(long a) {  
  10.           System.out.println("基本类型的方法被调用");  
  11.      }  
  12.      public void f(Long a) {  
  13.           System.out.println("包装类型的方法被调用");  
  14.      }  

在上面的程序中首先声明了一个int变量i,然后加宽转变成long型,再调用f()方法,分别传递int和long的基本类型和包装类型,诸位想想该程序是否能够编译?如果能编译输出结果又是什么呢?

首先,这段程序绝对是能够编译的。不过,说不能编译的同学还是很动了一番脑筋的,只是还欠缺点火候,你可能会猜测以下这些地方不能编译:

f()方法重载有问题。定义的两个f()方法实现了重载,一个形参是基本类型,一个形参是包装类型,这类重载很正常。虽然基本类型和包装类型有自动装箱、自动拆箱的功能,但并不影响它们的重载,自动拆箱(装箱)只有在赋值时才会发生,和重载没有关系。

cilent.f(i)报错。i是int类型,传递到fun(long l)是没有任何问题的,编译器会自动把i的类型加宽,并将其转变为long型,这是基本类型的转换规则,也没有任何问题。

cilent.f(Integer.valueOf(i)) 报错。代码中没有f(Integer i)方法,不可能接收一个Integer类型的参数,而且Integer和Long两个包装类型是兄弟关系,不是继承关系,那就是说肯定编译失败了?不,编译是成功的,稍后再解释为什么这里编译成功。

既然编译通过了,我们来看一下输出:

  1. 基本类型的方法被调用  
  2. 基本类型的方法被调用 

 

cilent.f(i)的输出是正常的,我们已经解释过了。那第二个输出就让人很困惑了,为什么会调用f(long a)方法呢?这是因为自动装箱有一个重要的原则:基本类型可以先加宽,再转变成宽类型的包装类型,但不能直接转变成宽类型的包装类型。这句话比较拗口,简单地说就是, int可以加宽转变成long,然后再转变成Long对象,但不能直接转变成包装类型,注意这里指的都是自动转换,不是通过构造函数生成。为了解释这个原则,我们再来看一个例子:

  1. public class Client {  
  2.      public static void main(String[] args) {  
  3.           int i=100;  
  4.           f(i);  
  5.      }  
  6.      public static void f(Long l){  
  7.      }  

 

这段程序编译是通不过的,因为i是一个int类型,不能自动转变为Long型。但是修改成以下代码就可以编译通过了:

  1. public static void main(String[] args) {  
  2.      int i=100;  
  3.      long l = (long)i;  
  4.      f(l);  

这就是int先加宽转变为long型,然后自动转换成Long型。规则说明白了,我们继续来看f(Integer.valueOf(i))是如何调用的,Integer.valueOf(i)返回的是一个Integer对象,这没错,但是Integer和int是可以互相转换的。没有f(Integer i)方法?没关系,编译器会尝试转换成int类型的实参调用,OK,这次成功了,与f(i)相同了,于是乎被加宽转变成long型—结果也很明显了。整个f(Integer.valueOf(i))的执行过程是这样的:

i通过valueOf方法包装成一个Integer对象。

由于没有f(Integer i)方法,编译器“聪明”地把Integer对象转换成int。

int自动拓宽为long,编译结束。

使用包装类型确实有方便的地方,但是也会引起一些不必要的困惑,比如我们这个例子,如果f()的两个重载方法使用的是基本类型,而且实参也是基本类型,就不会产生以上问题,而且程序的可读性更强。自动装箱(拆箱)虽然很方便,但引起的问题也非常严重—我们甚至都不知道执行的是哪个方法。

注意 重申,基本类型优先考虑。

分享到:
评论
1 楼 576017120 2014-01-23  
编写高质量代码:改善Java程序的151个建议 :(在线阅读前三章)
http://book.51cto.com/art/201202/317444.htm

相关推荐

    JAVA基础课程讲义

    基本类型转化时常见错误和问题 33 方法 33 简单的键盘输入和输出 33 本章思考作业 34 上机操作 34 第二章(2) 控制语句 35 顺序结构 35 选择结构 35 if单选择结构 35 if-else双选择结构 35 If-elseif-else多选择结构 ...

    Java Bug模式详解

    Java.Bug模式详解 第1章 混乱环境下的灵活方法 1.1 软件设计、实现和维护的趋势 1.1.1 对于稳定、安全 系统的需求增加 1.1.2 传统软件工程技 术的局限性 1.1.3 开放源代码的软 件项目的可利用性 1.1.4 对于...

    java算法与数据结构

    (2)图的深度优先和广度优先遍历。 (3)无向图的连通性和最小生成树 (4)拓扑排序 (5)关键路径 (6)单源最短路径 5.散列表(哈希表) (1)散列表的概念 (2)散列表解决散列冲突的方法(开放地址法、链地址...

    超爽的自学课件(java)

    <br>(11) 第11章:运行期类型鉴定 若只有指向基础类的一个句柄,Java的运行期类型标鉴定(RTTI)使我们能获知一个对象的准确类型是什么。一般情况下,我们需要有意忽略一个对象的准确类型,让Java的动态绑定...

    数据结构与算法分析Java语言描述(第二版)

    引论1.1 本书讨论的内容1.2 数学知识复习1.2.1 指数1.2.2 对数1.2.3 级数1.2.4 模运算1.2.5 证明的方法1.3 递归简论1.4 实现泛型特性构件pre-Java51.4.1 使用Object表示泛型1.4.2 基本类型的包装1.4.3 使用接口...

    数据结构与算法分析_Java语言描述(第2版)]

    译者序前言第1章 引论1.1 本书讨论的内容1.2 数学知识复习1.2.1 指数1.2.2 对数1.2.3 级数1.2.4 模运算1.2.5 证明的方法1.3 递归简论1.4 实现泛型特性构件pre-Java51.4.1 使用Object表示泛型1.4.2 基本类型的包装...

    Java开发技术大全 电子版

    10.11.1不能使用基本类型326 10.11.2不能使用泛型类异常326 10.11.3不能使用泛型数组327 10.11.4不能实例化参数类型对象..327 10.12本章小结328 第11章集合329 11.1集合接口与抽象类329 11.1.1Collection接口...

    数据结构与算法经典问题解析-Java语言描述

    讲述了基本概念、递归和回溯、链表、栈、队列、树、优先队列和堆、并查集DAT、图算法、排序、查找、选择算法(中位数)、符号表、散列、字符串算法、算法设计技术、贪婪算法、分治算法、动态规划算法、复杂度类型等...

    数据结构与算法分析 Java语言描述第2版

    译者序前言第1章 引论1.1 本书讨论的内容1.2 数学知识复习1.2.1 指数1.2.2 对数1.2.3 级数1.2.4 模运算1.2.5 证明的方法1.3 递归简论1.4 实现泛型特性构件pre-Java51.4.1 使用Object表示泛型1.4.2 基本类型的包装...

    数据结构与算法分析_Java语言描述(第2版)

    1.4.2 基本类型的包装 1.4.3 使用接口类型表示泛型 1.4.4 数组类型的兼容性 1.5 利用Java5泛性实现泛型特性成分 1.5.1 简单的泛型类和接口 1.5.2 自动装箱/拆箱 1.5.3 带有限制的通配符 1.5.4 泛型static方法 ...

    突破程序员基本功的16课.part2

    1.1.3 基本类型数组的初始化 1.1.4 引用类型数组的初始化 1.2 使用数组 1.2.1 数组元素就是变量 1.2.2 没有多维数组 1.3 小结 第2课 对象与内存控制 2.1 实例变量和类变量 2.1.1 实例变量和类变量的属性 ...

    数据结构与算法分析-Java语言描述(第2版)_2_2

    java5 1.4.1 使用object表示泛型 1.4.2 基本类型的包装 1.4.3 使用接口类型表示泛型 1.4.4 数组类型的兼容性 1.5 利用java5泛性实现泛型特性成分 1.5.1 简单的泛型类和接口 1.5.2 自动装箱/拆箱....

    数据结构与算法分析-Java语言描述(第2版)_1_2

    java5 1.4.1 使用object表示泛型 1.4.2 基本类型的包装 1.4.3 使用接口类型表示泛型 1.4.4 数组类型的兼容性 1.5 利用java5泛性实现泛型特性成分 1.5.1 简单的泛型类和接口 1.5.2 自动装箱/拆箱....

    vc++6.0 程序设计学与用教程

    3.7 各类型数据间的优先关系和相互转换 第4章 运算符与表达式 4.1 算术运算符 4.2 关系运算符 4.3 布尔逻辑运算符 4.4 位运算符 4.5 赋值运算符 4.6 字符串运算符 4.7 扩展赋值运算符 4.8 条件运算符 ...

    初级java笔试题-alpr:算法

    基本数据类型、算法和数据结构的介绍。 我们的重点是 Java 实现的应用程序和科学性能分析。 Part I 重点介绍基本data structures 、 sorting和searching 。 主题包括: 联合发现, 二分查找, 堆栈, 排队, 包, ...

    数据结构与算法分析_Java_语言描述

    小结 练习 参考文献 第6章 优先队列(堆) 6.1 模型 6.2 一些简单的实现 6.3 二叉堆 6.3.1 结构性质 6.3.2 堆序性质 6.3.3 基本的堆操作 6.3.4 其他的堆操作 6.4 优先队列的应用 6.4.1 选择问题 6.4.2...

    算法第四版-PDF-网盘链接

     1.1.1 Java程序的基本结构 4  1.1.2 原始数据类型与表达式 6  1.1.3 语句 8  1.1.4 简便记法 9  1.1.5 数组 10  1.1.6 静态方法 12  1.1.7 API 16  1.1.8 字符串 20  1.1.9 输入输出 21...

Global site tag (gtag.js) - Google Analytics