数据类型
关键字
关键字一共50个,其中const和goto是保留字。
此外,还有3个特殊值:true,false,null。它们看起来像关键字,但从技术角度,它们是特殊的布尔值和空值。
变量概念
变量就是用来存储数据的
变量定义方式
三种方式
方式1: 先声明 再赋值
方式2: 连声明 带赋值 写为一条语句
方式3: 同时声明多个同类型的变量(了解) 实际开发中不推荐使用 因为阅读性较差
package com.yuluochenxiao.test;
public class FunctionTest {
public static void main(String[] args) {
// 方式1: 先声明 再赋值
int a;
a = 100;
System.out.println("变量a的取值为:" + a);
// 方式2: 连声明 带赋值 写为一条语句
int b = 123;
System.out.println("变量b的取值为:" + b);
// 未赋值的局部变量是不能使用的
int c, d, e = 55, f, g = 66;
System.out.println("变量e的取值为:" + e);
System.out.println("变量g的取值为:" + g);
System.out.println("变量c的取值为:" + c); // 报错
System.out.println("变量d的取值为:" + d); // 报错
System.out.println("变量f的取值为:" + f); // 报错
}
}
数据类型
注意:Java是强类型语言,变量的类型必须与数据的类型一致。
在 Java 中,直接写一个整数常量(不带后缀)默认是
int
类型。
基本数据类型
整数类型
整数类型四种
byte
1个字节8位 数值范围 -128 ~ 127(1位是正[0]负[1] 2的7次方)
short
2个字节16位 数值范围 -32768 ~ 32767 (1位是正负 2的15次方)
int
4个字节32位 数值范围 -2147483648 ~ 2147483647 (1位是正负 2的31次方)
long
8个字节64位
byte取值范围?最大取值的原因?
-128 ~127
因为一个字节占8位,每一个都只能存储一个0或者一个1,最大的取值为每一位都存储一个1。
还要注意 计算机以首位(最高位)作为符号位 0表示正数 1表示负数,
所以 最大的取值为0111 1111 转换为十进制为127
Java中的每一个数据都有其对应的数据类型
int为整数的默认类型,如需为long类型赋值
如果取值范围超出了int 则需要在值的后面追加 "L"
如果取值范围在int范围以内 则可加 可不加
一个汉字 2 个字节
一个字母 1 个字节
package com.yuluochenxiao.test;
public class FunctionTest {
public static void main(String[] args) {
byte b1 = 100;
System.out.println("b1 = " + b1);
byte b2 = -123;
System.out.println("b2 = " + b2); // soutv 自动生成打印上一行变量的输出语句
//byte b3 = -129; // 报错 超出范围
short s1 = 8956;
System.out.println("s1 = " + s1);
short s2 = -23451;
System.out.println("s2 = " + s2);
// short s3 = -32769; // 报错 超出范围
int i1 = 895645;
System.out.println("i1 = " + i1);
int i2 = -561245;
System.out.println("i2 = " + i2);
//int i3 = 2147483648; // 报错 超出范围
// int为整数的默认类型,如需为long类型赋值
// 如果取值范围超出了int 则需要在值的后面追加“L”
// 如果取值范围在int范围以内 则可加 可不加
long l1 = 567854651;
System.out.println("l1 = " + l1);
long l2 = -45127856;
System.out.println("l2 = " + l2);
long l3 = 2147483648L;
System.out.println("l3 = " + l3);
long l4 = 100;
}
}
浮点类型
浮点类型 : 这两种类型都是近似值 不是精确值 如需精确值 使用后续学习的 BigDecimal
类
float类型赋值时,需要在数值后加"F"。
double类型赋值时,超出float类型取值范围,需要在数值后加"D"
double为浮点数的默认类型,如需为float类型赋值,需要在数值后加"F"
package com.yuluochenxiao.test;
public class FunctionTest {
public static void main(String[] args) {
float f1 = -340000000000000000000000000000000000000F;
System.out.println("f1 = " + f1);
float f2 = -0.0000000000000000000000000000000000000000000014F;
System.out.println("f2 = " + f2);
float f3 = 0.00014F;
System.out.println("f3 = " + f3);
float f4 = 340000000000000000000000000000000000000F;
System.out.println("f4 = " + f4);
// 给double类型赋值 如果取值范围超出了float的取值范围 必须在末尾加上D 推荐大写
double d1 = 2.5;
System.out.println("d1 = " + d1);
double d2 = 3.6;
System.out.println("d2 = " + d2);
}
}
long类型和float类型取值(谁大)
为什么 float 类型的字节数 小 但是取值比long类型大
这是因为 float 和 long 的数据存储方式和编码机制不同。尽管 float 的字节数更小(4 字节),它能够表示比 long 更大的范围,主要是因为 浮点数采用了科学计数法表示,而 long 是直接存储整数的值。
为什么 float 的范围更大?
指数部分:float 的 8 位指数(加上偏移值)允许表示 $2^{-126}$ 到 $2^{127}$ 之间的数,因此可以覆盖极大范围的值。
科学计数法:使用科学计数法表示数值,可以通过指数轻松扩展数值的范围,而不需要像 long 那样每一位都直接表示具体的值。
布尔类型
boolean类型 仅能描述true 或者 false
boolean类型可以直接赋值 true 或者 false 也可以赋值 最终结果为true或者false 的表达式
package com.yuluochenxiao.test;
public class FunctionTest {
public static void main(String[] args) {
boolean bl1 = true;
System.out.println("bl1 = " + bl1);
boolean bl2 = false;
System.out.println("bl2 = " + bl2);
int a = 10;
int b = 20;
boolean bl3 = a > b;
System.out.println("bl3 = " + bl3);
boolean bl4 = a < b;
System.out.println("bl4 = " + bl4);
}
}
字符类型
char只能保存任意 一个
字符,使用 单引号
包裹一个内容
赋值方式
赋值方式1 直接使用英文的 `单引号` 包裹 一个 内容
赋值方式2 直接赋值在0~65535以内的整数
赋值方式3 使用英文单引号包括十六进制的Unicode字符值 必须以杠u开头
package com.yuluochenxiao.test;
public class FunctionTest {
public static void main(String[] args) {
// 赋值方式1 直接使用英文的单引号包括一个内容
char ch1 = 'a';
System.out.println("ch1 = " + ch1);
char ch2 = '1';
System.out.println("ch2 = " + ch2);
char ch3 = '中';
System.out.println("ch3 = " + ch3);
char ch4 = '!';
System.out.println("ch4 = " + ch4);
char ch5 = '~';
System.out.println("ch5 = " + ch5);
// 赋值方式2 直接赋值在0~65535以内的整数
// ASCII 美国标准信息交换码 0 ~ 127
char ch6 = 65;
System.out.println("ch6 = " + ch6); // A
char ch8 = 66;
System.out.println("ch8 = " + ch8); // B
char ch9 = 67;
System.out.println("ch9 = " + ch9); // C
char ch7 = 97;
System.out.println("ch7 = " + ch7); // a
char ch10 = 48;
System.out.println("ch10 = " + ch10); // 0
// 中文汉字 以及 中文标点符号 将参考Unicode编码表 Unicode编码表是一个十六进制的编码表
// 记录了世界上绝大多数国加的语言 中文的取值范围是 : \u4e00(19968) ~ \u9fa5(40869)
char ch11 = 20013;
System.out.println("ch11 = " + ch11);
char ch12 = 20320;
System.out.println("ch12 = " + ch12);
char ch13 = 19967;
System.out.println("ch13 = " + ch13);
char ch14 = 19968;
System.out.println("ch14 = " + ch14);
char ch15 = 19969;
System.out.println("ch15 = " + ch15);
char ch16 = 40869;
System.out.println("ch16 = " + ch16);
// 赋值方式3 使用英文单引号包括十六进制的Unicode字符值 必须以杠u开头
char c1 = '\u4e2d';
System.out.println("c1 = " + c1);
char c2 = '\u4e00';
System.out.println("c2 = " + c2);
}
}
引用数据类型
String类型
String
类型 String是JDK提供的一个类,属于引用数据类型
,任何英文双引号
包括的内容 都是字符串
package com.yuluochenxiao.test;
public class FunctionTest {
public static void main(String[] args) {
String str1 = "abc";
String str2 = "1234";
String str3 = "月";
String str4 = "Aqua";
String str5 = "\"\"";
char ch1 = '\''; // char只能保存任意 一个 字符
System.out.println("str1 = " + str1);
System.out.println("str2 = " + str2);
System.out.println("str3 = " + str3);
System.out.println("str4 = " + str4);
System.out.println("str5 = " + str5);
System.out.println("ch1 = " + ch1);
}
}
类
类是一个引用数据类型,类似于TS中的接口interface。
空指针异常
只要使用指向为null的引用,调用任何的属性或者方法,就会产生空指针异常。
通常写的一个类就是一个数据类型。写的类就是自定义类。和JDK中内置的类是同一级别的。
数组类案例
学生类
package com.classType;
public class Student {
private String name;
private int age;
private Address address;
private Hobby[] hobby;
// set get方法
public Hobby[] getHobby() {
return hobby;
}
public void setHobby(Hobby[] hobby) {
this.hobby = hobby;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Address getAddress() {
return address;
}
public void setAddress(Address address) {
this.address = address;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
", address=" + address +
", hobby=" + hobby +
'}';
}
}
地址类
package com.classType;
public class Address {
private String province;
private String city;
private String area;
public String getProvince() {
return province;
}
public void setProvince(String province) {
this.province = province;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public String getArea() {
return area;
}
public void setArea(String area) {
this.area = area;
}
@Override
public String toString() {
return "Address{" +
"province='" + province + '\'' +
", city='" + city + '\'' +
", area='" + area + '\'' +
'}';
}
}
爱好类
package com.classType;
public class Hobby {
private String hobbyType;
private String hobbyName;
public String getHobbyType() {
return hobbyType;
}
public void setHobbyType(String hobbyType) {
this.hobbyType = hobbyType;
}
public String getHobbyName() {
return hobbyName;
}
public void setHobbyName(String hobbyName) {
this.hobbyName = hobbyName;
}
// 重写toString
@Override
public String toString() {
return "Hobby{" +
"hobbyType='" + hobbyType + '\'' +
", hobbyName='" + hobbyName + '\'' +
'}';
}
}
测试类
package com.classType;
public class Test {
public static void main(String[] args) {
// 创建对象
Student stu1 = new Student();
stu1.setName("aqua");
stu1.setAge(5);
// 创建地址对象
Address add1 = new Address();
add1.setProvince("日本省");
add1.setArea("东京都");
add1.setCity("歌舞伎町");
// 设置地址属性
stu1.setAddress(add1);
// 关于空指针异常
// 只要使用指向为null的引用 调用任何的属性或者方法 就会产生空指针异常
// 创建 hobby数组对象
Hobby [] hobbies = new Hobby[3];
// 创建 hobby元素对象
hobbies[0] = new Hobby();
hobbies[0].setHobbyType("电子竞技");
hobbies[0].setHobbyName("LOL");
hobbies[1] = new Hobby();
hobbies[1].setHobbyType("文艺类");
hobbies[1].setHobbyName("尬舞");
hobbies[2] = new Hobby();
hobbies[2].setHobbyType("体育类");
hobbies[2].setHobbyName("唱跳RAP 篮球");
// 打印信息
for (int i = 0; i < hobbies.length; i++) {
System.out.println(hobbies[i]);
}
// 设置 爱好属性
stu1.setHobby(hobbies);
// 打印信息
System.out.println("------------------------------------------------------------");
System.out.println(stu1.getName());
System.out.println(stu1.getAge());
System.out.println(stu1.getAddress());
System.out.println(stu1.getAddress().getProvince());
System.out.println(stu1.getAddress().getCity());
System.out.println(stu1.getAddress().getArea());
System.out.println("------------------------------------------------------------");
// 获取stu1的爱好类对象数组
Hobby[] hobbies1 = stu1.getHobby();
for (int i = 0; i < hobbies1.length; i++) {
// 调用爱好类中的toString方法重写
System.out.println(hobbies1[i]);
System.out.println(hobbies1[i].getHobbyType());
System.out.println(hobbies1[i].getHobbyName());
}
System.out.println("------------------------------------------------------------");
// 打印stu1对象
System.out.println(stu1);
}
}
关于对象关系:
以后我们会学习使用 ORM框架(Object Relation Mapping)对象关系映射。
常见的如Mybatis、MybatisPlus
以后在数据库中写的表,这些表在Java中要写成一个一个的类,
例如:你有一个学生表,然后对应就有一个学生类,表中有哪些字段哪些列,类中就有哪些属性。这个就叫做对象关系一一映射。
对象关系有:
一对一:一个学生对应一个地址;
一对多:一个学生对应多个爱好;
多对一:多个爱好对应一个学生;
多对多:多个学生对应多个爱好/地址;
数组
详见 数组 章节
对象
万物皆对象
详见 面向对象 章节
集合
详见 集合 章节
接口
详见 接口 章节
枚举
详见 枚举 章节
类型转换
自动提升 手动下降
自动类型提升
自动类型转换:自动类型提升
自动转换的条件
1.两种类型要相互兼容:数值与数值类型之间相互兼容。 例如short 兼容 byte 、 int兼容short等等
2.目标类型(等号左边)取值范围大于源类型(等号右边)取值范围
package com.yuluochenxiao.test;
public class FunctionTest {
public static void main(String[] args) {
// byte 转 short
byte b1 = 10;
short s1 = b1;
System.out.println("s1 = " + s1);
// byte 转 int
short s2 = 2356;
int i1 = s2;
System.out.println("i1 = " + i1);
// int 转 long
int i2 = 895645;
long l1 = i2;
System.out.println("l1 = " + l1);
// long 转 float
long l2 = 56231245L;
float f1 = l2;
System.out.println("f1 = " + f1);
// float转double
float f2 = 3.5F;
double d1 = f2;
System.out.println("d1 = " + d1);
// byte 转 short int long float double
byte b2 = 100;
short e = b2;
int a = b2;
long b = b2;
float c = b2;
double d = b2;
}
}
涉及运算符操作时,触发自动自动类型提升
进行算数运算时:
两个操作数有一个为double,计算结果提升为double。
如果操作数中没有double,有一个为float,计算结果提升为float。
如果操作数中没有float,有一个为long,计算结果提升为long。
如果操作数中没有long,有一个为int,计算结果提升为int。
如果操作数中没有int,均为short或byte或者char,计算结果仍旧提升为int。
总结:多个操作数进行数学计算,结果提升为这些操作数中取值范围最大的类型,如果均为byte、short、char则结果提升为int类型。
特殊:任何类型与String相加(+)时,实为拼接,其结果为String。
强制类型转换
强制类型转换条件
两种类型要相互兼容:数值与数值之间相互兼容。
目标类型(等号左边)取值范围小于源类型(等号右边)。
除了将浮点类型强制转换为整数类型后,小数点之后全部抹去,其他的都能完整保存
package com.yuluochenxiao.test;
public class FunctionTest {
public static void main(String[] args) {
// short类型 强转为 byte
short s1 = 127;
byte b1 = (byte)s1;
System.out.println("short类型 强转为 byte " + b1); // 127
// int类型 强转为 short
int i1 = 100;
short s2 = (short)i1;
System.out.println("s2 = " + s2); //100
// long类型 强转为 int
long l1 = 123;
int i2 = (int)l1;
System.out.println("i2 = " + i2); // 123
// float类型 强转为 long
// 将浮点类型强制转换为整数类型 小数点之后全部抹去
float f1 = 3.5F;
long l2 = (long)f1;
System.out.println("l2 = " + l2); // 3
// double类型 强转为 float
double d1 = 3.5;
float f2 = (float)d1;
System.out.println("f2 = " + f2); //3.5
// double类型 强转为 long int short byte char
double d2 = 2.5;
long l3 = (long)d2;
int i3 = (int)d2;
short s3 = (short)d2;
byte b3 = (byte)d2;
char ch1 = (char)d2;
}
}
强制类型转换特殊情况
强制类型转换特殊情况:将超出目标类型的数值进行转换
取值范围大强制转换取值范围小时,二进制数据会高位舍弃,低位保留
布尔类型不可与其他类型转换
示例1
定义一个 short类型的变量 short s1 = 257 他的二进制代码表示
short 0000 0001 0000 0001
强制类型转换为 byte类型 byte b1 = (byte) s1
二进制数据会高位舍弃,低位保留,所以b1的十进制为1
byte 0000 0001
示例2
定义一个 short类型的变量 short s2 = 128 他的二进制代码表示
short 0000 0000 1000 0000
强制类型转换为 byte类型 byte b2 = (byte) s2
二进制数据会高位舍弃,低位保留,所以b2的十进制为 -128
byte 1000 0000