数据类型
分为基本数据类型和非基本数据类型(复合数据类型)(又名引用数据类型)
java基本类型因为是使用频率很高的,而new创建的对象都是保存在堆内存中的,读取速度较慢。而且先获取对象再获取对象值也不如直接获取值方便,所以有了基本类型
- java明确了每种基本类型的内存占用大小,不随着平台而改变 | 基本类型 | 大小 | 最小值 | 最大值 | | —- | —- | —- | —- | | boolean | — | — | — | | char | 16 bits | Unicode 0 | Unicode 216 -1 | | byte | 8 bits | -128 | +127 | | short | 16 bits | - 215 | + 215 -1 | | int | 32 bits | - 231 | + 231 -1 | | long | 64 bits | - 263 | + 263 -1 | | float | 32 bits | IEEE754 | IEEE754 | | double | 64 bits | IEEE754 | IEEE754 | | void | — | — | — |
字符类型
- 字符常量有两种字符类型普通字符和转义字符
- 转义字符可以用在单/双引号
-
整型
整型常量有十进制、八进制和十六进制三种表示方法 1234(十进制,无变化)
- 0777(八进制,以数字 0 开头) 0具有迷惑性,所以少使用8进制
- 0x3ABC(十六进制,以 0x/0X开头)
- 长整型以L/l后缀表示
java7之后可以加上前缀 0b 或 0B 就可以表示二进制数
浮点型
float用F/f 无F/f的默认为double,double还可以D/d表示
- double叫做双精度浮点型,因为它精度是float精度的2倍。
- 绝大部分应用程序都采用 double 类型。在很多情况下,float 类型的精度很难满足需求。实际上,只有很少的情况适合使用 float 类型,例如,需要单精度数据的库, 或者需要存储大量数据。
除了小数形式,还有科学计数法(用e/E表示10的幂次方)
如123.24e40表示123.24乘以10的40次方
浮点型运算
- 浮点数类型与整数不同,当执行运算时如果出现某种不正常的状态,浮点数类型不会抛出异常。例如,如果用 0 除浮点数类型的变量,则计算结果是一个特别的无限值、
- 浮点数值不适用于无法接受舍入误差的金融计算中。 例如,命令 System.out.println ( 2.0-1.1 ) 将打印出 0.8999999999999999, 而不是人们想象的 0.9。**这种舍入误差的主要原因是浮点数值采用二进制系统表示, 而在二进制系统中无法精确地表示分数 1/10**。这 就好像十进制无法精确地表示分数 1/3 —样。如果在数值计算中不允许有任何舍入误差, 就应该使用 BigDecimal 类
- 整数除以 0 除将会产生一个异常
如11/0
, 而浮点数除以0 会得到无穷大或 NaN 结果sout(11.0/0)->Infinity(即∞)
- 当参与 / 运算的两个操作数都是整数时, 得到的是整数结果(去尾) 如
11/2=5
- 布尔型
BigInteger和BigDecimal
- 如果基本的整数和浮点数精度不能够满足需求, 那么可以使用 java.math 包中的两个很有用的类:Biglnteger 和 BigDecimal 这两个类可以处理包含任意长度数字序列的数值
- Biglnteger 类实现了任意精度的整数运算,即大数。
- 大数不能使用+和*运算符,而是使用add 和 multiply 方法。
- BigDecimal 实现了任意精度的浮点数运算。
- Biglnteger 类实现了任意精度的整数运算,即大数。
静态方法
BigInteger.valueOf()
可以将普通整型转为大数BigInteger a = BigInteger.valueOf(100);
Biglnteger c = a.add(b); // c = a + b
Biglnteger d = c.multiply(b.add(Biglnteger.valueOf(2))); // d = c * (b + 2)
基本类(包装类)
除了char和int外,其他都是首字母大写得到基本类
- 前 6 个类派生于公共的超类 Number,而 Character 和 Boolean 是 Object 的直接子类。
- 包装类都是final类型的,无法被继承 | 基本类型 | 对应的包装类(位于 java.lang 包中) | | —- | —- | | byte | Byte | | short | Short | | int | Integer | | long | Long | | float | Float | | double | Double | | char | Character | | boolean | Boolean |
基本类与对于基本类型可以互相转化。这种转化叫做装箱/拆箱
- 在java中万物皆对象,而基本类型非常常用,所以有了基本类型,同时又有了包装类。以下即包装类的简陋原型
public class MyInt {
private int number; // 基本数据类型
public Int (int number){ // 构造函数,传入基本数据类型
this.number = number;
}
public int intValue(){ // 取得包装类中的数据
return this.number;
}
public static void main(String[] args) {
MyInt temp = new Int(100); // 100 是基本数据类型, 将基本数据类型包装后成为对象
int result = temp.intValue(); // 从对象中取得基本数据类型
System.out.println(result);
}
}
Integer n = new Integer(123);
装箱,可以缩写为Integer n=123;
n=n+1;
自动拆箱 基本类运算时会给自动转换为基本类型
设有 Double 类对象 dObjdouble d = dObj.doubleValue();//自动拆
或者double d=dObj;
//这是自动拆箱
装箱即基本类型转为基本类,拆箱即基本类转为基本类型
Object类与基本类联系
- Object是所有类的超类,所以自然能接收基本类类型。
Object obj = 10; int temp = (Integer) obj;
期间自动实现了装拆箱与上下转型
IntegerCache缓存
public static void main(String[] args) {
Integer n1 = 47;
Integer n2 = 47;
System.out.println(n1 == n2); //TRUE
Integer n3 =128 ;
Integer n4 = 128;
System.out.println(n3 == n4); //false
}
- Integer 内部维护着一个 IntegerCache 的缓存(一个Integer对象数组),默认缓存范围是 [-128, 127],创建Integer对象时,如果值在这个范围内,就会直接复用缓存数组里的对象
- 所以 [-128, 127] 之间的2个同值的Integer对象用==会得到true,因为他们是一个对象的两个引用,只是创建了一个新的引用。而对于范围外的值的Integer对象,就是创建了新的对象和引用。
- 如果是一个类的对象持有Integer字段,那不存在==这个问题(比较一个对象的Integer字段时只需把他看成是基本类型即可,即只是值传递而非引用传递)
class A{Integer aa;
main(){A v1 = new A(),v2 = new A();
v1.i=v2.i = 128;
sout(v1.i==v2.i)} ->true
}
基本类的缓存
Byte,Short,Integer,Long 这 4 种包装类默认创建了数值 [-128,127] 的相应类型的缓存数据,Character 创建了数值在 [0,127] 范围的缓存数据,Boolean 直接返回 True or False。
三种创建Integer对象的方式
第一种自动装箱,本质上就是调用了valueOf()方法。所以第一种和第三种如果是在缓存池中的数值,那返回的只是一个对象复用。超出缓存池,返回的是新对象。而第二种无论是否在缓存池中都返回新的对象 ```java
1.Integer num= 130;
2.Integer num = new Integer(12);
3.Integer num = Integer.valueOf(12);
<a name="vJyG3"></a>
# 类型转换
<a name="AZeXk"></a>
## 自动转换
- 只要是涉及赋值与比较的地方都会发生自动转换
<br />**6 个实心箭头,表示无信息丢失的转换;有 3 个虚箭头, 表示可能有精度损失的转换**。
```java
sout(97=='a') //true
9.0==9 //true
强制转换
- 强制类型转换(cast ) 同样有可能会丢失一些信息
double x = 9.997; int nx = (int) x;
如果运算结果溢出了,将溢出的结果转为更大的类型还是错的
基本类.parse基本类()
parse...()
都是静态方法,所以使用类名调用- 字符型没有
**parse...()**
方法。取而代之的是一个charAt()
方法,该方法属于String方法,可以根据索引提取字符
- 字符型没有
还可以使用
基本类.valueOf()
String str = "10"; int temp = Integer.parseInt(str);// String->Integer->int System.out.println(temp * 2); // 20
基本类型/字符串转基本类
方法1:通过基本类的构造方法转
- 方法2:通过
基本类.valueOf(基本类型/字符串)
转,这种除了Integer外,其他跟方法1一样,但是转Integer时除了返回一个new的对象,还可能返回一个缓冲池中对象的引用- 这种方法不能用于字符型
默认浮点
- 注意小数默认为double,所以
//如果仅仅是为了输出,加可以通过以下方法转为保留小数的String类型 float num = 3.1415926f; String num1 = String.format(“%.2f”,num); System.out.println(num1); ```