Day11 --【Java全栈】方法 (下)
2026/7/11 22:09:14 网站建设 项目流程

全景定位(先在脑子里放一张地图)

Java 是面向对象的语言,所有代码都写在「类」里面。你可以把一个类理解成一个功能盒子,每个盒子里只装两样东西:

  1. 属性:盒子里存的数据(比如用户盒子里存姓名、年龄)

  2. 方法:盒子能做的事情(比如用户盒子能修改姓名、计算年龄)

简单说:属性是存东西的,方法是干活的,我们写 Java 代码,绝大多数时候都是在写方法。

1. 两大核心特性

1.1 方法签名

💡通俗理解

就像人的身份证号,是区分不同方法的唯一标识。名字+参数类型不一样,才是不同的方法。

🔴记忆:定义

JVM 区分方法的唯一标识 =方法名 + 参数类型列表

返回值、修饰符、抛出的异常,都不算方法签名。

误区:参数名不影响签名。

比如add(int a, int b)add(int x, int y)是完全相同的方法,不能同时存在,会编译报错。

1.2 方法重载(Overload)

💡通俗理解

同一个菜谱名“煎蛋”,可以有不同版本:煎1个蛋、煎2个蛋、用鸭蛋煎。你喊“煎蛋”时,厨师会根据你递的原料自动选对应版本。

🔴 记忆:定义

同一个类中,方法名相同,参数列表不同,就叫方法重载。和返回值、修饰符没有关系。

参数列表不同只有3种合法情况:

  1. 参数个数不同:add(int a)add(int a, int b)

  2. 参数类型不同:add(int a)add(double a)

  3. 参数类型顺序不同:add(int a, String b)add(String b, int a)

误区

  • 只改参数名、只改返回值,都不算重载,会直接编译报错。

1.3 方法重写(Override)

💡通俗理解

总店有一份“珍珠奶茶”的标准菜谱(父类方法),分店(子类)觉得不够甜,不改名、不改原料,只调整糖量和做法,做出分店版珍珠奶茶。顾客点单时,拿到的是对应分店的版本。

🟡进阶理解:定义

父子类继承关系中,子类写一个和父类方法名、参数列表完全一致的方法,覆盖父类的原有逻辑,这就是方法重写。它是面向对象「多态」的核心实现。

重写规则:两同两小一大

  • 两同:方法名相同、参数列表完全相同

  • 两小

    • 返回值类型兼容:基本类型必须完全一样;引用类型可以是父类返回类型的子类(比如父类返回Number,子类返回Integer)

    • 抛出的异常范围小于等于父类(只针对受检异常)

  • 一大:子类方法的访问权限,不能比父类更严格(父类是public,子类不能是private)

误区

  • private方法、static方法都不能被重写,子类写同名方法只是自己的新方法,不是重写。


2. 参数传递机制:值传递

💡通俗理解

  • 基本类型:你把菜谱复印一份给朋友,朋友在复印件上改,你的原件完全不变。

  • 引用类型:你给朋友一张仓库地址纸条(复印件)。朋友去仓库改了货物包装 → 仓库里的东西真变了;但朋友把纸条改成另一个仓库地址 → 你手里的纸条完全不变。

🔴 记忆:核心规则

Java 里只有值传递,没有引用传递,所有参数传的都是「副本」,只是不同类型的副本内容不一样:

  1. 基本类型参数:传的是数值的副本。方法里改参数值,完全不影响外面的原变量。

  2. 引用类型参数:传的是对象内存地址的副本。

    1. 方法内修改对象的内部属性 → 会影响外面的原对象(因为指向同一个内存)

    2. 方法内把参数重新赋值为新对象(new)→ 完全不影响外面的原引用(改的只是副本的地址)

🟡进阶补充:不可变类的特殊情况

StringInteger等不可变类,即使是引用类型,方法内“修改”也不会影响外部。

本质:不可变对象本身不能改,方法里的“修改”其实是让形参指向了新对象,属于「改指向」,不是「改内容」,完全符合值传递规则。

public void test(String s) { s = "新字符串"; // 形参指向了新对象,和外面的原引用无关 }

3. 可变参数(Varargs)

💡通俗理解

就像点菜时“随便加几个小菜”,你可以加0个、1个、5个,后厨用一个托盘(数组)全部装起来给你处理。

🔴记忆

  • 语法参数类型... 参数名,比如int... nums

  • 本质:底层就是数组,方法里可以完全当数组用

  • 3条硬规则

    • 一个方法最多只能有一个可变参数

    • 必须放在参数列表的最后一位

    • 调用时可以传0个、1个、多个,也可以直接传数组

🟡进阶:重载匹配优先级

如果同时有「固定参数方法」和「可变参数方法」,会优先匹配固定参数的,可变参数是兜底的。

public void method(int a) {} // 优先匹配这个 public void method(int... a) {} // 固定参数匹配不上才走这个

误区

不能和同类型数组参数构成重载,比如method(int... nums)method(int[] nums)签名相同,会编译报错。


4. 两类特殊方法

4.1 构造方法

💡通俗理解

品牌奶茶店加盟。每开一加盟家新店(new对象),都要按模板装修、安装设备、招员工,完成初始化。

🔴记忆

  • 作用:专门用来创建、初始化对象,new对象时会自动调用

  • 核心规则

    • 方法名必须和类名完全一样,大小写都不能错

    • 不能写任何返回值类型,连 void 都不能写,写了就变成普通方法

    • 没手动写构造方法时,编译器会自动生成一个无参的默认构造方法;只要手动写了一个,默认的就消失了

    • 构造方法可以重载,用不同参数创建不同初始状态的对象

🟡进阶补充

构造方法可以用private修饰,作用是禁止外面new对象,只能在类内部创建,典型应用是单例模式。

4.2 main 方法

🔴记忆

  • 作用:Java 程序的唯一入口,JVM 启动程序时会自动找它执行

  • 固定格式,一个字都不能错

public static void main(String[] args)
  • public:JVM 要全局访问,必须公开

  • static:JVM 调用时还没创建对象,必须属于类本身

  • void:入口不需要给 JVM 返回值

  • String[] args:命令行参数,可以在运行程序时传字符串进去


5. 静态方法 vs 实例方法

💡通俗理解

  • 静态方法:街边公共电话亭,不需要有房子(对象),谁都能直接打

  • 实例方法:你家座机,必须先有房子(对象),才能用里面的电话

维度

静态方法(static修饰)

实例方法(无static)

归属

属于类本身

属于对象实例

调用方式

直接类名.方法名()调用

必须先new对象,通过对象调用

能访问的内容

只能直接访问静态成员;不能用this/super

所有成员都能直接访问

加载时机

类加载时就存在

对象创建时才存在

🟡进阶理解:为什么静态方法不能被重写

二者绑定机制不同:

  • 静态方法:静态绑定(编译期就确定),看变量的声明类型

  • 实例方法:动态绑定(运行时才确定),看对象的实际类型

代码验证:

class Father { public static void staticMethod() { System.out.println("父类静态方法"); } public void instanceMethod() { System.out.println("父类实例方法"); } } class Son extends Father { public static void staticMethod() { System.out.println("子类静态方法"); } @Override public void instanceMethod() { System.out.println("子类实例方法"); } } // 测试 Father f = new Son(); f.staticMethod(); // 输出:父类静态方法(看声明类型Father) f.instanceMethod(); // 输出:子类实例方法(看实际类型Son)

6. 方法在 JVM 中的执行过程

🟢底层原理:入门阶段可跳过,不影响写代码

💡通俗理解

每次做菜,厨房分配一张临时操作台(栈帧),上面摆原料、草稿纸。菜做好后端出去,操作台就清空腾给下一道菜。

每次调用方法,JVM 都会在虚拟机里创建一个「栈帧」压入栈顶,栈帧包含4部分:

  1. 局部变量表:存方法的参数、局部变量

  2. 操作数栈:做运算的临时空间

  3. 动态链接:定位方法的内存地址

  4. 返回地址:方法执行完回到调用方的位置

方法执行完,栈帧就出栈销毁,内存自动释放。

⚠️ 注意:递归层级太深,栈帧太多超过栈容量,就会抛出StackOverflowError栈溢出错误。

7. 方法设计最佳实践

🟡进阶理解:写代码久了自然会有体会,入门先了解即可

💡通俗理解

好菜谱一页纸写完,步骤清晰不跳跃;原料别太多,容易搞混;过敏原标清楚,名字一看就懂。

  1. 单一职责:一个方法只做一件事

  2. 短小精悍:尽量控制在50行以内,太长就拆分

  3. 参数精简:参数不超过5个,太多就封装成对象

  4. 防御式校验:入口处校验参数合法性,提前拦截非法数据

  5. 见名知意:动词开头,不用拼音和不明缩写

  6. 分支全覆盖:有返回值的方法,所有执行分支都要有return


8. 核心红线汇总表(复习专用)

坑点

详细说明

返回值不算方法签名

不能靠返回值不同做方法重载,直接编译报错

private方法不能重写

子类看不到父类私有方法,同名只是子类自己的新方法

静态方法不能重写

静态绑定,子类同名只是隐藏父类方法,没有多态

构造方法不能加返回值

连void都不能加,加了就变成普通方法

Java只有值传递

引用类型传的是地址副本,重新赋值不影响外部原引用

抽象方法没有方法体

连大括号都不能有,必须分号结尾;有抽象方法的类必须是抽象类

this()/super()必须在构造方法首行

调用本类/父类构造方法必须放第一行,二者不能同时用

return之后不能写代码

属于不可达代码,直接编译报错

静态方法不能用this/super

静态方法不依赖对象,this代表当前对象,逻辑冲突

接口方法默认public abstract

不写修饰符也是公共抽象的;Java 9之后才支持私有方法


ps:我会比较喜欢今天的这种风格,本身学习对于普通人来讲就是一件不容易的事情,是否容易理解还是很重要的,不懂的术语结合起来去解释另外一个术语,真的会打击学习者的兴趣!

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询