6. Java 方法
方法的定义
方法是一段封装特定功能的、可重复调用的代码块。
语法格式:
修饰符 返回值类型 方法名(参数类型 形参1, 参数类型 形参2, ...) {
方法体
return 返回值;
}
各组成部分说明:
|
组成部分 |
说明 |
|
修饰符 |
控制访问权限和调用方式,如 |
|
返回值类型 |
方法返回结果的数据类型;无返回值用 |
|
方法名 |
小驼峰命名,见名知意 |
|
参数列表 |
形式参数(形参),多个用逗号分隔;无参数则留空 |
|
方法体 |
实现功能的具体代码 |
|
|
结束方法执行并返回结果; |
示例:
public static int getMax(int num1, int num2) {
if (num1 > num2) {
return num1;
} else {
return num2;
}
}
int max = getMax(10, 20); // max = 20
方法定义后不会自动执行,必须通过 方法名(实参) 显式调用。
方法的分类
按是否有参数和是否有返回值,方法分为四类:
|
分类 |
声明示例 |
调用方式 |
|
无参无返回值 |
|
|
|
无参有返回值 |
|
|
|
有参无返回值 |
|
|
|
有参有返回值 |
|
|
形参和实参
- 形参:方法定义时括号中的变量,是占位符
- 实参:调用方法时传入的具体值
要求:实参的类型、数量、顺序必须与形参一致,否则编译报错。
public static int add(int num1, int num2) { // num1、num2 是形参
return num1 + num2;
}
add(10, 20); // 10、20 是实参
add(a, 3); // 实参可以是变量
add(2 + 3, a * 2); // 实参可以是表达式
方法重载
规则
同一个类中,方法名相同、参数列表不同,构成方法重载。
|
判断条件 |
说明 |
|
方法名 |
必须相同 |
|
参数个数 |
不同即构成重载 |
|
参数类型 |
不同即构成重载 |
|
参数顺序 |
不同即构成重载(如 |
与返回值类型无关,与参数名无关。
以下写法不构成重载,会编译报错:
// 编译错误:仅返回值类型不同
public static int add(int a, int b) { return a + b; }
public static double add(int a, int b) { return a + b; }
// 编译错误:仅参数名不同
public static int add(int a, int b) { return a + b; }
public static int add(int x, int y) { return x + y; }
原因:add(1, 2) 调用时编译器无法根据返回值判断目标方法。
重载匹配顺序
编译器按以下优先级匹配重载方法:
- 精确类型匹配
- 自动类型提升(
byte→short→int→long→float→double) - 自动装箱/拆箱
- 可变参数(优先级最低)
public static void test(long a) { System.out.println("long"); }
public static void test(double a) { System.out.println("double"); }
test(10); // 输出 "long":int → long 比 int → double 更近
重载示例
public class OverloadDemo {
public static int add(int a, int b) {
return a + b;
}
public static double add(double a, double b) { // 参数类型不同
return a + b;
}
public static int add(int a, int b, int c) { // 参数个数不同
return a + b + c;
}
public static double add(int a, double b) { // 参数顺序不同
return a + b;
}
}
值传递
Java 只有一种参数传递方式:值传递。实参将自身的值复制一份传给形参,方法内对形参的修改不影响实参。
"值"的含义取决于实参类型:
|
实参类型 |
传递的值 |
方法内修改的影响 |
|
基本类型 |
数据值本身 |
不影响实参 |
|
引用类型 |
堆内存地址的副本 |
修改地址本身不影响实参;修改地址指向的对象内容会影响原对象 |
基本类型
public static void change(int x) {
x = 100; // 修改的是副本
}
int a = 10;
change(a);
System.out.println(a); // 10,不受影响
引用类型:修改对象内容
public static void changeContent(int[] arr) {
arr[0] = 100; // arr 与实参指向同一对象
}
int[] a = {1, 2};
changeContent(a);
System.out.println(a[0]); // 100,原数组内容被修改
引用类型:修改引用本身
public static void changeRef(int[] arr) {
arr = new int[]{3, 4}; // arr 指向新对象,不影响实参
}
int[] a = {1, 2};
changeRef(a);
System.out.println(a[0]); // 1,原数组未受影响
方法调用内存模型
JVM 内存分区
|
内存区域 |
作用 |
|
栈(Stack) |
每个线程独享,存储方法调用栈帧(局部变量、形参、返回地址)。方法调用入栈,执行完毕出栈 |
|
堆(Heap) |
所有线程共享,存储对象实例和数组。栈中的引用变量存储的是堆地址 |
方法调用流程
public static int add(int x, int y) {
int result = x + y;
return result;
}
public static void main(String[] args) {
int a = 10;
int b = 20;
int sum = add(a, b);
}
执行步骤:
main入栈:栈帧中存储a=10、b=20- 调用
add(a, b):a=10、b=20的值复制给形参x、y;add栈帧入栈,计算result=30 add出栈:return 30将结果传给main的sum;add栈帧弹出main出栈:程序结束
递归
方法调用自身的写法,须满足两个条件:
- 有递归出口(终止条件)
- 每次递归调用,问题规模缩小
public static int factorial(int n) {
if (n == 1) return 1; // 递归出口
return n * factorial(n - 1); // 问题规模缩小
}
递归层级过深会导致栈帧无限堆积,抛出 StackOverflowError。
基本类型与引用类型
|
对比维度 |
基本类型(8种) |
引用类型 |
|
存储内容 |
数据值本身 |
堆中对象的地址 |
|
内存位置 |
栈(方法栈帧) |
引用在栈,对象在堆 |
|
默认值 |
对应类型的零值( |
|
|
赋值/传参 |
复制值,互不影响 |
复制地址,修改内容相互影响 |
|
是否可为 |
否 |
是 |
Java 的 8 种基本类型:
|
分类 |
类型 |
占用 |
取值范围 |
|
整数 |
|
1B |
-128 ~ 127 |
|
|
2B |
-32768 ~ 32767 |
|
|
|
4B |
-2³¹ ~ 2³¹-1 |
|
|
|
8B |
-2⁶³ ~ 2⁶³-1 |
|
|
浮点 |
|
4B |
精度 6~7 位 |
|
|
8B |
精度 15~16 位 |
|
|
字符 |
|
2B |
0 ~ 65535 |
|
布尔 |
|
JVM 实现相关 |
|
注意事项
- 方法不能嵌套定义:Java 不允许在一个方法体内定义另一个方法
return执行后方法立即结束,其后代码不会执行(编译可通过但不可达)- 声明了非
void返回值类型的方法,所有执行路径都必须有return语句 - 调用方法时,实参的类型、数量、顺序必须与形参一致
- 引用类型变量值为
null时调用方法或访问属性会抛出NullPointerException
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐



所有评论(0)