java基本数据类型

(写了很多 Java程序,也开发过很多Java项目,现在才决定要写点Java相关的系列文章,因为我对自己的文章没有绝对的信心,都是开发过程中的经验之谈,再加 上我自己以前考过SCJP证书,所以希望写点不误导读者的更加细节和详细的文章出来,所以希望有读者觉得有笔误的话留我的Email地址给我,而且为了不 误导读者,都使用了【草案】,谢谢大家的合作: silentbalanceyh@126.com

【以下讲解都在 32bit 的系统中】

1.Java数据类型基本概念:

   数据类型在计算机语言里面,是对内存位置的一个抽象表达方式,可以理解为针对内存的一种抽象的表达方式。接触每种语言的时候,都会存 在数据类型的认识,有复杂的、简单的,各种数据类型都需要在学习初期去了解,Java是强类型语言,所以Java对于数据类型的规范会相对严格。数据类型 是语言的抽象原子概念,可以说是语言中最基本的单元定义,在Java里面,本质上讲将数据类型分为两种:简单类型和复杂类型。

   简单类型: 简单数据类型是不能简化的、内置的数据类型、由编程语言本 身定义,它表示了真实的数字、字符和整数。

   复杂类型 :Java语言本身不支持C++中的结构(struct) 或联合(union)数据类型,它的复合数据类型一般都是通过类或接口进行构造,类提供了捆绑数据和方法的方式,同时可以针对程序外部进行信息隐藏。

2.Java中的 基本 类型:

   1) 概念:

   Java中的简单类型从概念上分为四种: 实数、整数、字符、布尔值 。但是有一点需要说明的是,Java里面只有八种原始类 型,其列表如下:

   实数: double、float

   整数: byte、short、int、 long

   字符: char

   布尔值: boolean

   复杂类型和基本类型的内存模型本质上是不一样的,简单数据类型的存储原理是这样的:所有的简单数据类型不存在“引用”的概念,简单数 据类型都是直接存储在内存中的内存栈上的,数据本身的值就是存储在栈空间里面,而Java语言里面只有这八种数据类型是这种存储模型;而其他的只要是继承 于Object类的复杂数据类型都是按照Java里面存储对象的内存模型来进行数据存储的,使用Java内存堆和内存栈来进行这种类型的数据存储,简单地 讲,“引用”是存储在有序的内存栈上的,而对象本身的值存储在内存堆上的。

   2) 详细介绍:

   Java的简单数据 讲解 列表如下:

   int: int为 整数 类型,在存储的时候,用 4个字节 存储,范围为 -2,147,483,648 到2,147,483,647 ,在变 量初始化的时候, int 类型的默认值为 0

   short short 也 属于 整数 类 型,在存储的时候,用 2 个字节 存储,范围为 -32,768 32,767 ,在变量初始化的时候, short 类型的默认值为 0 ,一般情况下,因为 Java 本 身转型的原因,可以直接写为 0

   long long 也 属于 整数 类 型,在存储的时候,用 8 个字节存储,范围为 -9,223,372,036,854,775,808 9,223,372,036, 854,775,807 ,在变量初始化的时候, long 类型的默认值为 0L 0l ,也可直接写为 0

   byte byte 同 样属于 整数 类 型,在存储的时候,用 1 个字节 来存储,范围为 -128 127 ,在变量初始化的时候, byte 类型的默认值也为 0

   float float 属 于 实数 类 型,在存储的时候,用 4 个字节 来存储,范围为 32 IEEEE 754 单精度 范 围,在变量初始化的时候, float 的默认值为 0.0f 0.0F ,在初始化的时候可以写 0.0

   double double 同样属于 实数 类型,在存储的时候,用 8 个字节 来存储,范围为 64 IEEE 754 双精度 范 围,在变量初始化的时候, double 的默认值为 0.0

   char char 属 于 字符 类 型,在存储的时候用 2 个字节 来存储,因为 Java 本身的字符集不是用 ASCII 码来进行存储,是使用的 16 Unicode 字符集,它的字符范围即是 Unicode 的字符范围 ,在变量初始化的时候, char 类型的默认值为 'u0000'

   boolean boolean 属于 布尔 类型,在存储的时候不使用字节,仅仅使用 1 来存储,范围仅仅为 0 1 ,其字面量为 true false ,而 boolean 变量在初始化的时候变量的默认值为 false

   3) 相关介绍:

  在 Java 基本类型在使用字面量赋值的时候,有几个简单的特性如下:

   1 】当整数类型的数据使用字面量赋值的 时候,默认值为 int 类型,就是直接使用 0 或者其他数字的时候,值的类型为 int 类型,所以当使用 long a = 0 这种赋值方式的时候, JVM 内部存在数据转换。

  【 2 】当实数类型的数据使用字面量赋值的时候,默认值为 double 类型,就是当字面两出现的时候, JVM 会使用 double 类型的数据类型。

  ( * :以上两点在转型中进行详细说明。)

  【 3 】从 JDK 5.0 开始, Java 里面出现了自动拆箱解箱的操作,基于这点需要做一定的说明:

  对应原始的数据类型,每种数据类型都存在一个复杂类型的封装 类,分别为 Boolean Short Float Double Byte Int Long Character ,这些类型都是内置的封装类,这些封装类( Wrapper )提供了很直观的方法,针对封装类需要说明的是,每种封装类都有 一个 xxxValue() 的方法,通过这种方法可以把它引用的对象里面的值转化成为原始 变量的值,不仅仅如此,每个封装类都还存在一个 valueOf(String) 的方法直接把字符串对象转换为相应的简单类型。

  在 JDK 5.0 之前,没有存在自动拆解箱的操作,即 Auto Box 操作,所以在这之前是不能使用以下方式的赋值代码的:

Integer a = 0; // 这种赋 值方式不能够在 JDK 1.4 以及以下的 JDK 编译器 中通过

但是 JDK 5.0 出现了自动拆解箱的操作,所以在 JDK 5.0 以上的编译器中,以上的代码是可以通过的,关于自动拆箱解箱我会 另外用一篇 1.4 5.0 的升级加以详细说明。

3.Java 中简基本数据类型的转型:

   Java 中的简单数据类型的转换分为两种: 自 动转换和强制转换

   1) 自动转换:

  当一个较“小”的数据和较“大”的数据一起运算的时候,系统将自动将较“小”的数据转换为较“大”的数据,再进行运算。

  在方法调用过程,如果实际参数较“小”,而函数的形参比较“大”的时候,除非有匹配的方法,否则会直接使用较“大”的形参函数进行调 用。

   2) 强制转换:

  将“大”数据转换为“小”数据时,可以使用强制类型转换,在强制类型转换的时候必须使用下边这种语句:

int a = (int)3.14;

  只是在上边这种类型转换的时候,有可能会出现精度损失。

  关于类型的自动提升,遵循下边的规则:

   所有的 byte short char 类型的值将提升为 int 类型;

  如果有一个操作数是 long 类型,计算结果是 long 类型;

  如果有一个操作数是 float 类型,计算结果是 float 类型;

  如果有一个操作数是 double 类型,计算结果是 double 类型;

  自动类型转换图如下:

   byte -> short(char) -> int -> long -> float -> double

  如果是强制转换的时候,就将上边的图反过来

   3) 转换附加:

  当两个类型进行自动转换的时候,需要满足条件:【 1 】这两种类型是兼容的,【 2 】目的类型的数值范围应该比源转换值的范围要大。而拓展范围就遵 循上边的自动类型转换树,当这两个条件都满足的时候,拓展转换才会发生,而对于几个原始类型转换过程,根据兼容性 boolean char 应该是独立的,而其他六种类型是可以兼容的,在强制转换过程,唯 独可能特殊的是 char int 是可以转换的,不过会使用 char ASCII 码值比如:

int a = (int)'a';

   a 的值在转换过后输出的话,值为 97

4.Java 中的高精度数:

   Java 提供了两个专门的类进行高精度运算: BigInteger BigDecimal ,虽然 Java 原始变量都具有对应的封装类型,但是这两个 变量没有对应的原始类型,而是通过方法来提供这两种类型的一些运算,其含义为普通类型能够做的操作,这两个类型对应都有,只是因为精度过大可能效率不够 高。至于这两个类的具体操作可以参考 JDK 的相关 API 文档。

5. 关于数据类型的一些技巧:(以下为参考一篇原文文档)

  若要求精度的结果,尽量避免使用 float double

   float double 类型本身是为了做科学运算,即执行二进 制浮点运算而设计,但是却不能提供完全精确的结果,所以在要求精度的数值中,避免使用 float double float double 在货币运算中尤其不合适,要让 float double 精确表达 0.1 也是不可能的事。测试一下下边这段代码就明白 了:

   System.out.println(2.02-0.42);

  结果是不是出乎意料,这个结果并不是偶然,而是 JVM 本身设计的目的决定的。 而要解决这个问题,最好的办法是使用 BigDecimal int 或者 long 进行相关运算,特别是货币运算,使用 BigDecimal 代替 double 是一个很好的办法。

   BigDecimal 唯一的缺点在于: BigDecimal 没有相对 应的原始类型,所以在进行基本数值运算的时候,需要进行方法调用才能操作,这样会使得和我们的编程习惯不相符合,若使用 int long ,就需要进行简单的封装运算。

  所以在要求精度答案的计算任务里面,一般慎用 float double ,如果在进行商务运算,并且要求四舍五入或者简单的舍入行为,使用 BigDecimal 可能更加方便。所以尽量避免在精度运算中使用 float double ,特别是我们常用的货币运算。

5. 总结:

  以上是开发过程中针对 Java 数据类型的一份总结,最后一个技巧是在一个 商务系统运算的时候发现的,然后参考了网上的很多文档,偶然在一篇 BLOG 中发现的,原文提倡在 精度运算中尽量不用 float double ,而关于 Java 的基本数据类型,上边应该涵盖了所有开发会用到的内容,还有一点就是在于几个特殊值的比较,这里没有做说明,比如 Double.NaN == Double.NaN 输出为 false ,等等所有封装类的特殊类型,没有进行详 细说明。

原文地址:http://docs.google.com/Doc?docid=0AXJpK9YuEe6pZGM5ZDd3ODNfN2d3NWhwcWc4&hl=en

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值