一、 什么是方法
-
分析
System.out.println()
System是一个系统的类,out是一个对象输出对象,println()就是一个方法
-
Java方法就是语句的集合,它们在一起执行一个功能
- 方法是解决一类问题的步骤的有序组合
- 方法包含于类或对象中
- 方法在程序中被创建,在其他地方被引用
-
设计方法的原则:方法的本意是功能块,就是实现某个功能的语句块的集合,我们设计方法的时候,最好保持方法的原子性,就是一个方法只完成1个功能,这样有利于我们后期的扩展
public class Demo01 { // main方法 // 每次输入psvm回车就会出现下面的语句,这就是一个main方法 public static void main(String[] args) { // 调用下面的方法实现加法 int sum = add(1,2); System.out.println(sum); test(); } // 加法 public static int add(int a, int b){ return a+b; } // 下面就是输出数字,没有参数传递 public static void test(){ for (int i = 0; i <= 1000; i++) { if (i%5 == 0){ System.out.print(i+"\t"); } if (i%(5*3)==0){ // 这里就是保证每行输出3个被5整除的数 // println 输出完会换行 // print 输出完不会换行 System.out.println(); // System.out.print("\n"); } } } }
二、方法的定义
Java的方法类似于其他语言的函数,是一段用来完成特定功能的代码片段,一般情况下,定义一个方法包含以下语法:
-
方法包含一个方法头和一个方法体,下面是一个方法的所有部分:
-
修饰符:这是可选的,告诉编译器如何调用该方法。定义了该方法的访问类型。
-
返回值类型:方法可能会返回值。
returnValueType
是方法返回值的数据类型。有些方法执行所需的操作,但没有返回值,在这种情况下,returnValueType
是关键字void
。 -
方法名:是方法的实际名称。方法名和参数表共同构成方法签名。
-
参数类型:参数像是一个占位符。当方法被调用时,传递值给参数。这个值被称为实参或变量。参数列表是指方法的参数类型、顺序和参数的个数。参数是可选的,方法可以不包含任何参数。
–>形式参数:在方法调用时用于接收外界输入的数据
–>实参:调用方法时实际传给方法的数据
-
方法体:方法体包含具体的语句,定义该方法的功能。
public class Demo02 { public static void main(String[] args) { int max = max(10, 20); System.out.println(max); } // 比较大小 public static int max(int num1, int num2) { int result = 0; if (num1 == num2) { System.out.println("num1 == num2"); return 0; // return除了可以返回结果,还可以终止方法 } if (num1 > num2){ result = num1; } else { result = num2; } return result; // 返回结果 } }
-
三、方法调用
-
调用方法:对象名.方法名(实参列表)
-
Java支持两种调用方法的方式,根据方法是否返回值来选择
-
当方法返回一个值的时候,方法调用通常被当作一个值,例如
int larger = max(30, 40);
-
如果方法返回值是void,方法调用一定是一条语句
System.out.println("Hello, wangrong!");
-
值传递和引用传递
-
Java参数传递中,不管传递的是基本数据类型还是引用类型,都是值传递(参考下面两篇文章)
-
四、方法的重载
-
重载就是在一个类中,有相同的函数名称但形参不同的函数
-
方法的重载的规则:
- 方法名称必须相同
- 参数列表必须不同(个数不同、类型不同或参数排列顺序不同等)
- 方法的返回类型可以相同也可以不相同
- 仅仅返回类型不同不足以成为方法的重载
-
实现理论:
- 方法名称相同时,编译器会根据调用方法的参数个数、参数类型等去逐个匹配,以选择对应的方法,如果匹配失败,则编译报错
public class Demo02 { public static void main(String[] args) { // int max = max(10, 10); // 这里调用输出的就是int类型 double max = max(10, 20.0); // 而这里调用输出的就是double类型 System.out.println(max); } // 比较大小 public static int max(int num1, int num2) { int result = 0; if (num1 == num2) { System.out.println("num1 == num2"); return 0; // return除了可以返回结果,还可以终止方法 } if (num1 > num2){ result = num1; } else { result = num2; } return result; // 返回结果 } // 比较大小 // 这里把上面的int类型都变为double,max()函数也就变成了一个函数的重载 public static double max(double num1, double num2) { //double result = 0; // 也可以继续返回int类型,只是下面要进行一个强制转换 int result = 0; if (num1 == num2) { System.out.println("num1 == num2"); return 0; // return除了可以返回结果,还可以终止方法 } if (num1 > num2){ // result = num1; result = (int)num1; // 进行一个强制转换 } else { // result = num2; result = (int)num2; // 进行一个强制转换 } return result; // 返回结果 } }
五、命令行传参
有时候希望运行一个程序时再传递给它消息。这要靠传递命令行参数给main()函数实现。
public class CommandLine {
public static void main(String args[]){
for (int i=0; i<args.length; i++){
System.out.println("args[" + i + "]: " + args[i]);
}
}
}
点开Terminal使用命令行
可以看到,使用javac com.rong.method.Demo03
出现错误,那么说明是不能这样写的。
接下来就不从IDEA中执行了,转去使用命令行来操作,进入Demo03文件所在的路径。
在文件路径前面加上cmd回车
进入控制台,使用javac Demo03.java
去编译,出现如下错误,其错误原因是使用简单javac
命令编译java文件,如果代码中存在中文,就算是注释有中文的也会弹出错误,正确的命令应该改为javac -encoding UTF-8 Demo03.java
然后通过java命令执行会报出错误“找不到或无法加载主类 Demo03”,所以要退到src这个目录下才可以执行
使用命令cd ../
回退到src目录下,然后运行就不能只是java Demo03
了,要加上完整的包名,也即是把命令改为java com.rong.method.Demo03
,回车之后可以看到什么都没有输出,因为我们没有给它传递参数
现在来给它传递参数,输入一串字符串进去,可以看到顺利输出三个参数
六、可变参数
- JDK1.5开始,Java支持传递同类型的可变参数给一个方法。
- 在方法声明中,在指定参数类型后加一个省略号(…)。
- 一个方法中只能指定一个可变参数,它必须是方法的最后一个参数。任何普通的参数必须在它之前声明。
public class Demo04 {
public static void main(String[] args) {
}
// 下面定义了函数重载,参数越来越多,就会越来越繁琐,有可能一个重载要写几十次,这样就非常麻烦了
public void method(){}
public void method(int i){}
public void method(int i, int i2){}
public void method(int i, double i2){}
}
// 下面写一个可变参数,输出i
public class Demo04 {
public static void main(String[] args) {
Demo04 demo04 = new Demo04();
// 调用test(),并且不传参数
demo04.test();
}
//
public void test(int... i){
System.out.println(i);
}
}
可以看到什么都没有输出,[I@1b6d3586只是对象在内存中的存在的地址
接下来,给它传递一个1,看到它输出的值为1
public class Demo04 {
public static void main(String[] args) {
Demo04 demo04 = new Demo04();
// 调用test(),并且不传参数
demo04.test(1);
}
//
public void test(int... i){
System.out.println(i[0]);
}
}
如果此时什么都没有写,那就会报出异常“数组下标越界”
public class Demo04 {
public static void main(String[] args) {
Demo04 demo04 = new Demo04();
// 调用test(),并且不传参数
demo04.test();
}
//
public void test(int... i){
System.out.println(i[0]);
}
}
还可以多传几个参数,然后进行遍历
public class Demo04 {
public static void main(String[] args) {
Demo04 demo04 = new Demo04();
// 调用test(),并且不传参数
demo04.test(1 ,2, 3, 4, 5);
}
//
public void test(int... i){
System.out.println(i[0]);
System.out.println(i[1]);
System.out.println(i[2]);
System.out.println(i[3]);
System.out.println(i[4]);
}
}
public class Demo04 {
public static void main(String[] args) {
printMax(34, 12, 36, 48.9, 23, 15.6); // 传递可变参数的方法
printMax(new double[]{34, 12, 36, 48.9, 23, 15.6}); // 传递一个数组
}
public static void printMax(double... numbers) {
if (numbers.length == 0) {
System.out.println("No argument passed");
return;
}
double result = numbers[0];
// 输出最大值
for (int i = 1; i < numbers.length; i++) {
if (numbers[i] > result) {
result = numbers[i];
}
}
System.out.println("The max value is " + result);
}
}
七、递归
-
递归就是:A方法调用A方法,就是自己调用自己
-
利用递归可以用简单的程序来解决一些复杂的问题,它通常把一个大型复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解,递归策略只需少量的程序就可描述出解题过程所需要的多次重复计算,大大减少了程序的代码量。递归的能力在于用有限的语句来定义对象的无限集合。
-
递归结构包括两个部分:
- 递归头:什么时候不调用自身方法。如果没有头,将陷入死循环。
- 递归体:什么时候需要调用自身方法。
import java.util.Scanner; public class Demo05 { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); System.out.println("请输入需要求的阶层:" ); int n = scanner.nextInt(); int num = f(n); System.out.println(n + "的阶层为:" + num); } // 计算阶层 public static int f(int n){ if (n == 1){ return 1; }else{ return n*f(n-1); } } }
解决问题的时候可以想办法用递归解决,但是递归并不一定就是最好的方法,比如说小计算可以用递归,但是如果调用自身太多了,反而会影响自身的性能。
import java.util.Scanner;
public class Caculator {
public static void main(String[] args) {
// 练习:写一个计算器,要求实现加减乘除功能,并且能够循环接收新的数据,通过用户交互实现
/*
思路:
写4个方法:加减乘除;
利用循环+switch进行用户交互;
传递需要操作的两个数;
输出结果。
*/
Scanner scanner = new Scanner(System.in);
System.out.print("请输入第一个数:");
double num1 = scanner.nextDouble();
scanner.nextLine(); // 这里使用一个nextLine(),用它接收\n,防止输入运算符和第二个数出错
System.out.print("请输入需要进行运算的运算符(+ - * /):");
String operator = scanner.nextLine();
System.out.print("请输入第二个数:");
double num2 = scanner.nextDouble();
double result;
scanner.close();
switch (operator){
case "+":
result = num1 + num2;
System.out.println(num1 + "+" + num2 + "=" + result);
break;
case "-":
result = num1 - num2;
System.out.println(num1 + "-" + num2 + "=" + result);
break;
case "*":
result = num1 * num2;
System.out.println(num1 + "*" + num2 + "=" + result);
break;
case "/":
if (num2 != 0){
result = num1 / num2;
System.out.println(num1 + "/" + num2 + "=" + result);
}else{
System.out.println("除数不能为0!");
}
break;
default:
System.out.print("输入操作符不合法!");
}
}
}
造成上面的错误原因,经过在网上搜索和调试代码,原因是 nextLine()
方法不能放在 nextInt()
代码段的后面,从输入上看,好像直接跳过了这个输入运算符的语句,但其实并没有跳过,而是它已经有内容,其内容就是 \n
。因为 nextInt()
接收一个整型字符,不会读取 \n
,nextline()
读入一行文本,会读入 \n
字符,所以当我们输入的时候就会出现上面的错误。那解决的方式就是可以在第一个nextInt()
语句后面 nextLine()
这个语句之前加一个 nextLine()
,专门用它接收这个 \n
。
import java.util.Scanner;
public class Caculator2 {
public static void main(String[] args) {
// 练习:写一个计算器,要求实现加减乘除功能,并且能够循环接收新的数据,通过用户交互实现
/*
思路:
写4个方法:加减乘除;
利用循环+switch进行用户交互;
传递需要操作的两个数;
输出结果。
*/
Scanner scanner = new Scanner(System.in);
System.out.print("请输入第一个数:");
double num1 = scanner.nextDouble();
scanner.nextLine();
System.out.print("请输入需要进行运算的运算符(+ - * /):");
// charAt() 方法用于返回指定索引处的字符。索引范围为从 0 到 length() - 1。语法:public char charAt(int index)。
char operator = scanner.next().charAt(0);
System.out.print("请输入第二个数:");
double num2 = scanner.nextDouble();
double result;
scanner.close();
switch (operator){
case '+':
result = num1 + num2;
System.out.println(num1 + "+" + num2 + "=" + result);
break;
case '-':
result = num1 - num2;
System.out.println(num1 + "-" + num2 + "=" + result);
break;
case '*':
result = num1 * num2;
System.out.println(num1 + "*" + num2 + "=" + result);
break;
case '/':
if (num2 != 0){
result = num1 / num2;
System.out.println(num1 + "/" + num2 + "=" + result);
}else{
System.out.println("除数不能为0!");
}
break;
default:
System.out.print("输入操作符不合法!");
}
}
}
上述编写一个计算器,实现加减乘除功能的代码要注意两个问题:
- 使用switch语句,case当中的符号要注意单引号和双引号问题
- 输入字符串类型时,有两种方式:一种是使用String类来创建和操作字符串;另一种是定义char类型,但是要注意使用charAt()方法返回指定索引处的字符,比如说
char operator = scanner.next().charAt(0)
注:笔记是自己一个字一个字写出来的,但是是参考遇见狂神说的课程[https://www.bilibili.com/video/BV12J41137hu/?spm_id_from=333.999.0.0&vd_source=51e338bc66714d1cb8adb07196bec5e5]