`

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

相关推荐

    01-java基础-基本数据类型.docx

    选择数据类型时,应根据实际需求,如处理数字优先考虑int和double,二进制操作使用byte,处理中文字符使用char,描述内存大小或主键列则可使用long。 整型数据是数值型的基本数据类型之一,Java提供了四种整型:...

    java中long类型转换为int类型

    在Java编程语言中,数据类型转换是常见的操作,特别是在处理...如果可能,应优先选择不涉及溢出风险的方案,或者在转换前进行溢出检查。对于向上转换,如`int`到`long`,则无需担心溢出问题,可以安全地进行隐式转换。

    Java中的自动装箱与拆箱:深入理解基本数据类型与对象的转换

    - 当不需要使用对象的方法时,优先选择基本数据类型。 - 对于频繁操作的数据结构,考虑使用原始数组而非列表或集合。 - 在适当的情况下,避免不必要的装箱和拆箱操作,尤其是在性能敏感的部分。 总之,自动装箱和...

    JAVA试题及答案(50道选择题)-java选择题及答案.docx

    String是对象类型,char是基本数据类型,而用户自定义的类类型也是引用类型。 16. 对象的特征在类中表示为变量,称为类的( B ) - 正确答案是 B,属性。在面向对象编程中,类的属性代表对象的状态。 17. 在java...

    JAVA试题及答案50道选择题-java选择题及答案.doc

    其中,JAVA2 SE 是标准版,提供了基本的功能和 API。 2. main 方法 JAVA 程序的 main 方法是程序的入口点,必须写在类里面。JAVA 程序可以有多个 main 方法,但只能有一个入口点。main 方法中可以有多条语句,但...

    Java编程中影响性能的细节

    6. **选择合适的包装类型和基本类型**:包装类型适用于需要对象的场景,如集合类。而在其他情况下,使用基本类型可以减少不必要的对象创建,提高性能。 7. **谨慎使用synchronized**:同步操作会带来性能开销,可能...

    广度优先搜索学习五例之二(JAVA)

    虽然描述中没有具体的信息,但我们可以从提供的博文链接推测,作者可能在博客中详细解释了如何用Java编写一个BFS算法,并可能通过具体的例子展示了BFS如何处理不同类型的图问题。通常,这样的教程会包括代码实现、...

    农行,笔试题,java,c

    2. 结构化程序设计:顺序、选择、循环三种基本结构。 3. Linux 命令:umask 002 的文件权限为 rw-rw-r--。 二、Java 编程 4. 指令组成:操作码和操作数。 5. 自顶向下集成:按照软件的控制层次结构,分为深度优先...

    Java面试题基本知识点总结(1)

    - **可抛出的四种类型**:根据题目给出的选择题,Java中可以通过`throws`关键字抛出以下几种类型的对象:`Exception`、`Error`、`Throwable`。其中`Error`和`RuntimeException`及子类是未检查的异常,其他`Exception...

    JAVA提速_fox

    6. **包装类型与基本类型的使用**:在需要对象特性的场景下使用包装类型,其他情况优先选择基本类型,因为基本类型在栈中处理,速度更快。 7. **谨慎使用synchronized**:同步操作会带来性能开销,应尽量减小同步...

    实用JAVA教程:基于BLUEJ的对象优先方法 第三版

    - 数据类型:涵盖基本数据类型,如整型、浮点型、字符型和布尔型,以及引用类型。 - 流程控制:包括条件语句(if-else)、循环(for、while)和选择结构(switch)。 - 异常处理:讲解如何使用try-catch-finally...

    HDU题目java实现

    7. **排序与搜索**:包括冒泡排序、选择排序、插入排序、快速排序、归并排序等基本排序算法,以及线性搜索、二分搜索等查找算法。 8. **图论与树**:HDU题目中可能涉及图的遍历(深度优先搜索DFS、广度优先搜索BFS...

    Java性能优化的45个细节.pdf

    以下是关于Java性能优化的详细知识点,内容包括单例模式的合理应用、静态变量的使用考量、对象创建与垃圾回收策略、final修饰符与内联优化、局部变量与实例变量的性能差异、包装类型与基本类型的内存影响、同步机制...

    java开发性能优化

    6. **包装类型与基本类型的使用**:根据场景选择使用包装类型或基本类型。包装类型适用于对象操作,基本类型则用于数值计算,避免不必要的自动装箱拆箱。 7. **慎用synchronized**:同步可能导致性能下降,应尽量...

    Java数据结构课件

    在Java中,数组是最基本的数据结构,它允许存储同类型的元素序列。数组提供了直接访问元素的能力,但插入和删除元素的效率较低。链表则通过节点之间的指针链接元素,使得插入和删除操作相对快速,但访问元素的速度较...

    实验05 Java集合.doc

    此外,数组只能存储基本类型和引用类型,而集合只存储对象,但通过自动装箱机制,基本类型也可以在集合中使用。 对于TreeSet实现第一题的问题,可以创建一个TreeSet,然后添加Person对象,由于TreeSet会自动根据...

    java基本的算法代码

    首先,我们来看看Java语言中的基础算法类型。Java是一种面向对象的编程语言,其强大的类库和丰富的数据结构为实现各种算法提供了便利。常见的算法包括排序、搜索、图算法、动态规划、回溯法等。 1. **排序算法**:...

    java笔记

    - **基本类型比较**:使用`==`或`!=`运算符来比较基本类型的值。 #### 九、控制语句 - **break**和**continue**:在循环体内使用`break`可以立即终止循环,而`continue`则跳过当前迭代的剩余部分,继续执行下一次...

    十年大厂Java笔试面试题及答案

    数组是 Java 中的一种基本数据结构,它可以用来存储大量的数据。 在 Java 中,可以使用多维数组来存储数据。多维数组可以用来存储大量的数据,并且可以通过索引来访问数组中的元素。 3. 算法:TOP K 问题 TOP K ...

Global site tag (gtag.js) - Google Analytics