最近闲来无聊打算做一个博客网,没事记记笔记什么,可是网站不好做,需要点时间,就先写写笔记来练练手。
可是要写什么呢,太难的好像我也写不出来,万一写错了误导别人就不好了。
哈哈,不多说,直奔主题,要是写的不好,大家可以提出来。
java有八种基本数据类型分别是,**char、shoat、int、float、double、long、byte、boolean。**
    而它们对应的包装类也有**,Character、Shoat、Integer、Float、Double、Long、Byte、Boolean。**
那么他们之间有什么区别呢,简单来说他们是完全不同的概念,前者的java提供的基本数据类型,注意这里说了是**基本数据类型**;而后者则是java为它们提供常见处理的**工具类**,注意说了是类也就是它们存在着对象。
 
 1. 初始化
这里以int和Integer为例举例说明,当我们初始化一个int和一个Integer并没有给定他们值时,前者默认值为0,而后者默认为null(空对象)。
当我们需要传入一个参数时,对int、Integer的选择就很重要,如果我们传入的Intger为null很有可能抛出一个空指针异常使我们的程序蹦掉;而选择int时因为有初始值,不会出现Intger出现的问题,但是另一个问题也接踵而来,
我们不知道传入的int值的多少,很有可能就会给我们的程序埋了一个影藏的bug;对于int还是Integer的选择我们应该通过现实场景进行选择。
这里重点说一下,当我们使用MVC模式开发时,Controller接收参数如果参数不存在,而参数是int类型时就会抛出一个参数不存在异常,而Integer却不会,只是得到的参数为null。
 
 
2)自动拆箱,自动装箱机制
自动拆箱和自动装箱机制是在JDK1.5引进的一个新机制,观察下面的代码,为什么会有这样的结果产生呢。
 Integer a = 34;
int b = 34;
Integer c = b;
int d = a;
System.out.println( a == b);
System.out.println( d == c);
基本数据类型的和其包装类的相互转换,这是为什么呢?
答案很简单,因为我们在执行Integer a = 34; 代码时jdk默认执行的是

Integer a = Integer.valueOf(34);

  

而我们在执行int d = a;时编译执行的却是

int d = a.intValue();

  

你可能会有疑问,为什么会是这样?
这个时候我们就需要打开源码进行查看寻找答案。
 /**
* Returns an {@code Integer} instance representing the specified
* {@code int} value. If a new {@code Integer} instance is not
* required, this method should generally be used in preference to
* the constructor {@link #Integer(int)}, as this method is likely
* to yield significantly better space and time performance by
* caching frequently requested values.
*
* This method will always cache values in the range -128 to 127,
* inclusive, and may cache other values outside of this range.
*
* @param i an {@code int} value.
* @return an {@code Integer} instance representing {@code i}.
* @since 1.5
*/
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
文档是这样说的,返回一个制定int数值的Integer对象实例,这样好像还不足以说明什么,那我们要如何证明我们是对的呢?
我们可以查看他的编译文件,一切就真相大白了(javac命令)。
 public static void main(String[] var0) {
new User();
Integer var2 = Integer.valueOf(34);
byte var3 = 34;
Integer var4 = Integer.valueOf(var3);
int var5 = var2.intValue();
System.out.println(var2.intValue() == var3);
System.out.println(var5 == var4.intValue());
}
这好像就不需要我在多说什么了。
细心的小伙伴会看到文档里面有这么一句话 * This method will always cache values in the range -128 to 127,
 * inclusive, and may cache other values outside of this range.该方法会缓存-128到127之间的值,这句话又是什么意思呢。
 
 Integer a = 120;
Integer b = 120;
Integer c = 300;
Integer d = 300;
System.out.println( a == b);
System.out.println( d == c);
这两句代码会输出社么呢,小伙伴们肯定说都是true啊,或者说都是false。会这样说的小伙伴不能说你错了,只能说你对了一半;是这样的啊,我们知道==运算符进行运算时,运算符两边如果都为基本数据类型的话那就直接对数值进行比较;但是如果两边或者一边为非基本数据类型时,即对象实例,则比较的是他们的内存地址(如果为空对象的话则为null),这里很明显两边都是对象实例,所以比较的是内存地址。
额?为什么是这样呢,按我们之前讲得理论不是应该都为false才对嘛,因为他们比较的是内存地址呀。哈哈,这就是我们之前讲到的问题,Integer会缓存-128到127之间的数值,而这么数值当然是缓存在一个对象实例里面啦,当我们需要使用时又进行取出(准确点来说是拿到的是它的引用),而不在这个范围内的数值当然都是重新创建实例啦,有兴趣的小伙伴可以进去看下源码。
3) 类型转换
这是包装类很大的存在原因,试想一下,我们有一个数值传递过来时是String或者说是Object类型,我们要怎么转换成int类型呢?
Integer的ValueOf可以将一个String类型转换成int。
使用强制类型转换编译器会报类型转换异常(String类型无法转换成Integert类型),使用valueof方法则可以通过编译,运行结果也是正确的;那么在试想一下,如果是 String a = "120.0";那会是怎么样的结果呢。
抛出一个异常,不能输入字符串为“120.0”,a是浮点类型的,那怎么办,总会有解决方法的。
哎呦,好像行不通,Float精度比Integer高,嗯!强转?
也不行,好像很绝望。
Integer b = Float.valueOf(a).intValue();
好像行了,测试一下。
还真行,什么情况,这个intValue又是个什么方法。
 /**
* Returns the value of this {@code Float} as an {@code int} after
* a narrowing primitive conversion.
*
* @return the {@code float} value represented by this object
* converted to type {@code int}
* @jls 5.1.3 Narrowing Primitive Conversions
*/
public int intValue() {
return (int)value;
}
什么,居然是个强转,搞了半天还是强转,那为啥我们那样转不行呢,因为我们是类强转,而它是类型转换。
挖槽还真可以,说明这就没错了。
4)内存使用
这次那long类型来举例,因为这样举例会比较明显,我们知道long类型是占8个字节(占用跟系统有关),而Long包装类呢,却是一个对象。
 Long start = System.currentTimeMillis();
Long l = 0L;
for (Integer i = 0; i < Integer.MAX_VALUE; i++){
l++;
}
System.out.println(System.currentTimeMillis() - start);
这段代码会执行多久呢,好像是一瞬间的事,可是他执行了13060ms,可能这关系到机器,但是这个问题是很严重的,如果不小心写了这样的代码,搞蹦一个程序是很简单的事情。
这里每次执行l++操作其实都相当于创建了一个新的实例,那这个量就非常大了,而如果换成基本数据类型的话,从始至终它都是8个字节
我们修改一下程序
 Long start = System.currentTimeMillis();
long l = 0L;
for (int i = 0; i < Integer.MAX_VALUE; i++){
l++;
}
System.out.println(System.currentTimeMillis() - start);
那么它的运行时间又是多少呢?78ms
是不是很惊讶,相差了好几百倍,所以我们绝对不可以出现这样的代码,对于基本数据类型还是包装类的选择,我们首选还是基本数据类型,而当某些场景无法继续使用基本数据类型时,我们才使用包装类进行处理。
OK,到此为止,基本数据类型跟包装类之间的关系和区别我就讲完了,如果有讲的不好或者是讲得不对的地方大家一定要指出来,不然我就没法进步了。
到时候博客开通了,还需要各位老少爷们捧场哈。
作者: 小丑鱼yang 
链接:http://www.imooc.com/article/17521
来源:慕课网

Java探秘之基本数据类型和包装类(int,Integer)(一)的更多相关文章

  1. Java面向对象 String 基本数据类型对象包装类

      Java面向对象  String 知识概要:              (1)String的用法详解 (2)基本数据类型对象包装类 String          顾名思义,该类主要是对字符串 ...

  2. 面试题:基础数据类型 包装类 int Integer

    因为在学习集合时知道集合里存放的对象都是Object类型,取出的时候需要强制类型转换为目标类型(使用泛型集合不需要),如int a = (Integer)arrayList.get(0):然后我们就会 ...

  3. Java Number类(数据类型的包装类)

    Java Number 一般地,当需要使用数字的时候,我们通常使用内置数据类型,如:byte.int.long.double等. 例如: int i = 5000; float gpa = 13.65 ...

  4. Java基础【基本数据类型包装类、int与String 之间的相互转换】

    为什么会有基本类型包装类? 将基本类型数据类型封装成对象,这样的好处可以在对象中定义更多方法操作该数据. 包装类常用的操作就是用于基本数据类型与字符串之间的转换 问题:int a=100; 为什么不能 ...

  5. Java基础(34):Java中基本数据类型的包装类(主要为了不同数据类型之间更方便的进行转换)(Wrapper类)

    相信各位小伙伴们对基本数据类型都非常熟悉,例如 int.float.double.boolean.char 等.基本数据类型是不具备对象的特性的,比如基本类型不能调用方法.功能简单...,为了让基本数 ...

  6. 黑马程序员——JAVA基础之基本数据类型包装类和1.5JDK新特性装箱

    ------- android培训.java培训.期待与您交流! ---------- 基本数据类型包装类: byte Byte short Short int Integer char Charac ...

  7. Java中基本数据类型和包装类

    参考:深入剖析Java中的装箱和拆箱; Java中基本数据类型和包装类互转中 缓冲机制的使用; java学习笔记:装箱和拆箱,包装器和缓冲池 Java 各 类型数据在内存中分配情况详解 一 java内 ...

  8. java基本数据类型及其包装类

    1.String类 String s1 = "hello world"; String s2 = "hello world"; String s3 = s1 + ...

  9. Java基础-数据类型和包装类

    数据类型 分为基本数据类型和引用数据类型 基本数据类型变量存储的就是数据本身,引用数据类型的变量是保存数据的空间地址 四种基本数据类型: 逻辑型 boolean 文本型 char 整数型 byte s ...

随机推荐

  1. [原创]LAMP+phpmyadmin+FTP环境搭建

    ***简单ftp服务器搭建: rpm –qa|grep vsftpd   //检查是否安装服务 yum –y install vsftpd-*   //安装服务 mkdir /var/ftp/uplo ...

  2. Hibernate与Jpa的关系(2)

    [转自:http://blog.163.com/hero_213/blog/static/398912142010312024809/ ] 近年来ORM(Object-Relational Mappi ...

  3. Docker 镜像小结 - 每天5分钟玩转 Docker 容器技术(21)

    本节我们对 Docker 镜像做个小结. 这一部分我们首先讨论了镜像的分层结构,然后学习了如何构建镜像,最后实践使用 Docker Hub 和本地 registry. 下面是镜像的常用操作子命令: i ...

  4. ubuntu16.04 开发环境搭建

    1.更换源 sudo gedit /etc/apt/sources.list 2.更新系统 sudo apt-get update sudo apt-get dist-upgrade     3.移动 ...

  5. 机器学习:保序回归(IsotonicRegression):一种可以使资源利用率最大化的算法

    1.数学定义 保序回归是回归算法的一种,基本思想是:给定一个有限的实数集合,训练一个模型来最小化下列方程: 并且满足下列约束条件: 2.算法过程说明 从该序列的首元素往后观察,一旦出现乱序现象停止该轮 ...

  6. elememtui(有关权限的那些事)

    前言:关于权限路由的那些事儿…… 业务情景描述:现有一个后台管理系统,共存在三种类型的人员,①超级管理员(称作1):②组别管理员(2):③普通用户(3):每种类型的人看到的操作栏并不一样,可以进行的操 ...

  7. javascript基础(幼兔、小兔成兔数量等典型例题)

    一张纸的厚度是0.0001米,将纸对折,对折多少次厚度超过珠峰高度8848米var sum=0; var a=0.0001 for(var i=0;i<100;i++){ a=a*2; sum= ...

  8. js数组及数组应用(冒泡和二分,遍历输出)

    一.定义:1)var arr=new Array(); 加数据:arr[0]=1; 2)定义同时赋值:var arr=new Array(1,2,3,4,5); 3)调用:var arr=new Ar ...

  9. [转] .NET领域驱动设计—初尝(疑问、模式、原则、工具、过程、框架、实践)

    阅读目录: 1.1.疑问 1.1.1.UML何用 1.1.2.领域建模 1.2.模式 1.3.原则 1.5.过程 1.6.框架 1.7.项目演示 最近在研究DDD颇有收获,所以整理出来跟大家分享,共同 ...

  10. JavaScript 基础——使用js的三种方式,js中的变量,js中的输出语句,js中的运算符;js中的分支结构

    JavaScript 1.是什么:基于浏览器 基于(面向)对象 事件驱动 脚本语言 2.作用:表单验证,减轻服务器压力 添加野面动画效果 动态更改页面内容 Ajax网络请求 () 3.组成部分:ECM ...