在Java编程中,方法就像是你的个人工具箱里的各种工具------锤子用来钉钉子,螺丝刀用来拧螺丝,每个工具都有专门的用途。今天,我们来学习如何创建和使用自己的"编程工具"!
引入:为什么需要方法?
想象一下,你正在写一个学生成绩管理系统: 没有方法的情况:
java
public static void main(String[] args) {
// 计算第一个学生的总分
int score1 = 85;
int score2 = 90;
int score3 = 78;
int total1 = score1 + score2 + score3;
double average1 = total1 / 3.0;
System.out.println("第一个学生平均分:" + average1);
// 计算第二个学生的总分(重复写一遍!)
int score4 = 92;
int score5 = 88;
int score6 = 95;
int total2 = score4 + score5 + score6;
double average2 = total2 / 3.0;
System.out.println("第二个学生平均分:" + average2);
// 计算第三个学生的总分(又重复写一遍!)
// ... 太麻烦了!
}
使用方法的情况:
java
public static void main(String[] args) {
// 只需要调用方法,代码变得超级简洁!
calculateAverage(85, 90, 78, "第一个学生");
calculateAverage(92, 88, 95, "第二个学生");
calculateAverage(76, 85, 90, "第三个学生");
}
// 定义一个计算平均分的方法
static void calculateAverage(int score1, int score2, int score3, String name) {
int total = score1 + score2 + score3;
double average = total / 3.0;
System.out.println(name + "平均分:" + average);
}
看到区别了吗?方法让代码更简洁、更易读、更易维护!
一、方法基础:什么是方法?
1.1 方法的通俗理解
方法(Method) 就是一段有名字的代码块,可以重复使用。你可以把它想象成:
- 一个魔法咒语:念出咒语(调用方法),就会发生特定的魔法效果(执行代码)
- 一个厨房食谱:按照食谱(方法)的步骤,就能做出美味的菜(得到结果)
- 一个数学公式:比如 "圆的面积 = π × r²",这就是一个方法
1.2 方法的组成部分
java
// 访问修饰符 返回值类型 方法名(参数列表) {
// 方法体
// 返回值(如果需要)
// }
public static int add(int a, int b) {
int result = a + b;
return result;
}
二、创建和使用方法
2.1 最简单的无参方法
java
public class SimpleMethod {
public static void main(String[] args) {
System.out.println("=== 最简单的无参方法 ===\n");
// 调用方法:就像喊朋友的名字
sayHello(); // 第一次调用
sayHello(); // 第二次调用
sayHello(); // 可以无限次调用!
}
// 定义一个无参方法:向世界问好
// static:表示这是静态方法,可以在main中直接调用
// void:表示这个方法不返回任何值
// sayHello:方法名(我们自己取的)
static void sayHello() {
System.out.println("你好,Java世界!");
System.out.println("我正在学习Java方法!");
System.out.println("------------------");
}
}
2.2 带参数的方法(让方法更灵活)
java
public class MethodWithParameters {
public static void main(String[] args) {
System.out.println("=== 带参数的方法 ===\n");
// 传递不同的参数,得到不同的结果
greet("小明"); // 向小明问好
greet("小红"); // 向小红问好
greet("李老师"); // 向李老师问好
// 计算不同数字的和
printSum(5, 3); // 计算5+3
printSum(10, 20); // 计算10+20
printSum(100, 200); // 计算100+200
}
// 带一个参数的方法:向指定的人问好
// name:参数,调用时需要传入
static void greet(String name) {
System.out.println("你好," + name + "!");
System.out.println("欢迎来到Java课堂!");
System.out.println();
}
// 带两个参数的方法:计算两个数的和
static void printSum(int a, int b) {
int sum = a + b;
System.out.println(a + " + " + b + " = " + sum);
}
}
2.3 有返回值的方法(方法可以"给出答案")
java
public class MethodWithReturn {
public static void main(String[] args) {
System.out.println("=== 有返回值的方法 ===\n");
// 调用方法并接收返回值
int result1 = add(5, 3); // 调用add方法,得到返回值8
System.out.println("5 + 3 = " + result1);
int result2 = add(10, 20); // 再次调用,得到30
System.out.println("10 + 20 = " + result2);
// 返回值可以直接使用
System.out.println("7 + 8 = " + add(7, 8));
// 使用返回值进行进一步计算
int total = add(1, 2) + add(3, 4) + add(5, 6);
System.out.println("1+2 + 3+4 + 5+6 = " + total);
// 不同类型的方法
boolean isAdult = checkAge(20);
System.out.println("20岁是成年人吗?" + isAdult);
double area = calculateCircleArea(5.0);
System.out.println("半径为5的圆面积:" + area);
}
// 有返回值的方法:返回两个数的和
// int:表示这个方法返回一个整数
// return:返回计算结果
static int add(int a, int b) {
int sum = a + b; // 计算和
return sum; // 返回结果
}
// 检查年龄是否成年
static boolean checkAge(int age) {
if (age >= 18) {
return true; // 返回true
} else {
return false; // 返回false
}
// 注意:一个方法必须保证在所有情况下都有返回值
}
// 计算圆面积
static double calculateCircleArea(double radius) {
double area = 3.14159 * radius * radius;
return area; // 返回double类型
}
}
2.4 方法参数传递的细节
java
public class ParameterDetails {
public static void main(String[] args) {
System.out.println("=== 方法参数细节 ===\n");
// 基本类型参数传递(传值)
int x = 10;
System.out.println("修改前 x = " + x);
changeNumber(x); // 把x的值10传给方法
System.out.println("修改后 x = " + x);
System.out.println("结论:基本类型参数不会改变原变量\n");
// 数组参数传递(传引用)
int[] scores = {85, 90, 78};
System.out.println("修改前 scores[0] = " + scores[0]);
changeArrayElement(scores); // 把数组的"地址"传给方法
System.out.println("修改后 scores[0] = " + scores[0]);
System.out.println("结论:数组参数会改变原数组内容\n");
// 多个参数示例
printStudentInfo("张三", 18, 95.5);
printStudentInfo("李四", 20, 88.0);
// 可变参数(参数数量可变)
System.out.println("\n=== 可变参数 ===");
System.out.println("平均分1:" + calculateAverage(85, 90, 78));
System.out.println("平均分2:" + calculateAverage(92, 88, 95, 76, 85));
System.out.println("平均分3:" + calculateAverage(100, 95)); // 两个参数也可以
}
// 尝试修改基本类型参数
static void changeNumber(int num) {
num = 100; // 只修改了方法内的副本
System.out.println("方法内 num = " + num);
}
// 修改数组元素
static void changeArrayElement(int[] arr) {
if (arr.length > 0) {
arr[0] = 100; // 修改了原数组的内容
}
}
// 多个参数的方法
static void printStudentInfo(String name, int age, double score) {
System.out.println("姓名:" + name + ",年龄:" + age + ",成绩:" + score);
}
// 可变参数:可以接受任意数量的参数
// 语法:类型... 参数名
static double calculateAverage(int... scores) {
if (scores.length == 0) {
return 0.0;
}
int sum = 0;
for (int score : scores) {
sum += score;
}
return (double) sum / scores.length;
}
}
三、方法重载:同名不同"参"
java
public class MethodOverloading {
public static void main(String[] args) {
System.out.println("=== 方法重载 ===\n");
// 方法重载:方法名相同,但参数列表不同
// Java会根据你传入的参数自动选择合适的版本
System.out.println("整数相加: " + add(5, 3));
System.out.println("小数相加: " + add(5.5, 3.3));
System.out.println("三个数相加: " + add(1, 2, 3));
System.out.println("字符串连接: " + add("Hello, ", "Java!"));
// 实际应用:计算不同图形的面积
System.out.println("\n=== 计算图形面积 ===");
System.out.println("正方形面积(边长5): " + calculateArea(5));
System.out.println("长方形面积(长5宽3): " + calculateArea(5, 3));
System.out.println("圆面积(半径4): " + calculateArea(4.0));
// 注意:返回值类型不同不能构成重载!
// 重载只看参数类型、数量、顺序,不看返回值
}
// 版本1:两个整数相加
static int add(int a, int b) {
System.out.print("调用int版本:");
return a + b;
}
// 版本2:三个整数相加(参数数量不同)
static int add(int a, int b, int c) {
System.out.print("调用三个参数版本:");
return a + b + c;
}
// 版本3:两个小数相加(参数类型不同)
static double add(double a, double b) {
System.out.print("调用double版本:");
return a + b;
}
// 版本4:字符串连接(完全不同类型)
static String add(String a, String b) {
System.out.print("调用String版本:");
return a + b;
}
// 版本5:整数和小数相加(参数顺序不同)
static double add(int a, double b) {
System.out.print("调用int-double版本:");
return a + b;
}
// 版本6:小数和整数相加(参数顺序不同)
static double add(double a, int b) {
System.out.print("调用double-int版本:");
return a + b;
}
// 图形面积计算方法(重载示例)
static int calculateArea(int side) {
return side * side; // 正方形
}
static int calculateArea(int length, int width) {
return length * width; // 长方形
}
static double calculateArea(double radius) {
return 3.14159 * radius * radius; // 圆形
}
}
四、方法的最佳实践和常见错误
java
public class MethodBestPractices {
public static void main(String[] args) {
System.out.println("=== 方法的最佳实践 ===\n");
// ✅ 好方法:单一职责,只做一件事
printWelcomeMessage();
int sum = calculateSum(10, 20);
System.out.println("计算结果:" + sum);
// ✅ 好方法:有意义的命名
boolean isValid = isValidEmail("test@example.com");
System.out.println("邮箱是否有效:" + isValid);
// ❌ 常见错误演示
System.out.println("\n=== 常见错误 ===");
// 错误1:方法太长(应该拆分成小方法)
// 错误2:方法名无意义(如 doSomething、process)
// 错误3:参数太多(超过3个要考虑封装成对象)
// 错误4:副作用太多(一个方法做了太多事情)
// 实用示例:学生管理系统
System.out.println("\n=== 学生管理系统示例 ===");
String name = "张三";
int[] scores = {85, 90, 78};
// 使用多个小方法,代码清晰易读
printStudentHeader(name);
double average = calculateAverage(scores);
String grade = calculateGrade(average);
printStudentResult(average, grade);
}
// ✅ 好例子:方法名清晰,功能单一
static void printWelcomeMessage() {
System.out.println("=== 欢迎使用学生管理系统 ===");
System.out.println();
}
static int calculateSum(int a, int b) {
return a + b;
}
static boolean isValidEmail(String email) {
// 简单的邮箱验证(实际应该用正则表达式)
return email != null &&
email.contains("@") &&
email.contains(".");
}
// 学生管理相关方法
static void printStudentHeader(String name) {
System.out.println("学生姓名:" + name);
System.out.println("------------");
}
static double calculateAverage(int[] scores) {
int sum = 0;
for (int score : scores) {
sum += score;
}
return (double) sum / scores.length;
}
static String calculateGrade(double average) {
if (average >= 90) return "A";
if (average >= 80) return "B";
if (average >= 70) return "C";
if (average >= 60) return "D";
return "F";
}
static void printStudentResult(double average, String grade) {
System.out.printf("平均分:%.2f\n", average);
System.out.println("等级:" + grade);
System.out.println();
}
// 📝 方法命名规范:
// 1. 动词开头:get、set、calculate、print、check等
// 2. 驼峰命名法:calculateAverageScore
// 3. 见名知义:不要用a、b、c这种无意义的名字
// 📝 方法设计原则:
// 1. 一个方法只做一件事
// 2. 方法不要太长(一般不超过50行)
// 3. 参数不要太多(最好不超过3个)
// 4. 避免副作用(不要修改不应该修改的东西)
}
五、递归方法:自己调用自己
java
public class RecursionDemo {
public static void main(String[] args) {
System.out.println("=== 递归方法 ===\n");
// 递归:方法自己调用自己
// 注意:必须有结束条件,否则会无限循环!
System.out.println("计算5的阶乘:");
int factorial = calculateFactorial(5);
System.out.println("5! = " + factorial);
System.out.println("\n计算斐波那契数列:");
for (int i = 0; i <= 10; i++) {
System.out.println("fib(" + i + ") = " + fibonacci(i));
}
System.out.println("\n递归实现数字倒序:");
printReverse(12345);
}
// 计算阶乘:n! = n × (n-1) × ... × 1
// 例如:5! = 5 × 4 × 3 × 2 × 1 = 120
static int calculateFactorial(int n) {
// 结束条件:0的阶乘是1
if (n == 0 || n == 1) {
System.out.println("到达结束条件:factorial(" + n + ") = 1");
return 1;
} else {
System.out.println("计算 factorial(" + n + ") = " + n + " × factorial(" + (n-1) + ")");
return n * calculateFactorial(n - 1);
}
}
// 斐波那契数列:每个数是前两个数之和
// fib(0)=0, fib(1)=1, fib(2)=1, fib(3)=2, fib(4)=3, ...
static int fibonacci(int n) {
if (n == 0) {
return 0;
} else if (n == 1) {
return 1;
} else {
return fibonacci(n - 1) + fibonacci(n - 2);
}
}
// 递归打印数字倒序
static void printReverse(int number) {
if (number < 10) {
// 只有一位数,直接打印
System.out.print(number);
} else {
// 打印最后一位数
System.out.print(number % 10);
// 递归处理剩下的数字
printReverse(number / 10);
}
}
}
六、实用案例:学生成绩管理系统
java
public class StudentGradeSystem {
public static void main(String[] args) {
System.out.println("=== 学生成绩管理系统 ===\n");
// 学生数据
String[] names = {"张三", "李四", "王五", "赵六"};
int[][] scores = {
{85, 90, 78}, // 张三的成绩
{92, 88, 95}, // 李四的成绩
{76, 85, 90}, // 王五的成绩
{88, 92, 86} // 赵六的成绩
};
// 处理每个学生
for (int i = 0; i < names.length; i++) {
processStudent(names[i], scores[i]);
}
// 找出最高分的学生
String topStudent = findTopStudent(names, scores);
System.out.println("\n⭐ 最高分学生:" + topStudent);
// 统计各分数段人数
printGradeDistribution(scores);
}
// 处理单个学生信息
static void processStudent(String name, int[] studentScores) {
printDivider();
System.out.println("学生:" + name);
double average = calculateAverage(studentScores);
String grade = getGradeLetter(average);
String status = getStatus(average);
System.out.printf("平均分:%.2f\n", average);
System.out.println("等级:" + grade);
System.out.println("状态:" + status);
printScores(studentScores);
}
// 计算平均分
static double calculateAverage(int[] scores) {
int sum = 0;
for (int score : scores) {
sum += score;
}
return (double) sum / scores.length;
}
// 获取等级(A-F)
static String getGradeLetter(double average) {
if (average >= 90) return "A";
if (average >= 80) return "B";
if (average >= 70) return "C";
if (average >= 60) return "D";
return "F";
}
// 获取状态(优秀/良好等)
static String getStatus(double average) {
if (average >= 90) return "优秀";
if (average >= 80) return "良好";
if (average >= 70) return "中等";
if (average >= 60) return "及格";
return "不及格";
}
// 打印分数详情
static void printScores(int[] scores) {
System.out.print("各科分数:");
for (int i = 0; i < scores.length; i++) {
System.out.print("科目" + (i+1) + ":" + scores[i]);
if (i < scores.length - 1) {
System.out.print(", ");
}
}
System.out.println();
}
// 找出最高分学生
static String findTopStudent(String[] names, int[][] allScores) {
double highestAverage = -1;
String topStudent = "";
for (int i = 0; i < names.length; i++) {
double average = calculateAverage(allScores[i]);
if (average > highestAverage) {
highestAverage = average;
topStudent = names[i];
}
}
return topStudent + String.format(" (%.2f分)", highestAverage);
}
// 统计分数分布
static void printGradeDistribution(int[][] allScores) {
int excellent = 0, good = 0, medium = 0, pass = 0, fail = 0;
for (int[] scores : allScores) {
double average = calculateAverage(scores);
if (average >= 90) excellent++;
else if (average >= 80) good++;
else if (average >= 70) medium++;
else if (average >= 60) pass++;
else fail++;
}
printDivider();
System.out.println("📊 分数分布统计:");
System.out.println("优秀(90+): " + excellent + "人");
System.out.println("良好(80-89): " + good + "人");
System.out.println("中等(70-79): " + medium + "人");
System.out.println("及格(60-69): " + pass + "人");
System.out.println("不及格(<60): " + fail + "人");
}
// 打印分隔线
static void printDivider() {
System.out.println("----------------------------");
}
}
七、总结:最重要的知识点
🎯 核心要点总结:
-
方法是代码的积木块:把常用的代码封装成方法,让程序更清晰、更易维护
-
方法三要素:
- 方法名:要见名知义,用动词开头(如calculate、print、get)
- 参数列表:方法需要的输入信息
- 返回值:方法执行后给出的结果(没有返回值用void)
-
方法调用:使用方法名加括号,传入需要的参数
java// 定义方法 static int add(int a, int b) { return a + b; } // 调用方法 int result = add(5, 3); -
方法重载:同一个方法名,不同的参数列表
javaadd(5, 3); // 调用int版本 add(5.5, 3.3); // 调用double版本