Java ---变量、常量、类型转换、默认值、重载、标识符、输入输出、访问修饰符、泛型、迭代器

一、变量与常量

变量是程序中可变化的存储单元,常量则是初始化后不可修改的值,二者共同构成了程序数据存储的核心。

(一)变量的核心要素与声明

  1. 变量三要素:变量名、变量类型、作用域。

  2. 声明规则:Java 是强类型语言,每个变量必须先声明类型再使用,声明格式为:

    java 复制代码
    数据类型 变量名 [= 值]; // 可逗号分隔声明多个同类型变量
    // 示例:
    int age = 18; // 声明int类型变量age并赋值
    double height, weight = 60.5; // 声明double类型的height和weight,仅weight赋值
  3. 注意事项:

    • 变量类型可分为基本类型(如 int、double)和引用类型(如 String)。
    • 变量名必须是合法标识符(不能以数字开头、不能是关键字等)。
    • 变量声明是完整语句,必须以分号结尾。

(二)变量的作用域与生命周期

Java 变量的作用域分为 3 类,不同作用域的变量生命周期和访问规则不同:

作用域类型 定义位置 特点 & 访问方式 生命周期 示例代码
类变量(静态变量) 类内部、方法外 用 static 修饰,属于类,可通过类名或对象访问 类加载时创建,类卸载时销毁 static int allClicks = 0;
实例变量(对象变量) 类内部、方法外 属于对象,需创建对象后通过对象访问 对象创建时创建,对象不可用时销毁 String str = "hello world";
局部变量 方法 / 代码块内 仅在所在代码块内有效,不能用访问修饰符修饰 从定义处开始,到包围它的}结束 方法内写int i = 0;

(三)常量的定义与规范

  1. 定义:用final关键字修饰,初始化后程序运行中不可修改的值。
  2. 声明格式:final 数据类型 常量名 = 值
  3. 命名规范:常量名一般用大写字母 + 下划线
  4. 类常量:staticfinal可组合修饰类常量,属于类级别的常量,顺序可互换

(四)变量与常量的命名规范

核心原则:见名知意,遵循行业通用规范:

命名对象 规范 示例
类成员变量 首字母小写 + 驼峰原则 monthSalary、lastName
局部变量 首字母小写 + 驼峰原则 studentAge、totalScore
常量 大写字母 + 下划线 MAX_VALUE、PI
类名 首字母大写 + 驼峰原则 Man、GoodMan
方法名 首字母小写 + 驼峰原则 run()、runRun()

二、数据类型

分为基本类型和引用类型

(一)分类与特点

类型分类 定义特点 包含类型
基本类型 直接存储值,无 null 状态 byte、short、int、long、float、double、char、boolean
引用类型 存储对象的内存地址,可赋值 null 1. 类(自定义类、包装类);2. 数组;3. 字符串

(二)包装类与基本类型的对应关系

包装类是基本类型对应的引用类型,可实现基本类型与引用类型的灵活转换,对应关系如下:

基本类型 对应的包装类(引用类型)
byte Byte
short Short
int Integer
long Long
float Float
double Double
char Character
boolean Boolean

(三)引用类型的空指针异常

当引用类型变量的值为null时,调用其方法或访问其字段,会抛出NullPointerException(空指针异常),需避免在变量为null时进行相关操作。

(四)默认值

变量只定义不赋值时,会拥有默认值,局部变量无默认值,必须手动初始化后才能使用:

数据类型 明细 默认值
基本类型 byte、short、int、long 0
float、double 0.0
boolean false
引用类型 类、接口、数组、String null

三、类型转换

类型转换分为基本类型转换、包装类与基本类型转换、引用类型转换及其他类型转换

(一)基本类型转换

基本类型转换基于数据范围大小,分为隐式转换和强制转换,转换方向通过类型范围箭头示意

  1. 隐式转换(自动转换)

    • 规则:顺箭头方向(小范围→大范围),无需手动干预,编译器自动完成。

    • 示例

      java 复制代码
      byte a = 10;
      int b = a; // byte自动转int(小范围→大范围)
  2. 强制转换

    • 规则:逆箭头方向(大范围→小范围),需在待转换对象前加(目标类型)

    • 注意:可能导致精度丢失或数值溢出,需谨慎使用。

    • 示例:

      java 复制代码
      int c = 1000;
      byte d = (byte) c; // int强制转byte(大范围→小范围),可能溢出
  3. 特殊说明:boolean 类型不能与任何其他基本类型进行转换。

(二)包装类型与基本类型转换

包装类与对应的基本类型之间可自由转换,Java 提供自动装箱和自动拆箱机制,无需手动调用转换方法。

  1. 自动装箱:基本类型→包装类示例:Integer b = 10;(int 类型自动转为 Integer 包装类)

  2. 自动拆箱:包装类→基本类型示例:

    java 复制代码
    Integer c = 10;
    int d = c; // Integer包装类自动转为int基本类型

(三)引用类型之间的转换

引用类型转换的核心是基于继承或实现关系(is a关系),分为向上转型和向下转型。

  1. 转换前提转换的对象和目标类型之间必须符合「是一个」的继承 / 实现关系

3.非法转换场景

  • 无「is a」关系的类型转换:Appliance c = new Cat();(Cat 和 Appliance 无继承关系,编译不通过)。
  • 强制转换实际类型不匹配:Dog d = (Dog) a;(a 实际是 Cat 对象,运行时抛出ClassCastException)。
  1. 类型检查工具(避免转换异常)
  • getClass():获取对象的实际类型,查看引用变量背后真正的对象类型

    java 复制代码
    System.out.println(a.getClass()); // 输出 class Cat(a实际是Cat对象)
    System.out.println(b.getClass()); // 输出 class Cat(b实际是Cat对象)
  • instanceof:检查对象是否是某类型(或其子类)的实例,避免ClassCastException

    java 复制代码
    System.out.println(a instanceof Cat);   // true(a是Cat对象)
    System.out.println(a instanceof Dog);   // false(a不是Dog对象)
    System.out.println(b instanceof Animal); // true(b是Cat,Cat是Animal的子类)
  1. 转型的作用
  • 统一管理子类对象:用父类数组存储不同子类对象

  • 方法参数统一接收子类对象:用父类类型作为方法参数,接收任意子类对象,示例:

    java 复制代码
    static void test(Animal animal) {
        // 方法内可统一处理Cat、Dog等Animal子类对象
    }
    test(new Cat()); // 自动向上转型
    test(new Dog()); // 自动向上转型

(四)其他类型转换

当类型转换不属于上述场景时,需借助专门的转换方法实现,典型示例为 String 与基本类型的转换。

示例:String 转 int

  • 方法:Integer.parseInt(字符串)(将字符串形式的数字转为 int 类型)
java 复制代码
String a = "1";
String b = "2";
// String转int后进行加法运算
System.out.println(Integer.parseInt(a) + Integer.parseInt(b)); // 输出3(数值相加)
// 字符串的加法=拼接字符串
System.out.println(a + b); // 输出"12"(字符串拼接)

四、方法

(一)方法的组成与语法结构

方法由方法头方法体两部分组成,完整语法结构如下:

java 复制代码
修饰符 返回值类型 方法名(参数类型 参数名) {
    // 方法体:具体功能实现代码
    return 返回值; // 无返回值时可省略,或写return;
}

(二)调用规则

方法调用需根据是否有返回值、是否为静态方法区分:

1.按返回值区分调用方式有返回值:调用可作为一个值赋值给变量,或直接参与运算

2.按是否为静态方法

静态方法(带 static 修饰符):直接通过类名.方法名()调用,无需创建对象

非静态方法(无 static 修饰符):必须先实例化类(创建对象),再通过对象名.方法名()调用

3.类成员访问规则

非静态成员(字段、方法):只能通过对象访问

静态成员(字段、方法):可通过类名或对象访问

调用限制:静态方法不能调用非静态方法;

非静态方法可调用非静态方法和静态方法

五、构造器(构造方法)

(一)构造器的核心特点

  1. 名称必须与所属类的名称完全相同
  2. 没有返回值,且不能写 void 关键字

(二)构造器的作用

  1. new关键字的本质是调用构造器,通过构造器创建对象实例
  2. 初始化对象的属性(如给字段赋值)

(三)构造器的重要注意点

  1. 若类中未自定义任何构造器,编译器会自动生成一个无参、空方法体的缺省构造方法
  2. 若类中定义了有参构造器,编译器将不再生成缺省构造方法。此时若需使用无参构造方法创建对象,必须手动定义无参构造器
  3. 构造器的核心功能仅为初始化类的成员变量,不能用于其他业务逻辑

六、方法重载

(一)方法重载的规则

  1. 方法名称必须完全相同。
  2. 参数列表必须不同(满足任一条件即可):参数个数不同、参数类型不同、参数排列顺序不同
  3. 返回值类型可相同可不同,不影响重载判定
  4. 仅返回值类型不同,不能构成重载(编译器会报错)

(二)重载的实现原理

当调用重载方法时,编译器会根据传入的实参个数、类型、顺序等信息,自动匹配对应的方法。若未找到匹配的方法,编译器将抛出错误。

(三)示例

java 复制代码
public class MethodOverloadDemo {
    // 重载1:两个int类型求和
    public static int sum(int a, int b) {
        return a + b;
    }

    // 重载2:三个int类型求和(参数个数不同)
    public static int sum(int a, int b, int c) {
        return a + b + c;
    }

    // 重载3:两个double类型求和(参数类型不同)
    public static double sum(double a, double b) {
        return a + b;
    }

    // 重载4:参数顺序不同(int+String → String+int)
    public static void showInfo(int num, String str) {
        System.out.println("数字:" + num + ",字符串:" + str);
    }

    public static void showInfo(String str, int num) {
        System.out.println("字符串:" + str + ",数字:" + num);
    }

    // 错误示例:仅返回值不同,不能构成重载(编译器报错)
    // public static double sum(int a, int b) {
    //     return a + b;
    // }

    public static void main(String[] args) {
        System.out.println(sum(10, 20)); // 匹配sum(int,int) → 输出30
        System.out.println(sum(10, 20, 30)); // 匹配sum(int,int,int) → 输出60
        System.out.println(sum(1.5, 2.5)); // 匹配sum(double,double) → 输出4.0
        showInfo(100, "Java"); // 匹配showInfo(int,String) → 输出:数字:100,字符串:Java
        showInfo("Java", 100); // 匹配showInfo(String,int) → 输出:字符串:Java,数字:100
    }
}

七、标识符

标识符是用于命名类、方法、变量、常量等的名称,必须遵循严格的命名规则,否则编译器会报错

(一)标识符的核心规则

  1. 不能使用 Java 中的关键字(如 public、class、static 等)作为标识符。
  2. 首字符只能是字母(A-Z、a-z)、美元符($)或下划线(_),不能以数字或 #等特殊字符开头。
  3. 首字符之后可以是字母、美元符($)、下划线(_)或数字的任意组合。
  4. 标识符区分大小写(如 age 和 Age 是两个不同的标识符)。

(二)命名建议

  1. 不建议使用中文或拼音命名,可读性差且不符合行业规范。
  2. 类名采用帕斯卡命名法(首字母大写,如 UserInfo)。
  3. 方法名、变量名采用驼峰命名法(首字母小写,后续单词首字母大写,如 getUserName)。
  4. 常量名全部大写,多个单词用下划线分隔(如 MAX_NUM)。

八、输入与输出

(一)Scanner 类常用输入方法

Scanner 类需导入java.util.Scanner包,常用输入方法如下:

  1. nextInt():接收一个 int 类型整数。
  2. nextLong():接收一个 long 类型整数。
  3. nextFloat():接收一个 float 类型小数。
  4. nextDouble():接收一个 double 类型小数。
  5. next():接收不带空格的字符串(遇到空格、回车即停止)。
  6. nextLine():接收带空格的整段字符串(直到回车结束)。

(二)输入方法差异说明

next():仅读取空格前的内容,无法接收包含空格的字符串(

nextLine():读取从当前位置到回车前的所有内容,支持包含空格的字符串

(三)输出方法

常用输出方法为System.out.println()(输出内容后换行)和System.out.print()(输出内容后不换行)

java 复制代码
System.out.println("Hello Java"); // 输出后换行
System.out.print("Hello ");
System.out.print("World"); // 输出结果为"Hello World"(不换行)

九、访问修饰符

访问修饰符用于控制类、字段、方法的访问权限,是实现封装性的核心手段,Java 中常用的访问修饰符有 4 种

(一)常用访问修饰符及访问范围

修饰符 可修饰对象 当前类 同包类 不同包子类 不同包非子类
private 字段、方法
default(无修饰符) 字段、方法、类
protected 字段、方法
public 字段、方法、类

(二)重要注意点

  1. 局部变量(方法内部定义的变量)不能使用任何访问修饰符修饰。
  2. protected 修饰的成员,在不同包子类中,仅能通过子类对象或 this 关键字访问,不能直接通过父类对象访问。
  3. 访问范围优先级:private < default < protected < public。

(三)使用原则

为保证代码的封装性和安全性,建议尽可能缩小访问范围:

  1. 字段优先设置为 private(仅当前类可访问,通过 getter/setter 方法对外暴露访问)。
  2. 子类需要访问的父类成员,设置为 protected。
  3. 对外提供的公共功能(如工具方法),设置为 public。
  4. 无需对外暴露的成员,使用 default 或 private 修饰。

十、泛型

泛型是 Java 的重要特性,核心作用是在编译阶段检查数据类型的安全性,同时避免程序中大量的类型强制转换,让代码更简洁

(一)泛型的核心优势

  1. 类型安全:编译器在编译期就可以校验集合、方法的入参类型是否匹配,杜绝运行时的类型转换异常。
  2. 消除强制转换:使用泛型声明的集合 / 对象,获取元素时无需手动强转,编译器自动完成类型匹配。
  3. 代码复用:一套泛型代码可以适配多种数据类型,无需为不同类型重复编写逻辑一致的代码。

(二)泛型的基础使用格式

泛型使用尖括号 <> 声明,里面写需要限定的引用数据类型,核心使用场景包含 2 类:

  1. 集合中使用泛型(最常用):指定集合只能存储某一种类型的数据
java 复制代码
// 限定ArrayList只能存储String类型,编译期校验,不能存入其他类型
ArrayList<String> strList = new ArrayList<>();
// 限定HashMap的键为String,值为Integer
HashMap<String, Integer> map = new HashMap<>();
  1. 自定义泛型方法 / 泛型类:让方法 / 类支持任意指定的引用类型
java 复制代码
// 泛型方法:可以对任意类型的数组进行遍历
public <T> void printArray(T[] arr) {
    for (T t : arr) {
        System.out.print(t + " ");
    }
}

(三)泛型的核心注意事项

  1. 泛型只作用于编译阶段,运行阶段泛型的类型约束会被擦除,这一特性称为「泛型擦除」。
  2. 泛型只能限定引用数据类型,不能使用基本数据类型(int、double 等),如需使用基本类型,需用对应的包装类(Integer、Double)。
  3. 泛型的上下限:可以通过 <? extends 父类> 限定泛型的上限、<? super 子类> 限定泛型的下限,精准控制类型范围。

十一、迭代器

迭代器(Iterator)是 Java 提供的集合元素遍历工具,定义了统一的遍历规范,适用于所有的 Collection 系列集合(ArrayList、HashSet、LinkedList 等),是遍历集合的标准方式。

(一)迭代器的核心优势

  1. 遍历方式统一:无论哪种集合,都可以使用完全相同的迭代器遍历代码,无需根据集合类型调整遍历逻辑。
  2. 解耦遍历与集合:迭代器封装了集合的遍历细节,我们无需关心集合的底层实现(数组 / 链表),只需调用迭代器方法即可。
  3. 安全遍历:迭代器遍历过程中,通过自身的 remove () 方法删除元素不会触发并发修改异常,比普通 for 循环更安全。

(二)迭代器的核心方法

所有迭代器都实现了 java.util.Iterator 接口,核心只有 3 个方法:

  1. boolean hasNext() :判断集合中是否还有下一个可遍历的元素,有则返回 true,无则返回 false。
  2. E next() :获取集合中的下一个元素,返回值为泛型指定的元素类型。
  3. void remove() :删除迭代器当前指向的元素,可选方法。

(三)迭代器的标准使用格式

java 复制代码
// 1. 创建集合并添加元素
Collection<String> coll = new ArrayList<>();
coll.add("Java基础");
coll.add("方法与构造器");
coll.add("泛型与迭代器");

// 2. 获取集合的迭代器对象
Iterator<String> it = coll.iterator();

// 3. 循环遍历:先判断,再获取
while(it.hasNext()){
    String str = it.next();
    System.out.println(str);
}

(四)迭代器的使用注意事项

  1. 迭代器遍历是单向的,只能从集合头部遍历到尾部,不能倒序遍历
  2. 调用next()方法前,必须先调用hasNext()判断,否则没有元素时会抛出NoSuchElementException
  3. 增强 for 循环(foreach)的底层就是迭代器实现,本质上是迭代器的语法
相关推荐
唐叔在学习2 小时前
Python自动化指令进阶:UAC提权
后端·python
12344522 小时前
【面试复盘】有了equals为什么还要hashcode
java·后端
lsx2024062 小时前
Vue3 自定义指令
开发语言
牛奔2 小时前
Go语言中结构体转Map优雅实现
开发语言·后端·macos·golang·xcode
毕设源码-邱学长2 小时前
【开题答辩全过程】以 台球俱乐部管理系统为例,包含答辩的问题和答案
java·eclipse
wujj_whut2 小时前
【Conda实战】从0到1:虚拟环境创建、多Python版本管理与环境切换全指南
开发语言·python·conda
蜗牛^^O^2 小时前
java中的JUC
java·开发语言
张心独酌3 小时前
Rust新手练习案例库- rust-learning-example
开发语言·后端·rust
geoqiye3 小时前
2026官方认证:贵阳宠物行业短视频运营TOP5评测
大数据·python·宠物