一、基本类型的简介

基本类型的两条准则:

  • Java中,如果对整数不指定类型,默认时int类型,对小数不指定类型,默认是double类型。
  • 基本类型由小到大,可以自动转换,但是由大到小,则需要强制类型转换。

所占的字节数:

byte: 1个字节;
char: 2个字节;
short: 2个字节;
int: 4个字节;
long: 8个字节;
float: 4个字节;(6位小数,指数是:10^-38~10^38; 范围:)
double: 8个字节;

char:Java中用 "\u四位十六进制的数字 (即使在注释中出现\u,后面如果
跟的不是4个16进制的数字,也会报错)"表示将字符转换成对应的unicode编 码;也可以用字符来赋值如: char c="\u0000" ,char的默认初始化值,unicode的null字符

基本类型的后缀:

long : l 或 L
float: f 或 F;
double: d 或 D

二、类型转换

  正如前面所说的,类型由大到小,是必需强制转换。但这并不意味着需要用户手动强制转换 —— 也就是 隐式转换。隐式转换 说的透彻点就是由编译器来进行强制转换,不需要用户再去写强制转换的代码。下面的前两个小点所说的便是特殊的隐式类型转换。

本小节所讨论的类型转换是不包括 类型由小到大的转换,讨论的是其他比较容易让人迷惑的类型转换

1. int类型的字面常量转换成比int类型低的变量类型

  所谓的字面常量就是值的本身,如 5、7、“aa”等等。我们先看个例子:

public static void main(String[] args) {int a = 8;  //8是字面常量byte b = 9;  //9是字面常量char c = 9+5;//常量表达式short s = (short) (c+10); //变量表达式,需要显式强制转换
}

  上面的代码是经过编译的,是正确的。b是byte类型,但b=9不需要显式地手动强制转换,这是因为9是字面常量,是由JVM自动完成。
  我们再来看一下c=9+5,c是char类型,9+5得到结果是int类型,但也不需要显式地手动强制转换。这是因为 9+5是常量表达式,所以在编译期间已经由编译器计算出结果了,即经过编译后,相当于 c=14,也是字面常量,所以可以隐式转换。同理,short s = (short) (c+10); 子所以不能隐式转换,就是因为表达式不是常量表达式,包含了变量,只能在运行期间完成,所以就要手动强制转换。

×××字面常量隐式转换的限制:

  • ×××字面常量的大小超出目标类型所能表示的范围时,要手动强制类型转换。
byte b = 128;//编译错误,128超出byte类型所能表示的范围
byte c = (byte)128;//编译通过
  • 对于传参数时,必须要显式地进行强制类型转换,明确转换的类型

编译器子所以这样要求,其实为了避免 方法重载出现的隐式转换 与 小类型自动转大类型 发生冲突。

public static void main(String[] args) {shortMethod(8);//编译错误shortMethod((short)8); //编译通过longMethod(8);//编译通过,因为这是小类型变成大类型,是不需要强制类型转换的
}public static void shortMethod(short c){System.out.println(c);
}public static void longMethod(short l){System.out.println(l);
}
  • char类型的特殊情况 :下面再细讲

2. 复合运算符的隐式转换

  *复合运算符(+=、-=、=、/=、%=)是可以将右边表达式的类型自动强制转换成左边的类型**

public static void main(String[] args) {int a = 8;  short s = 5; s += a;s += a+5;
}

  s+=a、s+=a+5;的表达式计算结果都是int类型,但都不需要手动强制转换。其实,如果是反编译这段代码的class文件,你会发现s+=a;,其实是被编译器处理成了

s=(short)(s+a)

也就是说对于所有的复合运算的隐式类型转换,其实是编译器自动添加类型转换的代码。

所以,相对于×××字面常量的隐式转换,复合运算符的隐式转换则没有任何限制因为前者只能在编译器期间发生,后者则是编译器实实在在的补全了类型转换的代码。

3. 特殊的char类型

  char类型在基本类中是一个比较特殊的存在。这种特殊性在于char类型是一个无符号类型,所以char类型与其他基本类型不是子集与父集间的关系(其他类型都是有符号的类型)。也就是说,char类型与byte、short之间的转换都需要显式的强制类型转换(小类型自动转换成大类型失败)。

  同时,由于char类型是一个无符号类型,所以对于×××字面常量的隐式转换的限制,不仅包括字面常量数值的大小不能超出2个字节,还包括字面常量数值不能为负数

 byte b = 2;char c = 2;//编译通过c = 100000000000;//编译不通过,超出char类型的范围char d = -2//字面常量为负数,编译不通过d = (char)-100;//编译通过char f = (char)b; //编译通过,必须显式的强制类型转换f = b;//编译不通过,不能隐式转换int  i = c;//编译通过,可以不需要强制类型转换short s = (short) c;//编译通过,必须显式地强制类型转换

  char类型是无符号的类型,这种无符号也体现在在其转换成int类型时,也就是说,char类型在扩展时,也是按无符号的方式扩展,扩展位填0。我们来看一个例子:

public static void main(String[] args) {short s = -5;char c = (char)s; System.out.println(c==s);  //falseSystem.out.println("(int)c = "+(int)c); //转换成int类型,值为65531System.out.println("(short)c = "+(short)c); //-5System.out.println("(int)s = "+(int)s);//-5
}

运行结果:

false
(int)c = 65531
(short)c = -5
(int)s = -5

  从上面的结果发现,char类型的c 与 short类s其实存储字节码内容是一样的,但由于前者是无符号,所以扩展成int类型的结果是 65531,而不是 -5。运算符==比较的就是他们扩展成int类型的值,所以为fasle。

对char类型的类型转换,可以总结成以下几点:

  • char类型与byte、short的相互转换,都需要显式地强类型制转换。
  • 对于数值是负数的,都需要进行显式地强制类型转换,特别是在×××字面常量的隐式转换中。
  • char类型转换成int、long类型是符合 小类型转大类型的规则,即无需要强制类型转换。

4. 运算结果的类型

  在Java中,一个运算结果的类型是与表达式中类型最高的相等,如:

char cc = 5;
float dd = 0.6f+cc;//最高类型是float,运算结果是float
float ee = (float) (0.6d+cc);//最高类型是double,运算结果也是double
int aa = 5+cc;//最高类型是int,运算结果也为int

  但是,对于最高类型是byte、short、char的运算来说,则运行结果却不是最高类型,而是int类型。看下面的例子,c、d运算的最高类型都是char,但运算结果却是int,所以需要强制类型转换。

 byte b = 2;char a = 5;char c = (char) (a+b);//byte+char,运算结果的类型为int,需要强制类型转换int  e = a+b;//编译通过,不需要强制类型转换,可以证明是intchar d = (char) (a+c);//char+char,short s1 = 5;short s2 = 6;short s3 =(short)s1+s2; 

综上所述,java的运算结果的类型有两个性质:

  • 运算结果的类型必须是int类型或int类型以上。
  • 最高类型低于int类型的,运算结果都为int类型。否则,运算结果与表达式中最高类型一致。

三、浮点数类型

1. 浮点类型的介绍

  我们都知道,long类型转换成float类型是不需要强制类型转换的,也就是说相对于flaot类型,long类型是小类型,存储的范围要更小。然而flaot只占了4个字节,而long却占了8个字节,long类型的存储空间要比float类型大。这究竟是怎么一回事,我们接下来将细细分析。

  浮点数使用 IEEE(电气和电子工程师协会)格式。 浮点数类型使用 符号位、指数、有效位数(尾数)来表示。要注意一下,尾数的最高

在java中,float 和 double 的结构如下:

类 型 符 号 位 指 数 域 有效位域
float 1位 8位 23位
double 1位 11位 52位

符号位: 0为正,1为负;
指数域: 无符号的,float的偏移量为127(即float的指数范围是-126~127,),double
有效位域: 无符号的;

2. 浮点类型的两个需要注意的地方

1)存储的小数的数值可能是模糊值

public static void main(String[] args) {double d1 = 0.1;double d2 = 0.2;System.out.println(d1+d2 == 0.3);System.out.println(d1+d2);
}

运行结果:

false
0.30000000000000004

  上述的运算结果并不是错误。这是因为无法用二进制来准确地存储的0.3,这是一个无限循环的值,与10进制的1/3很相似。不只是0.3,很多小数都是无法准确地用浮点型表示,其实这是由 小数的十进制转成二进制的算法所决定的,十进制的小数要不断乘2,知道最后的结果为整数才是最后的二进制值,但这有可能怎么也得不到整数,所以最后得到的结果可能是一个 无限值 ,浮点型就无法表示了

  但是对于 整数 来说,在浮点数的有效范围内,则都是精确的。同样,也是由于转换算法:十进制的整数转成二进制的算法是不断对2求余数,所以 不会存在无限值的情况;

2)浮点数的有效位及精度

  浮点型所能表示的有效位是有限的,所以哪怕是整数,只要超出有效位数,也只能存储相似值,也就是该数值的最低有效位将会丢失,从而造精度丢失。
  float类型的二进制有效位是24位,对应十进制的7 ~ 8位数字;double类型的二进制53位,对应十进制的10 ~ 11位数字。

double、float类型 所能表示的范围比int、long类型表示的范围要广,也浮点类型属于大类型。但是,并不能完美地表×××,浮点类型的精度丢失会造成一些问题。

public static void main(String[] args) {int a = 3000000;int b = 30000000;float f1 = a;float f2 = b;System.out.println("3000000==3000001 "+(f1==f1+1));System.out.println("30000000==30000001 "+(f2==f2+1));System.out.println("3000000的有效二进制位数:"+ Integer.toBinaryString(a).length());System.out.println("30000000的有效二进制位数:"+ Integer.toBinaryString(b).length());
}

运行结果:

3000000 == 3000001  false
30000000 == 30000001  true
3000000的有效二进制位数: 22
30000000的有效二进制位数: 25

  上面的例子很好体现了精度丢失所带来的后果:30000000==30000001 的比较居然为true了。而造成这种结果的原因就是 30000000的有效二进制位数是25位,超出了float所能表示的有效位24位,最后一位就被舍去,所以就造成在刚加的1也被舍去,因此30000000的加一操作前后的浮点型表示是一样的。

  当然,并不是超出浮点型的有效位就不能精确表示,其实,主要看的是最高有效位与最低非0有效位之间的 “间隙”,如果间隙的在浮点型的有效位数内,自然可以精确表示,因为舍去的低有效位都是0,自然就无所谓了。如果上面的例子的浮点型用的是double就不会丢失精度了,因为double的精度是52位。

3)解决浮点型精度丢失的问题

  浮点型带来精度丢失的问题是很让人头痛的,所以一般情况下,在程序中是不会使用float、double来存储比较大的数据。而商业计算往往要求结果精确。《Effactive Java》书中有一句话:

float和double类型的主要设计目标是为了科学计算和工程计算

JDK为此提供了两个高精度的大数操作类给我们:BigInteger、BigDecimal。

出处:http://www.cnblogs.com/jinggod/p/8424583.html
文章有不当之处,欢迎指正,你也可以关注我的微信公众号:好好学java,获取优质资源。

转载于:https://blog.51cto.com/sihai/2105313

java基础(一) 深入解析基本类型相关推荐

  1. 你所需要的java基础篇深入解析大汇总

    java基础篇深入解析大总结 java基础(一) 深入解析基本类型 java基础(二) 自增自减与贪心规则 java基础(三) 加强型for循环与Iterator java基础(四) java运算顺序 ...

  2. java基础之BitSet(解析)

    java基础之BitSet(解析) It depends on Java virtual machine. java中一个booliean有占用多少内存空间? 1个bit位 1个字节 4个字节 其实都 ...

  3. java基础(十) 深入理解数组类型

    戳上面的蓝字关注我们哦! 精彩内容 精选java等全套视频教程 精选java电子图书 大数据视频教程精选 java项目练习精选 1. 数组类简介   在java中,数组也是一种引用类型,即是一种类. ...

  4. java基础(七) 深入解析java四种访问权限

    戳上面的蓝字关注我们哦! 精彩内容 精选java等全套视频教程 精选java电子图书 大数据视频教程精选 java项目练习精选 引言   Java中的访问权限理解起来不难,但完全掌握却不容易,特别是4 ...

  5. Java基础篇:泛型与类型擦除

    一.什么是泛型: 泛型的本质是 参数化类型,也就是说 将所操作的数据类型 指定为一个参数,在不创建新类的情况下,通过参数来指定所要操作的具体类型(类似于方法中的变量参数,此时类型也定义成参数形式),也 ...

  6. Java 基础【12】 日期类型

    java api中日期类型的继承关系 java.lang.Object --java.util.Date --java.sql.Date --java.sql.Time --java.sql.Time ...

  7. java基础(八) 深入解析常量池与装拆箱机制

    ###引言 本文将介绍常量池 与 装箱拆箱机制,之所以将两者合在一起介绍,是因为网上不少文章在谈到常量池时,将包装类的缓存机制,java常量池,不加区别地混在一起讨论,更有甚者完全将这两者视为一个整体 ...

  8. java怎编写么解析一个类型_DAY3:你必须知道的java虚拟机之类篇——类文件的结构...

    马上过年啦,不知道大家今年有没有投资基金股票呢?是赚的盆满钵满还是拍断大腿,可以评论区一起交流交流,秀一秀哈哈,反正我是没来得及上车. 暴富西不可能暴富的啦,打工人嘛几能写写文章啦-记得点赞➕关注呀 ...

  9. Java基础——volatile关键字解析

    简介 volatile关键字虽然从字面上理解起来比较简单,但是要用好不是一件容易的事情.由于volatile关键字是与Java的内存模型有关的,因此在讲述volatile关键之前,我们先来了解一下与内 ...

最新文章

  1. Vue父组件网络请求回数据后再给子组件传值demo示例
  2. 面试题:请用代码实现ip地址与int之间互换?
  3. 车牌检测识别--Towards End-to-End Car License Plates Detection and Recognition with Deep Neural Networks
  4. Linux 磁盘坏道检测和修复
  5. SqlServer修改数据库文件及日志文件存放位置
  6. System_Recovery_21.0.3_62137_Multilingual_Product
  7. 通过小程序给公众号传递消息_多输入现场消息传递应用程序概念
  8. 计算机 教育 初中 论文范文1000字,初中作文1000字
  9. 恶意软件借手机游戏强行吸取流量,使用代码签名证书验明证身
  10. 拓端tecdat|R语言是否对二分连续变量执行逻辑回归
  11. C语言课程设计-车辆信息管理系统
  12. Pymol教程--安装
  13. python利用有道词典翻译_Python调用有道词典翻译
  14. 为什么每天都在学习,生活还是没有任何改善?
  15. signature=56b13ba141d8042e7f17a5bffcc46d8e,vue 汉字转成拼音
  16. 做好软件测试的关键是什么,做好测试计划和测试用例的工作的关键是什么?
  17. 常用颜色的RGB值及调色方法
  18. 教你使用html+js手绘一个时钟
  19. python-import自己的写的文件
  20. 1000个瓶子里面999瓶是水,多少次试验确定哪瓶是毒药

热门文章

  1. gnokii 中文安装使用文档
  2. UA MATH524 复变函数6 Green定理与Green公式
  3. VC++ 判断点是否在线段上
  4. Java的中BIO、NIO、AIO-1
  5. Django—模板渲染
  6. 开发时间及内容(二)
  7. Android View 事件分发机制详解
  8. 再议Unity 3D
  9. 01 MySQL锁概述
  10. 用Virtual PC 2007安裝Fedora Core 9