Java基础(2)数据类型与变量
上一篇我们学习了Java语言特性与main方法的创建等内容,接下来将在本篇中和大家一起简单了解Java中的关键字并学习数据类型与变量。
Java中的关键字
上一篇文章我们学习了什么是标识符。在 IDEA 中编写 Java 代码时,像 public、class、static 这类词会以特殊颜色高亮显示,这些具有特殊含义的标识符就被称为关键字。关键字是 Java 语言预先定义好的,所有关键字都由小写字母组成,在程序中具有固定的含义和用途,因此用户在自定义变量名、方法名、类名或包名等标识符时不能使用关键字。
部分常用关键字:
1. 用于定义访问权限修饰符的关键字
- public— 公开访问权限,任何类都可以访问。是最宽松的修饰符,常用于需要对外暴露的 API 方法。
- protected— 受保护访问权限,同包内的类以及不同包中的子类可以访问。适合希望在继承体系中共享的成员。
- default(无修饰符)— 默认访问权限,只能被同包内的类访问。当不写任何访问修饰符时默认生效。
- private— 私有访问权限,只能在本类内部访问。是实现封装性的关键,保护数据不被外部直接修改。
2. 用于定义类、函数、变量修饰符的关键字
- abstract— 声明抽象类或抽象方法。抽象方法没有方法体,需要子类去具体实现。
- final— 声明最终类(不能被继承)、最终方法(不能被重写)或常量(值不可修改)。
- static— 声明静态成员,属于类本身而不是某个实例。可以通过类名直接调用,无需创建对象。
- synchronized— 声明同步方法或同步代码块,用于控制多线程并发访问,保证线程安全。
3. 用于定义类与类之间关系的关键字
- extends— 表示继承关系,一个类可以继承另一个类(单继承),从而获得父类的属性和方法。
- implements— 表示实现接口,一个类可以实现多个接口,从而获得接口中定义的行为规范。
4. 用于定义建立实例、引用实例、判断实例的关键字
- new— 用于创建对象实例,在堆内存中分配空间,并调用构造方法初始化对象。
- this— 表示当前对象的引用,可以用来区分成员变量和局部变量,也可以在构造方法中调用其他构造方法。
- super— 表示父类对象的引用,可以用来调用父类的构造方法或访问父类中被重写的方法。
- instanceof— 用于判断一个对象是否为某个类或接口的实例,返回布尔值,常用于类型检查。
5. 用于异常处理的关键字
- try— 包裹可能抛出异常的代码块,配合 catch 或 finally 使用。
- catch— 捕获 try 块中抛出的异常,并定义处理逻辑。
- finally— 无论是否发生异常都会执行的代码块,常用于释放资源(如关闭文件流、数据库连接等)。
- throw— 用于手动抛出一个异常对象,可以在方法内部使用。
- throws— 用于方法声明上,表示该方法可能抛出的异常类型,提醒调用者进行处理。
6. 用于包的关键字
- package— 声明当前类所属的包,用于组织和管理类文件,避免类名冲突。
- import— 导入其他包中的类或接口,使得在当前文件中可以直接使用而不需要写完整包路径。
数据类型
Java 的数据类型分为两大类:基本数据类型和引用数据类型。
基本数据类型(8 种):
- byte:1 字节,取值范围 -128 ~ 127。
- short:2 字节,取值范围 -32768 ~ 32767。
- int:4 字节,取值范围约 -21 亿 ~ 21 亿,是最常用的整数类型。
- long:8 字节,用于表示更大的整数,赋值时需要在数字后加 L(如
100L)。 - float:4 字节,单精度浮点数,赋值时需要在数字后加 F(如
3.14F)。 - double:8 字节,双精度浮点数,是默认的浮点类型。
- char:2 字节,采用 Unicode 编码,可以表示一个字符(包括中文)。
- boolean:只有
true和false两个值,用于逻辑判断。
也可分为四类:整型、浮点型、字符型以及布尔型。
注意:
- 整型和浮点型都是带有符号的
- 整型默认为int,浮点型默认为double
引用数据类型:包括类(class)、接口(interface)、数组(array)、字符串(String)等。引用类型的变量存储的是对象在内存中的地址,而不是对象本身。
Java与C语言的数据类型的比较
在学习Java之前,大家可能也学习过C语言,那么C语言中的数据类型和Java中有什么区别呢?
我们先回顾一下C语言的数据类型:
C 语言的数据类型可以分为基本类型和派生类型。
基本类型:
- char:通常 1 字节,用于存储单个字符(ASCII 编码)。
- int:通常 4 字节,但具体大小依赖于编译器和平台(16 位系统上可能为 2 字节)。
- float:4 字节,单精度浮点数。
- double:8 字节,双精度浮点数。
- void:表示无类型,常用于函数返回值或通用指针(
void*)。
此外,C 语言还提供了修饰符short、long、signed、unsigned来调整整数类型的大小和符号属性,例如unsigned int、long long等。
派生类型:包括数组(array)、指针(pointer)、结构体(struct)、共用体(union)、枚举(enum)等。
Java 与 C 语言数据类型的主要区别
- 类型大小是否固定:Java 中所有基本数据类型的大小是固定的,与平台无关,保证了跨平台的一致性;而 C 语言中部分类型(如 int、long)的大小依赖于编译器和操作系统,可能存在平台差异。
- 有无 boolean 类型:Java 有专门的
boolean类型,只能取 true 或 false,不能用 0 或非 0 代替;C 语言直到 C99 才引入_Bool类型,传统上使用整数 0 表示假、非 0 表示真。 - char 类型的差异:Java 的
char固定占 2 字节,采用 Unicode 编码,可以表示中文等字符;C 语言的char通常占 1 字节,采用 ASCII 编码,主要表示英文字符。 - 有无指针:C 语言有指针类型,可以直接操作内存地址,灵活但容易出错;Java 没有指针的概念,用引用类型代替。
- struct 与类的区别:C 语言用
struct(结构体)来组织多个数据字段,但它只能包含数据,不能包含方法;Java 用类(class)来封装数据和行为,面向对象特性更强。 - 有无无符号类型:C 语言支持
unsigned修饰符来表示无符号整数(只能取非负值);Java 中所有整数类型都是有符号的,没有无符号类型。
变量
在我们学习变量之前,先简单了解一下什么是常量?
常量
常量就是在程序运行期间,固定不变的量
public class Test{ public static void main(String[] args){ System.out.println("hello"); System.out.println('a'); System.out.println(10); System.out.println(3.14); System.out.println(true); } }上述代码中:“hello”、‘a’、10、3.14、true都是常量,称为字面常量。
字面常量
字面常量(也称字面量)是指在程序中直接写出的固定值,它们在编译时就已经确定,并且在整个程序运行期间都不会改变。
字面常量的分类
根据数据类型的不同,Java 中的字面常量可以分为以下几类:
- 整数字面量:没有小数部分的数值常量,如
10、-20、0。默认为int类型,如果在数字后加L(或小写l),则表示long类型,如100L。 - 浮点数字面量:带有小数点的数值常量,如
3.14、-0.5。默认为double类型,如果在数字后加F(或f),则表示float类型,如3.14F。 - 字符字面量:用单引号括起来的单个字符,如
'a'、'中'、'1'。 - 字符串字面量:用双引号括起来的字符序列,如
"hello"、"你好"。字符串在 Java 中属于引用类型,不是基本类型,其底层是一个String对象。 - 布尔字面量:只有
true和false两个值,用于表示逻辑上的真和假。
需要区分的是,'a'是字符字面量,而"a"是字符串字面量,两者类型不同,在内存中的存储方式也不一样。
变量
什么是变量?
变量是程序中最基本的存储单元,其值在程序运行期间可以改变,比如人的身高、年龄等。而数据类型就是用来定义不同种类变量的。
在 Java 中,使用变量前需要先声明(定义变量类型和名称),然后赋值(给变量一个具体的值)。
变量的声明与赋值
声明变量的基本语法:
数据类型 变量名 = 初始值;例如:
int age; // 声明一个整型变量 age double d; // 声明一个双精度浮点型变量 d String name; // 声明一个字符串变量 name声明的同时可以赋值(初始化):
int age = 25; // 声明并初始化 double d = 8000.50; // 声明并初始化 String name = "张三"; // 声明并初始化也可以先声明,后赋值:
int score; score = 95; // 后续赋值变量的作用
- 存储数据:保存程序运行过程中需要使用的数据。
- 数据共享:同一个变量可以在程序的不同位置被访问和修改。
- 提高可读性:通过有意义的变量名,让代码更容易理解。
- 便于维护:当需要修改某个值时,只需修改变量的值,而不需要修改所有使用该值的地方。
变量与常量的区别
与前面学习的常量(程序运行期间固定不变的值)不同,变量的值可以在程序运行过程中被改变:
int count = 10; // 初始值为 10 count = 20; // 可以修改为 20 count = count + 5; // 可以参与运算并重新赋值而常量一旦赋值就不能再改变:
final int MAX_VALUE = 100; // 使用 final 关键字定义常量 // MAX_VALUE = 200; // 错误!常量不能重新赋值整型变量
Java 中的整型变量用于存储整数,根据存储空间和取值范围的不同,分为四种:字节型(byte)、短整型(short)、整型(int)和长整型(long)。它们都是基本数据类型,且都是有符号的(可表示正负)。
1. 字节型变量(byte)
- 内存占用:1 字节(8 位)
- 取值范围:-128 ~ 127
- 特点:占用空间最小,常用于处理二进制数据(如文件、网络流)或节省内存的大数组。
- 包装类型:byte的包装类型为Byte
//byte型变量所能表示的范围 System.out.println(Byte.MIN_VALUE);//最小值 System.out.println(Byte.MAX_VALUE);//最大值2. 短整型变量(short)
- 内存占用:2 字节(16 位)
- 取值范围:-32768 ~ 32767
- 特点:比 int 省空间,但使用频率较低。
- 包装类型:short的包装类型为Short
//short型变量所能表示的范围 System.out.println(Short.MIN_VALUE);//最小值 System.out.println(Short.MAX_VALUE);//最大值3. 整型变量(int)
- 内存占用:4 字节(32 位)
- 取值范围:约 -21 亿 ~ 21 亿(-2^31 ~ 2^31-1)
- 特点:最常用的整数类型。Java 中整数字面量(如 10、-5)默认就是 int 类型。
- 包装类型:int的包装类型为Integer
//int型变量所能表示的范围 System.out.println(Integer.MIN_VALUE);//最小值 System.out.println(Integer.MAX_VALUE);//最大值4. 长整型变量(long)
- 内存占用:8 字节(64 位)
- 取值范围:约 -9.22×1018 ~ 9.22×1018(-2^63 ~ 2^63-1)
- 特点:用于表示非常大的整数。定义 long 类型字面量时,需要在数字后加
L或l(建议大写 L,避免与数字 1 混淆)。 - 包装类型:long的包装类型为Long
//long型变量所能表示的范围 System.out.println(Long.MIN_VALUE);//最小值 System.out.println(Long.MAX_VALUE);//最大值浮点型变量
浮点型变量用于存储带有小数部分的数值。Java中有两种精度的浮点类型:单精度浮点型(float)和双精度浮点型(double)。它们都遵循 IEEE 754 标准。
1. 单精度浮点型(float)
- 内存占用:4 字节(32 位)
- 取值范围:约 ±3.4×1038(有效位数约 6-7 位十进制数字)
- 特点:精度较低,但占用空间小。在给
float类型变量赋值时,需要在数字后加F或f(如3.14F),否则编译器会将其视为double类型而报错。 - 包装类型:
float的包装类型为Float
// float型变量的声明与赋值 float f1 = 3.14F; // 正确,使用F后缀 float f2 = 2.718f; // 正确,使用f后缀 // float f3 = 3.14; // 错误!默认浮点字面量是double类型,需要强制类型转换或使用F后缀 // float型变量所能表示的范围 System.out.println(Float.MIN_VALUE); // 最小正非零值 System.out.println(Float.MAX_VALUE); // 最大值 System.out.println(Float.MIN_NORMAL); // 最小正规格化值2. 双精度浮点型(double)
- 内存占用:8 字节(64 位)
- 取值范围:约 ±1.8×10308(有效位数约 15-16 位十进制数字)
- 特点:默认的浮点类型,精度更高,是 Java 中最常用的浮点类型。浮点数字面量(如
3.14、2.71828)默认就是double类型。 - 包装类型:
double的包装类型为Double
// double型变量的声明与赋值 double d1 = 3.141592653589793; // 正确,默认就是double double d2 = 2.71828D; // 正确,也可以使用D后缀(可选) double d3 = 1.0e-10; // 科学计数法表示 // double型变量所能表示的范围 System.out.println(Double.MIN_VALUE); // 最小正非零值 System.out.println(Double.MAX_VALUE); // 最大值 System.out.println(Double.MIN_NORMAL); // 最小正规格化值注意事项:
- 浮点型运算可能存在精度损失,不适合用于需要精确计算的场景。
- 比较两个浮点数是否相等时,不要直接使用
==,而应判断它们的差值是否小于一个很小的阈值。
布尔型变量
布尔型变量用于存储逻辑值,只有两个可能的取值:true(真)和false(假)。它主要用于条件判断和逻辑运算。
- 内存占用:没有明确指定,JVM 实现相关(通常为 1 位到 1 字节)
- 取值范围:
true或false - 特点:
- 不能与整数类型(如
int)相互转换。 - 是控制流语句(如
if、while、for)的条件表达式的基础。 - 支持逻辑运算符:
&&(逻辑与)、||(逻辑或)、!(逻辑非)。
- 不能与整数类型(如
- 包装类型:
boolean的包装类型为Boolean
// boolean型变量的声明与赋值 boolean isReady = true; boolean isFinished = false; boolean result = (10 > 5); // 关系运算的结果是boolean类型 // 用于条件判断 if (isReady) { } else { } // 逻辑运算 boolean a = true; boolean b = false; System.out.println(a && b); // 输出: false (逻辑与) System.out.println(a || b); // 输出: true (逻辑或) System.out.println(!a); // 输出: false (逻辑非)注意事项:
- 在 Java 中,
boolean类型不能参与算术运算,也不能强制转换为其他基本数据类型。 - 关系运算符(
>、<、==、!=等)的结果总是boolean类型。 - Java的boolean类型不存在1表示true,0表示false这样的用法。
字符型变量
字符型变量用于存储单个字符。Java 使用char类型,它采用Unicode编码,可以表示世界上大多数语言的字符。
- 内存占用:2 字节(16 位)
- 取值范围:0 ~ 65535(即 Unicode 码点范围 0x0000 ~ 0xFFFF)
- 特点:
- 使用单引号
' '表示字符字面量,如'A'、'中'、'1'。 - 可以表示转义字符,如
'\n'(换行)、'\t'(制表符)、'\\'(反斜杠)。 - 可以直接用 Unicode 转义序列表示。
- 可以进行算术运算,因为
char本质上是一个无符号整数。
- 使用单引号
- 包装类型:
char的包装类型为Character
// char型变量的声明与赋值 char c1 = 'A'; // 英文字母 char c2 = '中'; // 中文字符 char c3 = '\n'; // 转义字符:换行 char c4 = '\u0041'; // Unicode转义序列,也表示'A' // char型变量可以进行算术运算 char letter = 'A'; System.out.println(letter); // 输出: A System.out.println(letter + 1); // 输出: 66 (字符'A'的Unicode码点65 + 1) System.out.println((char)(letter + 1)); // 输出: B // 常用Character类方法 System.out.println(Character.isDigit('5')); // true,判断是否为数字 System.out.println(Character.isLetter('A')); // true,判断是否为字母 System.out.println(Character.toUpperCase('a')); // 输出: A注意:
- 字符字面量必须用单引号括起来,且只能包含一个字符(转义字符算一个字符)。
- 字符串字面量(如
"Hello")是String类型,属于引用类型,不是char类型。 - 计算机中的字符本质上是⼀个整数。在 C 语⾔中使⽤ ASCII 表⽰字符, ⽽ Java 中使⽤ Unicode 表⽰字符。
类型转换
Java 是一门强类型编程语言,这意味着在编译阶段会对数据类型进行严格的检查。当参与运算的数据类型不一致时,就会发生类型转换。Java中的类型转换主要分为两类:自动类型转换(隐式转换)和强制类型转换(显式转换)。
1. 自动类型转换(隐式转换)
自动类型转换就是:代码不需要经过任何处理,在代码编译时,编译器会自动进行处理。
当数据范围⼩的转为数据范围⼤的时会⾃动进⾏。
这种转换也称为“向上转型”或“宽化转换”。
自动转换的方向(从小到大):
byte → short → int → long → float → double ↑ char示例:
int a = 100; long b = 10L; b = a;// 自动转换:int类型 → long类型 (范围扩大) System.out.println(b); // 输出: 100 float f = 3.14F; double d = 4.31; d = f;// 自动转换:float类型 → double类型 (精度提高) System.out.println(d); // 输出: 3.140000104904175 (注意浮点精度) char c = 'A'; int i = 0; i = c; // 自动转换:char类型 → int类型 (字符的Unicode码点) System.out.println(i); // 输出: 652. 强制类型转换(显式转换)
强制类型转换就是:代码需要经过一定的格式处理,不能自动完成类型转换。
当数据范围大的转为数据范围小的时需要强制类型转换。
这种转换也称为“向下转型”或“窄化转换”,可能会导致数据丢失或精度降低。
示例:
int a = 10; long b = 100L; a = (int)b;// 强制类型转换:long类型 → int类型 (范围缩小) System.out.println(a); // 输出: 100 float f = 3.14F; double d = 4.31; f = (float)d;// 强制类型转换:double类型 → float类型 (精度降低) System.out.println(f); byte i = 123; byte j = (byte)456;//456默认为int类型,超出了byte的范围,如果不进行强制类型转换,就会报错注意:
boolean类型不能与其他任何基本数据类型进行转换。- 不同数字类型的变量之间赋值, 表⽰范围更⼩的类型能自动转换成范围较⼤的类型。
- 将范围⼤的类型赋值给范围⼩的, 需要强制类型转换, 但可能导致精度丢失。
- 强制类型转换不一定能成功
- 给一个变量赋一个字面常量时,Java编译器会进行类型兼容性检查:对于整数字面量,如果值在目标类型(如byte、short、char)的取值范围内,编译器会自动进行隐式转换;如果超出范围,则编译报错,需要进行强制类型转换。
3. 自动类型提升
在表达式中,不同类型的数据之间相互运算时,数据类型小的会被提升为数据类型大的。比如:如果操作数的类型小于int(如byte、short、char),它们会先被自动提升为int类型,然后再参与运算。
byte b1 = 10; byte b2 = 20; // byte c = b1 + b2; // 编译错误!b1 + b2 的结果是 int 类型 int c = b1 + b2; // 正确 byte b = (byte)(b1 + b2);//正确 System.out.println(c); // 输出: 30 short s = 100; char c = 'A'; // Unicode 65 int sum = s + c; // s 和 c 都提升为 int 后相加 System.out.println(sum); // 输出: 1654. 字符串与基本数据类型的转换
在Java中使用String类来定义字符串类型。
例如:
public static void main(String[] args){ String s = "hello"; System.out.println(s); }- 基本类型转字符串:使用
String.valueOf()或+ ""。int num = 123; String str1 = String.valueOf(num); // 推荐 String str2 = num + ""; // 简洁,但会产生临时字符串 System.out.println(str1); // "123" - 字符串转基本类型:使用包装类的
parseXxx()方法。String str = "456"; int i = Integer.parseInt(str); double d = Double.parseDouble("3.14"); boolean b = Boolean.parseBoolean("true");
感谢阅读,下一篇文章我们将继续学习Java中的基础知识,希望这篇文章对你有帮助!
