`
jzinfo
  • 浏览: 116500 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

java高效编程读书笔记- 基本类型优先于包装类型

阅读更多

java的类型分两部分,基本类型和引用类型。并且,每个基本类型都对应了一个引用的类型,称为装箱基本类型。

如Integer 对应int,Double对应的double.

 

两者的主要区别有三:

  1. 基本类型只有值,而装箱类型则有与他们的值不同的同一性,也就是两个装箱类型可以具有相同的值,有不同的同一性(不同的引用)
  2. 基本类型只有功能完备的值,而每个装箱类型除了它对应基本类型的所有功能值外,还有个非功能的值--null
  3. 基本类型通常比装箱类型更节省时间和空间。

首先看装箱类型的同一性,自己写的一个比较函数代码如下:

// 比较器
  public int myCompare(Integer first, Integer second) {

         return first < second? -1 : (first==second ? 0 : 1);
	}

 

该函数用来表示Integer值的递增数字顺序。若第一个参数是小于,等于 或者大于它的第二个参数,则该方法返回负数,0或者正数.

 

但是该函数并不能正常的工作,当你调用 myCompare(new Integer(44), new Integer(44)),时,函数返回1.

但我们期待的是0。

原因是进行first<second比较时,系统自动对两个Integer对象被进行了自动拆箱,提取了基本类型的值,经过比较44<44不成立,则进行first==second的比较,这时系统进行的是同一性的比较,也就是比较两个包装类的引用,很明显不是同一个引用,所以函数返回1.

结论:对包装类用==操作符几乎总是错误的.

修改的方法是 新增加两个局部的值类型变量来替换。

	public int myCompare(Integer first, Integer second) {

		// 使用两个基本类型来转化,避免进行对象的同一性比较
	/*	int f = first;
		int s = second;
		return f < s ? -1 : (f == s ? 0 : 1);*/

		 return first < second? -1 : (first==second ? 0 : 1);
	}

 

再看下面的代码:

		Integer i1 = 100;  //自动装箱
		Integer i2 = 100;
		int j = 100;
		System.out.println(i1 == i2); 		        
                                System.out.println(i1 == j); 
		
                                Integer i3 = 128; //自动装箱
		Integer i4 = 128;
		int k = 128;
		System.out.println(i3 == i4); 
		System.out.println(i4 == k); 

 

以上代码分别输出结果是什么?

输出的结果是 true,ture,false,true

对于i1和i2的结果,我们很清楚明白,但是对于i3==i4的比较,为什么为false?

 

当将一个int值赋值给它的一个Integer包装类型变量时,Integer类型调用了valueOf方法:

    public static Integer valueOf(int i) {
	final int offset = 128;
	if (i >= -128 && i <= 127) { // must cache 
	    return IntegerCache.cache[i + offset];
	}
        return new Integer(i);

 

如果这个值在-128和127之间,则将该值进行了缓存处理,在内存中都是指向的一个包装类型对象.

 

也就是

Integer i1=100;

Integer i2=100;

Integer i3=100;

Integer i4=100;

...

Integer i100=100;

 

这些所有的Integer对象都是指向同一个对象地址空间的。

 

但是超过了这个区间,则分别创建的是不同的Integer对象.

查看IntegerCache中引用cache这个变量的部分:

private IntegerCache(){}

	static final Integer cache[] = new Integer[-(-128) + 127 + 1];

	static {
	    for(int i = 0; i < cache.length; i++)
		cache[i] = new Integer(i - 128);
	}

 

由于cache[]在IntegerCache类中是静态数组,也就是只需要初始化一次,即static{......}部分,所以,如果Integer对象初始化时是-128~127的范围,就不需要再重新定义申请空间,都是同一个对象---在IntegerCache.cache中,这样可以在一定程度上提高效率。

 

看另外的个例子:

	static Integer i;

	public void unbelieve() {
		if (i == 42) { // 这里将抛出空指向异常 因为自动装箱和拆箱的缘故,建议修改i的定义为int 或者和new
			// Integer(42)包装类型来比较
			System.out.println("不敢相信");
		}

 

这里不会输出"不敢相信",系统会报告NullPointerException异常。因为i被初始化为null,使用(i==42)时,因为i是Integer 类型,当包装类型和基本类型进行比较时,包装类型则会被自动拆箱,但i是一null,null对象引用被自动拆箱,则会得到一个NullPointerException异常。

修改的方法是将i定义为int或者将其和包装类进行比较,但同样要注意上面提到的-128~127这个区间的问题

 

另外一个关于性能的问题,看如下代码:

public static void main(String args[]){
    Long sum=0L;
    for(long i=0;i<Integer.MAX_VALUE;i++){
        sum=+i;       
    }
    System.out.println(sum);
}

这个程序中的的局部变量 sum 被声明为装箱类型Long,不是基本类型long,虽然编译和运行没有任何错误。但明显的,其在运行中被反反复复的装箱和拆箱,严重影响了性能。

 

 

 

 

分享到:
评论

相关推荐

    达内Java培训-CoreJava全程笔记(WORD唐亮版)

    CoreJava DAY02 数据类型和控制结构 6 CoreJava DAY03 数组 11 CoreJava DAY04 15 CoreJava DAY05 面向对象 17 CoreJava DAY06 类的加载过程、实例化、继承、多态 20 CoreJava DAY07修饰符 26 CoreJava DAY08 常用类...

    Java基础笔记知识点.rar

    JavaSE 之前整理的笔记,一共16章:1.Java概述,2.基本数据类型与运算符,3.流程控制与数组,4.面向对象1(类和对象 方法 构造方法),5. 面向对象2(成员变量与局部变量 常用系统类 包 访问控制符 String),6.面向对象3...

    Java学习笔记-个人整理的

    {1.5}基本类型变量的初始值}{26}{section.1.5} {1.6}数据类型转换}{26}{section.1.6} {1.7}方法}{26}{section.1.7} {1.8}运算符}{27}{section.1.8} {1.8.1}自增运算}{28}{subsection.1.8.1} {1.8.1.1}...

    Java优化编程(第2版)

    1.11 java编程实践 1.11.1 访问实例与类中变量的规则 1.11.2 引用类中的静态变量与方法的 …… 小结 第4章 java核心类与性能优化 4.1 散列表类与性能优化 4.1.1 线程同步散列表类 4.1.2 设置arraylist初始化容量 ...

    java笔试题算法-Thinking-in-Java:《ThinkingInjava》-Note《Java编程思想》笔记作者:[美]Bruce

    《Java编程思想》笔记 看了两个月,书中有穿插着一些设计模式应用到实际的例子中。这本书不会一味地讲语法,更多的是会讲一些Java的设计思想,比如他不会一开始就教你怎么用泛型,而是先介绍为什么会出现泛型,没有...

    Java开发详解.zip

    010301_【第3章:Java基础程序设计】_Java数据类型笔记.pdf 010302_【第3章:Java基础程序设计】_运算符、表达式与语句笔记.pdf 010303_【第3章:Java基础程序设计】_判断与循环语句笔记.pdf 010401_【第4章:数组与...

    CoreJava笔记

    CoreJava笔记 CoreJava DAY01 Java概述 1 CoreJava DAY02 数据类型和控制结构 6 CoreJava DAY03 数组 11 CoreJava DAY04 15 CoreJava DAY05 面向对象 17 CoreJava DAY06 类的加载过程、实例化、继承、多态 20 Core...

    Java基础最全笔记文档

    Java基础笔记分为 Java基础篇 和 Java加强篇 Java基础篇包括: 1. Java环境搭建、Java快速入门、IDEA开发工具 2. Java基础语法、类型转换、运算符、Scanner 3. 分支结构、循环结构、随机数 4. 数组详解、Debug工具...

    达内 CoreJava老师笔记汇总

    CoreJava DAY02 数据类型和控制结构 10 CoreJava DAY03 数组 20 CoreJava DAY04 27 CoreJava DAY05 面向对象 31 CoreJava DAY06 类的加载过程、实例化、继承、多态 37 CoreJava DAY07修饰符 50 CoreJava DAY08 常用...

    java内部学习笔记.docx

    Java技术基础 4 1.1编程语言 4 1.2 Java的特点 4 1.3 Java开发环境 4 1.4 Java开发环境配置 5 1.5 Linux命令与相关知识 5 1.6 Eclipse/Myeclipse程序结构 6 Java语言基础 7 2.1基础语言要素 7 2.2八种基本数据类型 7...

    c#学习笔记.txt

    c#学习笔记(1) 51099在线学习网发布 文章来源:网络收集 发布时间:2006-05-25 字体: [大 中 小] 51099在线学习网 http://www.51099.com 1, 结构(struct) 与 类(class) [attributes] [modifiers] struct ...

    java8源码-note:笔记

    包装类型 1.4 关于JVM 1.5 泛型 1.6 锁 1.7 浮点数 1.8 ArrayList.toArray() 1.9 String 1.10 HTTP 1.11 HashMap 2.进阶 2.1 关于Java8 stream的使用 2.2 关于读写分离遇到的问题 2.3 对象引用类型 2.4 ThreadLocal...

    Articles:文档和源代码。 关于如何开始学习算法和csharp。 如果您具有CC ++或其他编程语言知识,则很容易理解-C language program source code

    06-- 算法#06--基本数据类型和包装 07-- 算法#07-- (链表实现) 08-- 算法的#08--深入详解并查集union-find算法 09-- 算法#09--用简单的思维理解选择,插入,冒泡和希尔排序 10-- 算法#10--用简单的思维理解...

    mybatis学习笔记

    4.1.4 传递pojo包装对象 31 4.1.5 传递hashmap 32 4.2 resultType(输出类型) 33 4.2.1 输出简单类型 33 4.2.2 输出pojo对象 34 4.2.3 输出pojo列表 34 4.2.4 resultType总结: 35 4.2.5 输出hashmap 35 4.3 ...

Global site tag (gtag.js) - Google Analytics