一、基本类型的简介

  基本类型的两条准则:

  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”等等。我们先看个例子:

  publicstaticvoidmain(String[]args){inta=8;//8是字面常量byteb=9;//9是字面常量charc=9+5;//常量表达式shorts=(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);子所以不能隐式转换,就是因为表达式不是常量表达式,包含了变量,只能在运行期间完成,所以就要手动强制转换。

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

  ×××字面常量的大小超出目标类型所能表示的范围时,要手动强制类型转换。byteb=128;//编译错误,128超出byte类型所能表示的范围bytec=(byte)128;//编译通过

  对于传参数时,必须要显式地进行强制类型转换,明确转换的类型编译器子所以这样要求,其实为了避免 方法重载出现的隐式转换 与 小类型自动转大类型 发生冲突。

  publicstaticvoidmain(String[]args){shortMethod(8);//编译错误shortMethod((short)8);//编译通过longMethod(8);//编译通过,因为这是小类型变成大类型,是不需要强制类型转换的}publicstaticvoidshortMethod(shortc){System.out.println(c);}publicstaticvoidlongMethod(shortl){System.out.println(l);}

  char类型的特殊情况 :下面再细讲2. 复合运算符的隐式转换

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

  publicstaticvoidmain(String[]args){inta=8;shorts=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个字节,还包括字面常量数值不能为负数

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

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

  publicstaticvoidmain(String[]args){shorts=-5;charc=(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中,一个运算结果的类型是与表达式中类型最高的相等,如:

  charcc=5;floatdd=0.6f+cc;//最高类型是float,运算结果是floatfloatee=(float)(0.6d+cc);//最高类型是double,运算结果也是doubleintaa=5+cc;//最高类型是int,运算结果也为int

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

  byteb=2;chara=5;charc=(char)(a+b);//byte+char,运算结果的类型为int,需要强制类型转换inte=a+b;//编译通过,不需要强制类型转换,可以证明是intchard=(char)(a+c);//char+char,shorts1=5;shorts2=6;shorts3=(short)s1+s2;

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

  运算结果的类型必须是int类型或int类型以上。

  最高类型低于int类型的,运算结果都为int类型。否则,运算结果与表达式中最高类型一致。三、浮点数类型

  1. 浮点类型的介绍

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

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

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

  类 型符 号 位指 数 域有效位域

  float1位8位23位

  double1位11位52位

  符号位:0为正,1为负;

  指数域:无符号的,float的偏移量为127(即float的指数范围是-126~127,),double

  有效位域:无符号的;

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

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

  publicstaticvoidmain(String[]args){doubled1=0.1;doubled2=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类型表示的范围要广,也浮点类型属于大类型。但是,并不能完美地表×××,浮点类型的精度丢失会造成一些问题。

  publicstaticvoidmain(String[]args){inta=3000000;intb=30000000;floatf1=a;floatf2=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。

  

java基础深入解析基本类型的更多相关文章

  1. java 基础知识二 基本类型与运算符

    java  基础知识二 基本类型与运算符 1.标识符 定义:为类.方法.变量起的名称 由大小写字母.数字.下划线(_)和美元符号($)组成,同时不能以数字开头 2.关键字 java语言保留特殊含义或者 ...

  2. Java基础教程:枚举类型

    Java基础教程:枚举类型 枚举类型 枚举是将一具有类似特性的值归纳在一起的方法.比如,我们可以将周一到周日设计为一个枚举类型.彩虹的七种颜色设计为一个枚举类型. 常量实现枚举 我们通过定义常量的方式 ...

  3. java基础-8种基本类型

    正文 java中的八种基础类型. boolean:只有两个值,false,true 带符号类型 byte:占用1个字节,一个字节也就是8位,那么由于是最高一位是用来表示 负还是正,所以范围就是 -2^ ...

  4. Java基础教程(15)--枚举类型

      枚举类型定义了一个枚举值的列表,每个值是一个标识符.例如,下面的语句声明了一个枚举类型,用来表示星期的可能情况: public enum Day { SUNDAY, MONDAY, TUESDAY ...

  5. python基础——python解析yaml类型文件

    一.yaml介绍 yaml全称Yet Another Markup Language(另一种标记语言).采用yaml作为配置文件,文件看起来直观.简洁.方便理解.yaml文件可以解析字典.列表和一些基 ...

  6. java基础讲解04-----数据类型和运算符

    1.java的基本数据类型 1.数值型  { 整数型   byte  , short  ,int  ,long 浮点型   float , double } 2.字符型 3.布尔型 2.运算符 1.赋 ...

  7. JAVA基础——异常--解析

      简介 异常处理是java语言的重要特性之一,<Three Rules for effective Exception Handling>一文中是这么解释的:它主要帮助我们在debug的 ...

  8. Java基础 ----- 判断对象的类型

    1. 判断对象的类型:instanceOf 和 isInstance 或者直接将对象强转给任意一个类型,如果转换成功,则可以确定,如果不成功,在异常提示中可以确定类型 public static vo ...

  9. ## Java基础(二):变量类型

    Java 变量类型 一.局部变量:类的方法中的变量 局部变量声明在方法.构造方法或者语句块中: 局部变量在方法.构造方语句块中被执行的时候创建,当他们执行完成后,变量被销毁 访问修饰符不能用于局部变量 ...

随机推荐

  1. python图片处理(二)

    未经允许,请勿转载!!!! 这次打算先写处理图片的方法,然后再调用方法来运行 下面先写的是处理图片的方法: # -*- coding: utf-8 -*- import os import matpl ...

  2. git的使用(包括创建远程仓库到上传代码到git的详细步骤以及git的一些常用命令)

    A创建远程仓库到上传代码到git 1)登陆或这注册git账号 https://github.com 2)创建远程仓库 3)打开终端输入命令 cd到你的本地项目根目录下,执行如下git命令 git in ...

  3. SSM三层模型之间的参数传递

    Controller接收各种形式的传参:   RequestMapping()包含三部分信息:   表单传参: 1.表单action请求   1:参数名称和顺序都要和表单字段名称一致,直接接收(适合字 ...

  4. sql可重复执行语句例子

    1.添加字段 SET @add_key_type_to_report = (SELECT IF( (SELECT count(1) FROM INFORMATION_SCHEMA.COLUMNS WH ...

  5. swift 错误集锦

    1.注册 NIB 出现错误 // error:'registerNib(_:forCellReuseIdentifier:)' has been renamed to 'register' (_:fo ...

  6. python 简单的爬虫

    import urllib.request import re import ssl # 处理https请求 import time import os # 创建目录用 def get_html(ur ...

  7. js dom 操作技巧

    1.创建元素 创建元素:document.createElement() 使用document.createElement()可以创建新元素.这个方法只接受一个参数,即要创建元素的标签名.这个标签名在 ...

  8. php ci 报错 Object not found! The requested URL was not found on this server. If you entered the URL manually please check

    Object not found! The requested URL was not found on this server. The link on the referring page see ...

  9. [转载]ASP.NET-----Repeater数据控件的用法总结

    一.Repeater控件的用法流程及实例: 1.首先建立一个网站,新建一个网页index.aspx. 2.添加或者建立APP_Data数据文件,然后将用到的数据库文件放到APP_Data文件夹中. 3 ...

  10. js常量

    原文链接:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Statements/const const 声明创建一个 ...