01:数据类型
一、Java 数据类型总览
Java 是强类型语言,每个变量必须先声明类型,且类型不能随意改变,这也是Java语言安全性和规范性的重要体现。
Java中的数据类型整体分为两大类:
-
基本数据类型:共计8种,是Java内置的基础类型,存储的是具体数值
-
引用数据类型:除8种基本类型外,其余所有类型都属于引用类型,存储的是对象的内存地址
二、基本数据类型(Primitive Types)
Java的基本数据类型一共有8种,按照用途可以划分为4组,分别是整数类型、浮点类型、字符类型、布尔类型,下面逐一详细讲解。
(一)整数类型(4种)
整数类型用于存储整数数值,按照占用内存大小和取值范围不同,分为4种,具体特性如下:
byte类型:占用1个字节,取值范围在-128 ~ 127之间,适用于存储极小范围的整数
short类型:占用2个字节,取值范围在-32768 ~ 32767之间,日常开发中较少使用
int类型:占用4个字节,取值范围在-2147483648 ~ 2147483647之间,是Java中整数的默认类型,也是开发中最常用的整数类型
long类型:占用8个字节,取值范围极大,适合存储超大整数,声明该类型的变量时,数值末尾必须添加大写 L 作为标识(小写l容易和数字1混淆,不推荐使用)
代码示例:
java
// 不同整数类型变量声明
byte a = 10;
short b = 100;
int c = 1000;
long d = 10000000000L;
(二)浮点类型(2种)
浮点类型用于存储带有小数的数值,分为单精度浮点型和双精度浮点型两种:
float类型:占用4个字节,属于单精度浮点数,声明该类型变量时,数值末尾必须添加大写 F 作为标识
double类型:占用8个字节,属于双精度浮点数,精度比float更高,是Java中浮点数的默认类型,开发中处理小数优先使用该类型
代码示例:
java
// 不同浮点类型变量声明
float f = 3.14F;
double d = 3.1415926;
(三)字符类型(1种)
字符类型只有char一种,占用2个字节,专门用于存储单个字符。
字符类型的值必须使用单引号包裹
可以存储英文字符、中文字符,也可以存储Unicode编码对应的数字,编码会自动转为对应字符
代码示例:
java
// char类型变量声明
char c1 = 'A';
char c2 = '中';
char c3 = 97; // Unicode编码97对应字符'a'
(四)布尔类型(1种)
布尔类型只有boolean一种,主要用于逻辑判断,占用内存大小不固定。
该类型只有两个取值: true (真)和 false (假)
常用于条件判断、循环控制等逻辑场景
代码示例:
java
// boolean类型变量声明
boolean flag1 = true;
boolean flag2 = false;
三、基本数据类型默认值
在Java中,成员变量的基本数据类型会有默认初始值,具体如下:
整数类型(byte、short、int、long):默认值均为0
浮点类型(float、double):默认值均为0.0
字符类型(char):默认值为 \u0000 (空字符)
布尔类型(boolean):默认值为false
四、基本数据类型转换
Java支持基本数据类型之间的转换,分为自动类型转换和强制类型转换两种,转换需遵循数据范围规则。
1. 自动类型转换(隐式转换)
当小范围数据类型赋值给大范围数据类型时,Java虚拟机会自动完成类型转换,无需手动处理。
转换规则:byte → short → int → long → float → double,char类型可自动转换为int、long、float、double类型
代码示例:
java
int num = 100;
// int类型自动转换为double类型
double decimal = num;
2. 强制类型转换(显式转换)
当大范围数据类型需要赋值给小范围数据类型时,必须手动进行强制类型转换,否则编译报错。
转换格式:(目标数据类型) 变量名/数值
注意:强制类型转换可能会出现精度丢失、数据溢出的问题,需谨慎使用
代码示例:
java
double num = 3.99;
// 强制转换为int类型,直接舍弃小数部分,结果为3
int integer = (int) num;
五、引用数据类型
引用数据类型是基于基本数据类型构建的复杂类型,存储的是对象在堆内存中的地址,而非具体数值,主要包含以下几类:
-
类(Class):比如String字符串类、自定义的实体类、Object基类等,其中String是开发中最常用的引用类型
-
接口(Interface):使用interface关键字定义的接口类型
3. 数组([]):同一类型数据的集合,比如int[]、String[]都属于引用类型
4. 除此之外,枚举、注解、Lambda表达式等也都属于引用数据类型
String类型代码示例:
java
// String是引用类型,使用双引号存储字符串
String name = "Java开发者";
六、基本类型与包装类
Java为8种基本数据类型分别提供了对应的包装类(引用类型),方便在集合、泛型等场景中使用,对应关系如下:
byte对应Byte、short对应Short、int对应Integer、long对应Long
float对应Float、double对应Double
char对应Character
boolean对应Boolean
JDK 1.5及之后版本,支持自动装箱和自动拆箱,简化基本类型和包装类的转换:
自动装箱:基本数据类型自动转换为对应的包装类
自动拆箱:包装类自动转换为对应的基本数据类型
代码示例:
java
// 自动装箱:int → Integer
Integer num = 10;
// 自动拆箱:Integer → int
int value = num;
七、基本类型与引用类型核心区别
- 存储方式:基本类型存储具体数值,存放在栈内存;引用类型存储内存地址,对象实体存放在堆内存
2. 默认值:基本类型有固定默认值,引用类型默认值为null
3. 比较方式:基本类型用 == 比较数值大小;引用类型用 == 比较内存地址,比较内容需使用equals()方法
4. 空值:基本类型不能赋值为null,引用类型可以赋值为null
八、高频面试题
- 声明long类型变量时,为什么必须加L?
答:因为整数默认是int类型,超过int范围的数值不加L会编译报错,小写l易混淆,推荐用大写L。
2. float f = 3.14; 这句代码是否正确?
答:不正确,浮点数默认是double类型,double转float需要强制转换,正确写法是float f = 3.14F;
3. char类型可以存储中文字符吗?
答:可以,Java中char采用Unicode编码,能够覆盖所有中文字符。
4. 基本类型和引用类型的区别是什么?
答:核心区别是存储内容、存储位置、比较方式、空值支持不同,详细可参考上文区别总结。
02:数据类型扩展及面试题讲解
一、基本数据类型细节扩展
1. 整数类型底层与字面量
Java 整数默认是 int 类型,若数值超过 int 范围(-2147483648 ~ 2147483647),必须在末尾加 L 声明为 long 类型,否则编译报错。
整数支持多种进制字面量:
十进制: 100 (默认写法)
二进制: 0b100 (JDK7+,前缀 0b )
八进制: 0144 (前缀 0 ,易混淆,不推荐使用)
十六进制: 0x64 (前缀 0x ,大小写均可)
代码示例:
java
int dec = 100; // 十进制
int bin = 0b1100100; // 二进制,值为100
int oct = 0144; // 八进制,值为100
int hex = 0x64; // 十六进制,值为100
long bigNum = 10000000000L; // 超过int范围,必须加L
2. 浮点类型精度问题
float 和 double 是近似存储,无法精确表示部分小数(如 0.1 ),这是二进制浮点的固有特性。
金融、货币等高精度场景,禁止直接使用 float / double ,推荐使用 java.math.BigDecimal 保证计算精度。
代码示例:
java
// 浮点精度问题示例
double a = 0.1;
double b = 0.2;
System.out.println(a + b); // 输出0.30000000000000004,而非0.3
// 高精度计算推荐使用BigDecimal
BigDecimal num1 = new BigDecimal("0.1");
BigDecimal num2 = new BigDecimal("0.2");
System.out.println(num1.add(num2)); // 输出0.3,结果精确
3. char 类型本质与 Unicode
char 本质是16位无符号整数,对应 Unicode 编码表中的字符编号。
可直接赋值为 Unicode 编码,也可存储中文字符(Java 采用 UTF-16 编码)。
代码示例:
java
char c1 = 'A'; // 字符字面量
char c2 = 65; // 十进制编码,对应'A'
char c3 = '\u4e2d'; // Unicode转义,对应'中'
char c4 = '国'; // 直接存储中文字符
4. boolean 类型与 JVM 实现
Java 语法层面 boolean 只有 true 和 false 两个值,JVM 底层通常用 int (1表示true,0表示false)或 byte 实现。
boolean 不能与其他基本类型进行强制转换,也不能用 1/0 代替 true/false 。
二、高频面试题汇总
- 为什么 long 类型要加 L,不加会怎样?
答:整数默认是 int ,若数值超过 int 最大值却不加 L ,编译器会报「整数过大」错误;小写 l 易与数字 1 混淆,规范要求用大写 L 。
2. float f = 3.14; 编译报错吗?为什么?
答:会报错。浮点数默认是 double 类型, double 范围大于 float ,需手动加 F 声明为 float ,或进行强制转换。
3. char 类型可以存储中文吗?为什么?
答:可以。Java 中 char 采用 UTF-16 编码,覆盖了所有 Unicode 字符,包括中文字符;但生僻字或 emoji 可能占用 2 个 char (代理对)。
4. 为什么不能用 float/double 处理金钱?
答:因为二进制浮点无法精确表示 0.1 等小数,会导致精度丢失,引发金额计算错误。
03:类型转换
一、自动类型转换(隐式转换)
定义:小范围类型 → 大范围类型,JVM 自动完成转换,无需手动干预。
转换优先级: byte → short → int → long → float → double ; char 可直接转换为 int / long / float / double ,但不能与 byte / short 自动转换。
代码示例:
java
int num = 100;
double d = num; // int自动转double,结果100.0
char c = 'A';
int i = c; // char自动转int,结果65
二、强制类型转换(显式转换)
定义:大范围类型 → 小范围类型,必须手动添加 (目标类型) 语法,否则编译报错。
风险:可能出现精度丢失(浮点转整数)或数据溢出(整数转小范围整数)。
代码示例:
java
// 浮点转int,精度丢失
double pi = 3.14159;
int intPi = (int) pi; // 结果为3,直接舍弃小数部分
// 整数溢出示例
int maxInt = 2147483647;
byte b = (byte) maxInt; // 结果为-1,高位被截断,发生溢出
三、表达式中的类型提升
当表达式中包含多种基本类型时,Java 会自动将所有操作数提升为表达式中范围最大的类型。
规则: byte / short / char 会先提升为 int ,再与其他类型按优先级提升。
代码示例:
java
byte a = 10;
short b = 20;
int c = a + b; // a和b先提升为int,结果为int
long d = 100L;
double e = 1.1;
double f = d + e; // d提升为double,结果为double
四、包装类与自动装箱拆箱
自动装箱:基本类型 → 包装类(如 int → Integer ),JVM 自动调用 valueOf() 方法。
自动拆箱:包装类 → 基本类型(如 Integer → int ),JVM 自动调用 intValue() 等方法。
注意:包装类对象比较需用 equals() , == 会比较内存地址(缓存池内的小数值除外)。
代码示例:
java
// 自动装箱
Integer num = 10; // 等价于 Integer num = Integer.valueOf(10);
// 自动拆箱
int i = num; // 等价于 int i = num.intValue();
// 包装类比较
Integer a = 127;
Integer b = 127;
System.out.println(a == b); // true,127在缓存池内,地址相同
Integer c = 128;
Integer d = 128;
System.out.println(c == d); // false,128超出缓存池,地址不同
System.out.println(c.equals(d)); // true,比较数值
04:变量、常量、作用域
一、变量(Variable)
1. 变量的声明与初始化
语法: 数据类型 变量名 = 初始值; (初始化可延后,但使用前必须赋值)。
Java 是强类型语言:变量类型一旦声明,无法修改,只能存储对应类型的值。
代码示例:
java
int age; // 声明变量
age = 18; // 初始化
String name = "张三"; // 声明并初始化
2. 变量的分类(按作用域)
局部变量:定义在方法/代码块内部,作用域仅限当前方法/代码块,生命周期随方法/代码块执行结束而销毁,无默认值,必须手动初始化后才能使用。
成员变量(实例变量):定义在类内、方法外,作用域覆盖整个类的非静态方法,生命周期随对象创建而诞生、对象销毁而销毁,默认值与数据类型默认值一致。
类变量(静态变量):定义在类内、方法外,用 static 修饰,作用域覆盖整个类,被所有对象共享,生命周期随类加载而诞生、类卸载而销毁,默认值与数据类型默认值一致。
代码示例:
java
public class Student {
// 类变量(静态变量)
public static String school = "XX大学";
// 成员变量(实例变量)
private String name;
private int age;
public void study() {
// 局部变量
String subject = "Java";
System.out.println(name + "在学习" + subject);
}
}
二、常量(Constant)
定义:值不可修改的变量,用 final 关键字修饰。
命名规范:全部大写,单词间用下划线分隔(如 MAX_VALUE )。
分类:
静态常量: static final 修饰,属于类,全局共享,推荐使用。
实例常量: final 修饰,属于对象,创建后不可修改。
局部常量:方法内用 final 修饰,作用域内不可修改。
代码示例:
java
public class MathConst {
// 静态常量(推荐)
public static final double PI = 3.1415926;
// 实例常量
private final int MAX_AGE = 120;
public void test() {
// 局部常量
final int MIN_AGE = 0;
// MIN_AGE = 1; // 编译报错,常量不可修改
}
}
三、作用域(Scope)
作用域:变量可被访问的代码范围,由 {} 决定。
就近原则:当局部变量与成员变量同名时,局部变量优先(可通过 this / 类名 访问成员变量)。
生命周期:变量在作用域开始时创建,作用域结束时销毁,无法在作用域外访问。
代码示例:
java
public class ScopeDemo {
private int num = 10; // 成员变量
public void test() {
int num = 20; // 局部变量,与成员变量同名
System.out.println(num); // 输出20,就近原则
System.out.println(this.num); // 输出10,通过this访问成员变量
}
}
05:基本运算符
一、算术运算符
包括: + 、 - 、 * 、 / 、 % 、 ++ 、 --
/ :整数相除只保留整数部分,小数部分直接舍弃。
% :取模运算,结果符号与被除数一致。
++ / -- :自增/自减运算符,分前缀(先运算后取值)和后缀(先取值后运算)。
代码示例:
java
int a = 10;
int b = 3;
System.out.println(a / b); // 输出3
System.out.println(a % b); // 输出1
int c = 5;
System.out.println(c++); // 输出5,后自增
System.out.println(++c); // 输出7,先自增
二、赋值运算符
包括: = 、 += 、 -= 、 *= 、 /= 、 %=
复合赋值运算符会自动进行类型转换,避免手动强转。
代码示例:
java
short s = 10;
s += 5; // 等价于 s = (short)(s + 5),自动强转
System.out.println(s); // 输出15
三、比较运算符
包括: == 、 != 、 > 、 < 、 >= 、 <=
结果均为 boolean 类型,用于条件判断。
注意: == 比较基本类型时比较数值,比较引用类型时比较内存地址。
代码示例:
java
int x = 10;
int y = 20;
System.out.println(x > y); // 输出false
System.out.println(x != y); // 输出true
四、逻辑运算符
包括: && (短路与)、 || (短路或)、 ! (非)
短路特性: && 左侧为 false 时,右侧不执行; || 左侧为 true 时,右侧不执行,可提升效率。
代码示例:
java
int a = 5;
System.out.println(a > 10 && a++ > 0); // 输出false,a++未执行
System.out.println(a); // 输出5
System.out.println(a < 10 || a++ > 0); // 输出true,a++未执行
System.out.println(a); // 输出5
五、位运算符(了解)
包括: & (与)、 | (或)、 ^ (异或)、 ~ (取反)、 << (左移)、 >> (右移)、 >>> (无符号右移)
位运算符直接操作二进制位,常用于高效计算。
代码示例:
java
int a = 60; // 二进制 0011 1100
int b = 13; // 二进制 0000 1101
System.out.println(a & b); // 输出12(0000 1100)
System.out.println(a << 2); // 输出240,等价于乘以4
六、三元运算符
语法: 条件表达式 ? 表达式1 : 表达式2
条件为 true 时执行表达式1,为 false 时执行表达式2。
代码示例:
java
int score = 85;
String result = score >= 60 ? "及格" : "不及格";
System.out.println(result); // 输出"及格"
七、运算符优先级
优先级从高到低大致为:
() > 单目运算符( ++ / -- / ! )> 算术运算符 > 位移运算符 > 比较运算符 > 逻辑运算符 > 三元运算符 > 赋值运算符
实际开发中建议用 () 明确优先级,避免歧义。
Java 基础 08 至 12 阶段聚焦运算符进阶、包机制与文档生成三大核心模块,是夯实 Java 语法基础、规范代码编写的关键环节。以下结合 CSDN 博客排版需求,对核心知识点进行结构化总结,兼顾专业性与可读性。
06:自增自减运算符 + 初识 Math 类
1. 自增自减运算符(核心考点)
自增(++)、自减(--)是单目运算符,分为前置 与后置 两种形式,核心区别在于运算顺序与返回值:
| 形式 | 语法规则 | 执行特点 | 示例(int a=1;) |
|---|---|---|---|
| 前置自增 | ++变量 |
先自增,后取值 | int b=++a; → a=2,b=2 |
| 后置自增 | 变量++ |
先取值,后自增 | int b=a++; → a=2,b=1 |
| 前置自减 | --变量 |
先自减,后取值 | int b=--a; → a=0,b=0 |
| 后置自减 | 变量-- |
先取值,后自减 | int b=a--; → a=0,b=1 |
⚠️ 避坑要点:
- 运算符仅作用于变量,不可用于常量(如
5++编译报错); - 嵌套使用时逻辑易混乱,建议拆分代码分步计算,提升可读性。
2. 初识 Math 类(常用工具类)
Math 类是 Java 提供的数学运算工具类,位于java.lang包下,无需导包即可直接使用,所有方法均为静态方法,核心常用 API 如下:
| 方法 | 功能 | 示例 |
|---|---|---|
Math.abs(double a) |
取绝对值 | Math.abs(-5) → 5.0 |
Math.ceil(double a) |
向上取整 | Math.ceil(3.2) → 4.0 |
Math.floor(double a) |
向下取整 | Math.floor(3.8) → 3.0 |
Math.round(double a) |
四舍五入 | Math.round(3.5) → 4 |
Math.random() |
生成 [0.0,1.0) 随机数 | (int)(Math.random()*10) → 0-9 随机整数 |
Math.pow(double a, double b) |
计算 a 的 b 次幂 | Math.pow(2,3) → 8.0 |
Math.sqrt(double a) |
开平方 | Math.sqrt(16) → 4.0 |
07:逻辑运算符 + 位运算符
1. 逻辑运算符(布尔运算核心)
用于处理布尔值之间的逻辑关系,分为短路逻辑 与普通逻辑两类,是条件判断的基础:
| 运算符 | 名称 | 运算规则 | 短路特性 | 示例(boolean a=true, b=false) | ||||
|---|---|---|---|---|---|---|---|---|
&& |
短路与 | 两边为 true 则结果为 true | 左边为 false,右边不执行 | a&&b → false(b 不执行) |
||||
| ` | ` | 短路或 | 两边为 false 则结果为 false | 左边为 true,右边不执行 | `a | b` → true(b 不执行) | ||
! |
非 | 取反(true 变 false,false 变 true) | 无 | !a → false |
||||
& |
普通与 | 两边为 true 则结果为 true | 无短路,两边都执行 | a&b → false(b 执行) |
||||
| ` | ` | 普通或 | 两边为 false 则结果为 false | 无短路,两边都执行 | `a | b` → true(b 执行) | ||
^ |
异或 | 相同为 false,不同为 true | 无 | a^b → true |
2. 位运算符(二进制底层运算)
直接操作整数的二进制位,效率极高,适用于底层性能优化场景,核心运算符如下:
| 运算符 | 名称 | 运算规则(以 int a=3 (0011), b=5 (0101) 为例) | 结果 | ||
|---|---|---|---|---|---|
& |
按位与 | 对应位都为 1,结果为 1,否则为 0 | a&b=1(0001) |
||
| ` | ` | 按位或 | 对应位有 1,结果为 1,否则为 0 | `a | b=7(0111)` |
^ |
按位异或 | 对应位不同为 1,相同为 0 | a^b=6(0110) |
||
~ |
按位取反 | 0 变 1,1 变 0(补码运算) | ~a=-4 |
||
<< |
左移 | 各二进制位全部左移,高位丢弃,低位补 0 | a<<1=6(0110)(等价于 * 2) |
||
>> |
右移 | 各二进制位右移,正数高位补 0,负数补 1 | a>>1=1(0001)(等价于 / 2) |
||
>>> |
无符号右移 | 右移后高位统一补 0 | 负数右移结果为正数 |
💡 实用技巧:左移 / 右移运算效率远高于乘除 2,底层优化优先使用位运算。
08:三元运算符 + 语法小结
1. 三元运算符(简化条件判断)
三元运算符是if-else的简化形式,语法简洁,适用于简单的二选一逻辑:
-
语法格式 :
条件表达式 ? 表达式1 : 表达式2 -
执行逻辑 :条件为
true,执行表达式 1;为false,执行表达式 2。 -
示例 :
int score = 85; String result = score >= 60 ? "及格" : "不及格"; System.out.println(result); // 输出:及格
⚠️ 注意:表达式 1 和 2 需为同类型(或可自动转换),不可嵌套过深,否则降低代码可读性。
2. 运算符语法小结(易混点梳理)
- 运算符优先级:单目运算 > 算术运算 > 关系运算 > 逻辑运算 > 三元运算 > 赋值运算;
- 括号
()可强制提升优先级,是解决运算混乱的核心手段; - 赋值运算(
=)与比较运算(==)需严格区分,避免赋值符误用于条件判断。
09:包机制(代码组织规范)
包机制是 Java 用于分类管理类、避免命名冲突的核心机制,是大型项目开发的基础规范。
1. 包的定义与命名
-
定义 :使用
package关键字声明包,必须放在 Java 文件的第一行(注释除外); -
命名规范 :遵循小写字母 + 公司域名倒序 原则,避免使用关键字,如
com.xxx.util、cn.xxx.entity; -
示例 :
package com.javabase.operator; // 声明当前类所属包
2. 包的导入与使用
- 导入包 :使用
import关键字导入指定类或整个包,简化类名引用;- 导入单个类:
import java.util.Scanner; - 导入整个包:
import java.util.*;(不推荐过度使用,易引发类名冲突)
- 导入单个类:
- 静态导入 :导入静态成员(方法 / 常量),可直接调用(需谨慎使用);
- 示例:
import static java.lang.Math.*;→ 可直接调用abs()、random()等
- 示例:
- 包的访问权限 :结合
public/default/protected/private,控制类、成员的访问范围。
3. 包的本质
包在物理上对应文件系统的目录结构 ,如com.xxx.Operator类,对应文件路径为com/xxx/Operator.java。
10:JavaDoc 生成文档(代码规范化必备)
JavaDoc 是 Java 官方提供的文档生成工具,可通过代码中的注释自动生成标准化 API 文档,是专业开发的必备技能。
1. 注释规范(文档生成基础)
JavaDoc 仅识别多行注释/** ... */和 文档注释/** ... */,需按规范编写:
- 类注释:放在类上方,描述类功能、作者、版本等;
- 方法注释:放在方法上方,描述功能、参数、返回值、异常等;
- 成员注释:放在成员变量上方,描述变量含义。
2. 常用注释标签
| 标签 | 作用 | 示例 |
|---|---|---|
@author |
标注作者 | @author 张三 |
@version |
标注版本 | @version 1.0 |
@param |
描述方法参数 | @param num 输入的整数 |
@return |
描述返回值 | @return 计算结果 |
@throws |
描述抛出异常 | @throws Exception 异常说明 |
@since |
标注支持的 JDK 版本 | @since JDK 1.8 |
3. JavaDoc 生成步骤
- 编写规范的文档注释;
- 使用命令行或 IDE 生成文档:
-
命令行方式:
javadoc -d doc -author -version com.javabase.Operator.java-d doc:指定生成文档的输出目录为doc;-author/-version:保留作者和版本信息;
-
IDE 方式(IDEA):右键类 →
Generate→JavaDoc→ 配置输出路径,点击OK。
-
4. 生成文档效果
生成的文档为 HTML 格式,包含类结构、方法详情、参数说明等,可直接在浏览器打开,与 JDK 官方 API 文档格式一致。