Java基本数据类型介绍
Java是一种强类型语言(Strongly typed language),这就意味着必须为每一个变量声明一种类型。说到基本的数据类型,我们可以去了解下相关的java面向对象的思想。Java是以C++为基础设计的,尽管如此,但java是一种更纯粹的面向对象语言。在学习或者是使用java的时候,我们可以将自己置身于一个面向对象的世界里面,也就是java的世界,java乃至java程序内的一切都是对象。在各种各样的编程语言中亦会存在着各种各样的操作数据的方式。那在java中这是如何实现的呢?既然java把所有东西都当做了对象,那好,我们可以举一个例子:电视机,这个对象,我们在现实世界是如何操作电视机这个现实中的对象的呢,众所周知,我们用的是遥控器,那在java的世界中,我们用什么去操作电视机这个对象呢,我们用的是Handle,一个叫做句柄的东西,有的人把它称为“引用”,也有的人叫它指针。只要我们掌控住这个handle(遥控器),我们就可以随意的根据电视机这个对象所具有的功能对其进行控制。我们在屋里看电视的时候,想要对电视进行控制,例如调频,关声音等等,我们只需要手里抓住遥控器就行了,而不需要在怀里抱着个电视。在java中亦是如此,我们要操作java中的电视这个对象,只需要这个handle。此外,即使没有电视机,遥控板亦可独立存在。也就是说,只是由于拥有一个句柄,并不表示必须有一个对象同它连接。假如我们想在java程序中使用电视机这个对象,我们可以创建一个电视机的Handle:
TV tv;
但是我们在这里创建的只是一个Handle(遥控器),而不是一个对象(电视机)。若此时我们向tv这个handle发送消息,tv.open(),就会出现运行期的错误。这是由于tv并没有和任何东西进行衔接,也就是说这个遥控器没有可遥控的电视机。因此,我们一般在程序中会采用更安全的做法,在创建一个Handle的时候,无论如何都会去对这个Handle进行初始化:
TV tv = new Tv();
在java中所有对象都必须被创建,也就是说创建Handle的时候,我们会使它同一个对象进行衔接。我们通常会使用new关键字来做到。new的意思是:“把我变成这些对象的一种新类型”。Java提供了数量众多的基本类型,在这些类型之外,我们亦可以创建自己的类型,用new关键字。
大概了解了java的面向对象,我们现在步入正题,开始我们java基本数据类型的学习。
Java基本数据(Primitive)类型,这也是java的特殊情况,在上述中我们了解到我们可以使用new关键字来在程序中创建我们自己的类型,然而在这些类型的使用中,new关键字却是不是非常的有效,因为new将对象置于“堆”中。对于这些类型,Java采纳了与C和C++相同的方法。也就是说,不是用new创建变量,而是创建一个并非句柄的“自动”变量。这个变量容纳了具体的值,并置于堆栈中,能够更高效地存取。
Java决定了每种主要类型的大小。就像在大多数语言里那样,这些大小并不随着机器结构的变化而变化。这种大小的不可更改正是Java程序具有很强移植能力的原因之一。
基本数据类型
主类型 | 大小 | 最小值 | 最大值 | 封装器类型 |
boolean | 1-bit | – | – | Boolean |
char | 16-bit | Unicode 0 | Unicode 216- 1 | Character |
byte | 8-bit | -128 | +127 | Byte[11] |
short | 16-bit | -215 | +215 – 1 | Short1 |
int | 32-bit | -231 | +231 – 1 | Integer |
long | 64-bit | -263 | +263 – 1 | Long |
float | 32-bit | IEEE754 | IEEE754 | Float |
double | 64-bit | IEEE754 | IEEE754 | Double |
void | – | – | – | Void1 |
数值类型全都是有符号(正负号)的,所以不必费劲寻找没有符号的类型。
主数据类型也拥有自己的“封装器”(wrapper)类。这意味着假如想让堆内一个非主要对象表示那个主类型,就要使用对应的封装器。例如:
char c = 'x';
Character C = new Character('c');
也可以直接使用:
Character C = new Character('x');
这样做的原因将在以后的章节里解释。
高精度数字
java 1.1增加了两个类,用于进行高精度的计算:BigInteger和BigDecimal。尽管它们大致可以划分为“封装器”类型,但两者都没有对应的“主类型”。
这两个类都有自己特殊的“方法”,对应于我们针对主类型执行的操作。也就是说,能对int或float做的事情,对BigInteger和BigDecimal一样可以做。只是必须使用方法调用,不能使用运算符。此外,由于牵涉更多,所以运算速度会慢一些。我们牺牲了速度,但换来了精度。
BigInteger支持任意精度的整数。也就是说,我们可精确表示任意大小的整数值,同时在运算过程中不会丢失任何信息。
BigDecimal支持任意精度的定点数字。例如,可用它进行精确的币值计算。
至于调用这两个类时可选用的构建器和方法,请自行参考联机帮助文档。
转帖:
今天参考课本写了一个关于二进制与十进制转换的程序,程序算法不难,但写完后测试发现不论是二转十还是十转二,对于大于21亿即超过整数范围的数不能很好的转换。都会变成0.
参考书籍发现使用使用BigInteger可以解决这个问题。
于是查找了下JDK,然后测试几次终于写成功了!
使用心得如下:
1,BigInteger属于java.math.BigInteger,因此在每次使用前都要import 这个类。偶开始就忘记import了,于是总提示找不到提示符。
2,其构造方法有很多,但现在偶用到的有:
|
|
如要将int型的2转换为BigInteger型,要写为BigInteger two=new BigInteger("2"); //注意2双引号不能省略
3,BigInteger类模拟了所有的int型数学操作,如add()==“+”,divide()==“-”等,但注意其内容进行数学运算时不能直接使用数学运算符进行运算,必须使用其内部方法。而且其操作数也必须为BigInteger型。
如:two.add(2)就是一种错误的操作,因为2没有变为BigInteger型。
4,当要把计算结果输出时应该使用.toString方法将其转换为10进制的字符串,详细说明如下:
|
输出方法:System.out.print(two.toString());
5,另外说明三个个用到的函数。
|
|
|
|
remainder用来求余数。
negate将操作数变为相反数。
compare的详解如下:
compareTo
public int compareTo(BigInteger val)
将此 BigInteger 与指定的 BigInteger 进行比较。对于针对六个布尔比较运算符 (<, ==, >, >=, !=, <=) 中的每一个运算符的各个方法,优先提供此方法。执行这些比较的建议语句是:(x.compareTo(y) <op> 0),其中 <op> 是六个比较运算符之一。
指定者:
接口 Comparable<BigInteger>
中的 compareTo
参数:
val
- 将此 BigInteger 与之比较的 BigInteger。
返回:
当此 BigInteger 在数值上小于、等于或大于 val 时,返回 -1,0,或 1。
Java的数组
几乎所有程序设计语言都支持数组。在C和C++里使用数组是非常危险的,因为那些数组只是内存块。若程序访问自己内存块以外的数组,或者在初始化之前使用内存(属于常规编程错误),会产生不可预测的后果(注释②)。
②:在C++里,应尽量不要使用数组,换用标准模板库(Standard TemplateLibrary)里更安全的容器。
Java的一项主要设计目标就是安全性。所以在C和C++里困扰程序员的许多问题都未在Java里重复。一个Java可以保证被初始化,而且不可在它的范围之外访问。由于系统自动进行范围检查,所以必然要付出一些代价:针对每个数组,以及在运行期间对索引的校验,都会造成少量的内存开销。但由此换回的是更高的安全性,以及更高的工作效率。为此付出少许代价是值得的。
创建对象数组时,实际创建的是一个句柄数组。而且每个句柄都会自动初始化成一个特殊值,并带有自己的关键字:null(空)。一旦Java看到null,就知道该句柄并未指向一个对象。正式使用前,必须为每个句柄都分配一个对象。若试图使用依然为null的一个句柄,就会在运行期报告问题。因此,典型的数组错误在Java里就得到了避免。
也可以创建主类型数组。同样地,编译器能够担保对它的初始化,因为会将那个数组的内存划分成零。