数据类型
- 强类型语言:[Java] 要求变量的使用要严格符合规定,所有变量都必须先定义才能使用。(优缺点:安全性高,速度会慢)
- 弱类型语言:[javaScript]
Java数据类型分为两大类
- 基本类型 (primitive type)
- 引用类型 (reference type)
1. 基本类型【面试题】
【面试题:八个基本类型数据】
public class Demo {
public static void main(String[] args) {
// 八大基本类型
// 整数类型
Integer
int num1 = 10;// 最常用 对应一个类 Integer
byte num2 = 20;
short num3 = 30;
long num4 = 30L;// long 类型要在最后加L或l(大小写)通常用大写,不容易看错
// 浮点类型:小数
float num5 = 20.1F;// float 类型要在最后加F或f(大小写),否则会认为是double类型
double num6 = 3.1415926;
// 字符类型:一个字 2个字节
char name = '思';
// 布尔类型
boolean flag = true;
boolean flag2 = false;
}
}
1B(byte,字节)= 8bit(位)
No. | 数据类型 | 占字节 | 数据范围 |
---|---|---|---|
1 | byte(字节型) | 1 | -128~127 |
2 | short(短整型) | 2 | -32768~32767 |
3 | int(整型) | 4 | -2147483648~2147483647 |
4 | long(长整型) | 8 | -9223372036854775808~9223372036854775807 |
5 | float(单精度) | 4 | -3.4E38~3.4E38 |
6 | double(双精度) | 8 | -1.7E308~1.7E308 |
7 | char(字符) | 2 | 0~255 |
8 | boolean(布尔) | - | true或false |
2. 引用类型
类、接口、数组
3. 数据类型扩展【面试题】
public class Demo{
public static void main(String[] args) {
// (1)整数扩展:进制 二进制0b 八进制0 十进制 十六进制0x
int i = 0b10; // 二进制,以0b开头
int i2 = 010; // 八进制,以0开头
int i3 = 10; // 十进制,正常
int i4 = 0x10; // 十六进制,以0x开头
System.out.println(i);
System.out.println(i2);
System.out.println(i3);
System.out.println(i4);
// (2)浮点数扩展:最好避免使用浮点数进行比较 (银行一般用BigDecimal数学工具类比较)
// 以下判断有问题的原因:
// 原因1:float 有限 离散 舍入误差 大约 接近但不等于
// 原因2:float是8位有效数字,第7位数字将会产生四舍五
float f = 0.1F;
double d = 1.0 / 10;
System.out.println(f);
System.out.println(d);
System.out.println(f == d);//false
/*
计算机比较会转为二进制进行比较,小数转化成二进制时,可能出现无限循环,double和float的精度不一样,就会出现比值不一样
如0.1转换为二进制为:
0.1 * 2 = 0.2 ——- 整数为0,故取该位为0
0.2 * 2 = 0.4 ——- 整数为0,继续取0
0.4 * 2 = 0.8 ——- 整数为零,取零
0.8 * 2 = 1.6 ——- 整数为1,取1
0.6 * 2 = 1.2 ——- 取1
0.2 * 2 = 0.4 ——- 取零,和前面循环了。
故此0.1(base 10) == 0.00011 0011 0011…(0011为无限循环数位值)
*/
float f2 = 123456990F;
float f3 = f2 + 1;
System.out.println(f2);
System.out.println(f3);
System.out.println(f2 == f3);//true
// (3)字符扩展:所有字符本质是数字
char c1 = 'a';
char c2 = '中';
System.out.println((int) c1);//强制转换为数字 =>97
System.out.println((int) c2);//强制转换为数字 =>20013
//了解编码 Unicode (码点值:U0000-UFFFF)
char c3 = '\u0061';
System.out.println(c3);//a
// (4)转义字符:一些字符前加 “\” 使它具有其他意义
/*
\n 换行
\r 回车
\t 制表符
*/
// (5)对象:从内存分析
// == :比较的是地址值 equals:比较的是字符串的值 (String通常使用这个作比较)
/*
第一个 new String("hello World"); => 创建了两个对象,"hello World"创建于常量池中,String对象创建于堆内存中。
第二个 new String("hello World"); => 由于常量池中有"hello World"对象,所以只需创建一个对象,String对象创建于堆内存中。
s1与s2分别指向String对象堆内存,所以 s1 == s2 为false
*/
String s1 = new String("hello World");
String s2 = new String("hello World");
System.out.println(s1 == s2);//false
System.out.println(s1.equals(s2));//true 比较是字符串的值,所以为true
//只需创建一个对象"hello World"到常量池中,所以 s3 == s4 为true
String s3 = "hello World";
String s4 = "hello World";
System.out.println(s3 == s4);//true
// 常量的值在编译的时候就确定了,"hello"、"world"都是常量,因此s6的值在编译的时候也确定了,所以 s5 == s6 为true
String s5 = "hello World";
String s6 = "hello " + "World";
System.out.println(s5 == s6);//true
/*
s10由两个String变量相加得到,不能在编译时就确定下来,不能直接引用常量池中的"helloWorld"对象,
而是在堆内存中创建一个新的String对象并由s10指向,所以 s7 == s10 为false
*/
String s7 = "helloWorld";
String s8 = "hello";
String s9 = "World";
String s10 = s8 + s9;
System.out.println(s7 == s10);//false
/*
被final修饰变为宏变量,不可更改,编译器在程序使用该变量的地方,直接使用该变量的值进行替代,所以s14的值在编译的时候就为"helloworld"
指向常量池中的"helloworld"对象,所以 s11 == s14 为true
*/
String s11 = "helloWorld";
final String s12 = "hello";
final String s13 = "World";
String s14 = s12 + s13;
System.out.println(s11 == s14);//true
}
}
类型转换
- 由于 Java 是强类型语言,所以要进行有些运算的时候,需要用到类型转换
低 --------------------------------------------> 高
byte,short,char->int->long->float->double - 运算中,不同类型的数据先转化为同一类型,然后进行计算
- 强制类型转换:(类型)变量名 高转低
- 自动类型转换:低转高
- 注意点:【面试点】
- 不能对布尔值进行转换
- 不能把对象类型(变量)转为不相干类型
- 在把高容器转换到低容器的时候,强制转换
- 转换的时候可能存在内存溢出或精度问题
// 【面试题】
public class Demo3 {
public static void main(String[] args) {
// 强制转换 (类型)变量名 高转低
// 自动转换 低转高
// 转换的时候可能存在内存溢出或精度问题
int i = 128;
byte b = (byte) i;//将int转换成byte 强制转换 出现内存溢出
System.out.println(b);//-128
System.out.println((int) 23.7);//23 精度出现问题
System.out.println((int) -45.36f);//-45 精度出现问题
// 操作比较大的数的时候,注意溢出问题
// JDK7新特性,数字之间可以用下划线分隔 不影响结果
int money = 10_0000_0000;//与1000000000一样
int years = 20;
int total = money * years;
System.out.println(total);//-1474836480 计算的时候溢出了
long total2 = money * years;
System.out.println(total2);//-1474836480 默认是int 转换之前已经存在问题
long total3 = money * ((long)years);//先把一个数转换为long
System.out.println(total3);//20000000000 正确
}
}