目录
方法概述
我们在学习运算符的时候,都为每个运算符单独的创建一个新的类和main方法,我们会发现这样编写代码非常的繁琐,而且重复的代码过多。能否避免这些重复的代码呢,就需要使用方法来实现。
方法:就是将一个功能抽取出来,把代码单独定义在一个大括号内,形成一个单独的功能。当我们需要这个功能的时候,就可以去调用。这样即实现了代码的复用性,也解决了代码冗余的现象。
方法入门
方法的定义
- 定义格式:
修饰符 返回值类型 方法名 (参数列表){
代码...
return 结果;
}
- 定义格式解释:
- 修饰符:目前固定写法public static
- 返回值类型:目前固定写法void
- 方法名:为我们定义的方法起名,满足标识符的规范,用来调用方法。
- 参数列表:目前无参数
- return:方法结束。因为返回值类型是void,方法大括号内的return可以不写
- 举例:
public static void methodName() {
System.out.println("这是一个方法");
}
方法的调用
方法在定义完毕后,方法不会自己运行,必须被调用才能执行,我们可以在主方法main中来调用我们自己定义好的方法。在主方法中,直接写要调用的方法名字就可以调用了。
public static void main(String[] args) {
//调用定义的方法method
method();
}
//定义方法,被main方法调用
public static void method() {
System.out.println("自己定义的方法,需要被main调用运行");
}
注意事项
- 方法必须定义在一个类中的方法外
- 方法不能定义在另一个方法的里面
方法深入
定义方法的格式详解
修饰符 返回值类型 方法名(参数列表){
//代码省略...
return 结果;
}
- 修饰符:public static 固定写法
- 返回值类型:表示方法运行的结果的数据类型,方法执行后将结果返回到调用者
- 参数列表:方法在运算过程中的未知数据,调用者调用方法时传递
- return:将方法执行后的结果带给调用者,方法执行到return ,整体方法运行结束
注意:return 结果; 这里的"结果"在开发中,我们正确的叫法成为方法的返回值
定义方法的两个明确
- 明确返回值类型:方法计算的是整数的求和,结果也必然是个整数,返回值类型定义为int类型。
- 明确参数列表:计算哪两个整数的和,并不清楚,但可以确定是整数,参数列表可以定义两个int类型的变量,由调用者调用方法时传递。
public class Method_Demo2 {
public static void main(String[] args) {
// 调用方法getSum,传递两个整数,这里传递的实际数据又称为实际参数
// 并接收方法计算后的结果,返回值
int sum = getSum(5, 6);
System.out.println(sum);
}
/*
定义计算两个整数和的方法
返回值类型,计算结果是int
参数:不确定数据求和,定义int参数.参数又称为形式参数
*/
public static int getSum(int a, int b) {
return a + b;
}
}
程序执行,主方法main 调用getSum 方法,传递了实际数据5和6 ,两个变量a和b 接收到的就是实际参数,并将计算后的结果返回,主方法main 中的变量sum 接收的就是方法的返回值。
定义方法的注意事项
- 定义位置,类中方法外面。
- 返回值类型,必须要和return 语句返回的类型相同,否则编译失败
// 返回值类型要求是int
public static int getSum() {
return 5;// 正确,int类型
return 1.2;// 错误,类型不匹配
return true;// 错误,类型不匹配
}
- 不能在return 后面写代码,return 意味着方法结束,所有后面的代码永远不会执行,属于无效代码
public static int getSum(int a,int b) {
return a + b;
System.out.println("Hello");// 错误,return已经结束,这里不会执行,无效代码
}
调用方法的三种形式
- 直接调用:直接写方法名调用
public static void main(String[] args) {
print();
}
public static void print() {
System.out.println("方法被调用");
}
- 赋值调用:调用方法,在方法前面定义变量,接收方法返回值
public static void main(String[] args) {
int sum = getSum(5,6);
System.out.println(sum);
}
public static int getSum(int a,int b) {
return a + b;
}
- 输出语句调用:
- 在输出语句中调用方法,System.out.println(方法名())
public static void main(String[] args) {
System.out.println(getSum(5,6));
}
public static int getSum(int a,int b) {
return a + b;
- 不能用输出语句调用void 类型的方法。因为方法执行后没有结果,也就打印不出任何内容。
public static void main(String[] args) {
System.out.println(printHello());// 错误,不能输出语句调用void类型方法
}
public static void printHello() {
System.out.println("Hello");
}
方法参数的值传递机制
概述
- 方法,必须由其所在类或对象调用才有意义。若方法含有参数:
- 形参:方法声明时的参数
- 实参:方法被调用时实际传给形参的参数值
- Java的实参值如何传入方法?
- Java里方法的参数传递方式只有一种:值传递。即将实际参数值的副本(复制品)传入方法内,而参数本身不受影响
- 形参是基本数据类型时:将实参基本数据类型变量的“数据值”传递给形参
- 形参是引用数据类型时:将实参引用数据类型变量的“地址值”传递给形参
变量存储的值
- 如果变量是基本数据类型,此时它存储的是它所保存的数据值
- 如果变量是引用数据类型,此时它存储的是它所保存的数据的地址值
- 注意:引用数据类型变量中不是null就是地址值
值传递机制-基本数据类型
/**
* 方法参数的传递机制,值传递-针对基本数据类型
* 1. 形参:方法定义时,声明在小括号内的参数
* 实参:方法调用时,实际传递给形参的数据
*
* 2. 值传递机制:
* 如果参数是基本数据类型,此时实参赋给形参的是实参真实存储的数据值。
*/
public static void jiaoHuan(int a, int b){
int temp;
temp = a;
a = b;
b = temp;
}
public static void main(String[] args) {
int a = 1, b = 2;
jiaoHuan(a, b);
System.out.println("执行完交换方法后,a = " + a + ", b = " + b);
}
核心代码的内存图:
值传递机制-引用数据类型
/**
* 方法参数的传递机制,值传递-针对引用数据类型
*
* 值传递机制:
* 如果参数是引用数据类型,此时实参赋给形参的是实参存储数据的地址值
*/
public static void jiaoHuan(int[] arr){
int temp;
temp = arr[0];
arr[0] = arr[1];
arr[1] = temp;
}
public static void main(String[] args) {
int[] arr = {1,2,4};
jiaoHuan(arr);
System.out.println("执行完交换方法后,数组的值是:");
System.out.println("arr[0] = " + arr[0] + ", arr[1] = " + arr[1]);
}
核心代码的内存图:
总结
其实关于这个方法参数的值传递的问题,重点是搞清楚变量赋值的问题。基本数据类型变量保存的是真实的数据,而引用数据类型保存的是数据的地址值。
所以如果将一个基本数据类型变量赋给另一个基本数据类型变量,赋的是真实的值;
而将一个引用数据类型的变量赋给另一个引用数据类型变量,赋的是数据的地址值!
然后是搞清楚内存结构图!
递归方法
- 递归方法:一个方法体内调用它自身
- 方法递归包含了一种隐式的循环,它会重复执行某段代码,但这种重复执行无须循环控制
- 递归一定要向已知方向递归,否则这种递归就变成了无穷递归,类似于死循环
/**
* 递归方法
* 1.递归方法:一个方法体内调用它自身
* 2.方法递归包含了一种隐式的循环,它会重复执行某段代码,但这种重复执行无须循环控制
* 3.递归一定要向已知方向递归,否则这种递归就变成了无穷递归,类似于死循环
*/
public class RecursionTest {
public static void main(String[] args) {
//方式一:求1-100的和
int sum = 0;
for(int i = 1; i <= 100; i++){
sum += i;
}
System.out.println(sum);
//方式二:使用递归
RecursionTest test = new RecursionTest();
int sum2 = test.getSum(100);
System.out.println(sum2);
int fiBonacci = test.getFiBonacci(4);
System.out.println(fiBonacci);
}
//1.求1-n的和
public int getSum(int n){
if(n == 1){
return 1;
}else{
return n + getSum(n-1);
}
}
//2.求1-n的乘积
public int getMul(int n){
if(n == 1){
return 1;
}else{
return n * getMul(n-1);
}
}
//3.已知有一个数列:f(0) = 1,f(1) = 4,f(n+2) = 2 * f(n+1) + f(n).
//其中n是大于0的整数,求f(10)的值.
public int f(int n){
if(n == 0){
return 1;
}else if(n == 1){
return 4;
}else{
return 2 * f(n-1) + f(n-2);
}
}
}