0%

javaSE基础学习day08

再谈方法

  • 方法的重载
  • 可变形参的方法
  • 方法参数的值传递机制❗❗❗(重要)
  • 递归方法

方法的重载

同一个类中,允许存在一个以上的同名方法,只要它们的参数个数或者参数类型不同即可。重载与方法的权限修饰符、返回值类型、形参变量名、方法体没有关系,只看参数列表,且参数列表必须不同 ( 参数个数或参数类型 ) 。调用时,根据方法参数列表的不同来区别。如下的5个方法构成了重载:

1
2
3
4
5
6
7
8
9
public void getSum(int x,int y){return x+y;}	
public void getSum(double x,double y){return x+y;} //与参数类型不同
public void getSum(int x,int y,int z){return x+y+z;} //与参数个数不同
public void getSum(String x,int y){return x+y;}
public void getSum(int y,String x){return x+y;}
//如下的3个方法不能与上述5个方法构成重载
public int getSum(int x,int y){return x+y;} //重载与返回值类型无关
public void getSum(int m,int n){return m+n;} //重载与形参变量名无关
private void getSum(int i,int j){return x+y;} //重载与权限修饰符无关

String类中的binarySearch方法重载

可变形参的方法

JavaSE 5.0 中提供了Varargs(variable number of arguments)机制,允许直接定义能和多个实参相匹配的形参。从而可以用一种更简单的方式,来传递个数可变的实参。

1
2
3
4
//JDK 5.0以前:采用数组形参来定义方法,传入多个同一类型变量
public static void test(int a ,String[] books);
//JDK5.0:采用可变个数形参来定义方法,传入多个同一类型变量
public static void test(int a ,String…books);
  • 声明格式:方法名(参数的类型名 …参数名)。
  • 可变参数:方法参数部分指定类型的参数个数是可变多个:0个,1个,2个或多个。
  • 可变个数形参的方法与本类中方法名相同,形参不同的方法之间构成重载。
  • 可变个数形参的方法与本类中方法名相同,形参类型也相同的数组不构成重载,二者不能共存。
  • 方法的参数部分有可变形参时,需要把可变形参放在形参声明的最后。
  • 在一个方法的形参位置,最多只能声明一个可变个数形参。
1
2
3
4
5
6
7
public void show(String ... strs){}
//不能与上一个方法同时存在
public void show(String[] strs){}

//报错:The variable argument type String of the method show must be the last parameter
//show方法的变量参数类型字符串必须是最后一个参数
public void show(String ...strs,int i){}

方法参数的值传递机制

方法必须由其所在类或对象调用才有意义。若方法含有参数:
📌 形参:方法声明时的参数
📌 实参:方法调用时实际传给形参的参数值
Java方法参数的传递方式仅有值传递,即将实际参数值的副本传入方法内,而参数本身不受影响。
📌 形参是基本数据类型:将实参基本数据类型变量的“数据值”传递给形参。
📌 形参是引用数据类型:将实参引用数据类型变量的“地址值”传递给形参。
引用数据类型的方法值传递
📌 如果变量是基本数据类型,此时赋值的是变量所保存的数据值。
📌 如果变量是引用数据类型,此时赋值的是变量所保存的数据的地址值。

练习

练习1

方法参数的值传递——练习1

练习2
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
public class Test2{
public static void main(String[] args){
int a = 10;
int b = 10;
method(a,b);//需要在method方法被调用之后,仅打印出a = 100,b = 200,请写出method方法的代码
System.out.println("a="+a);
System.out.println("b="+b);
}
}
//代码编写处
//法1
public static void method(int a,int b){
a = a * 10;
b = b * 20;
System.out.println("a="+a);
System.out.println("b="+b);
System.exit(0);//终止当前运行的Java虚拟机
}
//法2
public static void method(int a,int b){
//重置System.out.println()打印流
PrintStream ps = new PrintStream(System.out){
@Override
public void println(String x){
if("a=10".equals(x)){
x = "a=100";
}else if("b=10".equals(x)){
x = "b=200";
}
super.println(x);
}
};
System.setOut(ps);
}

exit()方法属于System类,System这个类是在java.lang包中,我们从API文档中找到这个方法(java.lang包在系统运行中自动加载,不需要通过import这个方法,所以可以直接调用该方法)。System.exit(int status)这个⽅法是⽤来结束当前正在运⾏中的java虚拟机。System.exit(0)是正常退出程序,⽽System.exit(1)或者⾮0,表⽰⾮正常退出程序。

练习3
1
2
3
4
5
6
7
8
9
10
11
12
13
14
//定义一个 int 型的数组: int[] arr = new int[]{12,3,3,34,56,77,432};让数组的每个位置上的值去除以首位置的元素,得到的结果,作为该位置上的新值。遍历新的数组。
//错误写法:第一次循环使arr[0]变成了1,接下来的数组元素值都是除1,而不是除12
for(int i = 0;i < arr.length;i++){
arr[i] = arr[i] / arr[0];
}
//正确写法1
for(int i = arr.length-1;i <= 0;i--){
arr[i] = arr[i] / arr[0];
}
//正确写法2
int temp = arr[0];
for(int i = 0;i < arr.length;i++){
arr[i] /= arr[0];
}
练习4
1
2
3
4
5
6
int[] arr = new int[10];
System.out.println(arr); //这里该输出什么? 大多数人答案是: 地址值

char[] arr1 = new char[10];
System.out.println(arr1); //这里该输出什么? 大多数人的答案是:地址值

1
2
3
4
5
6
7
8
9
10
//demo
public class ArrayPrintTest{
public static void main (String[] args) {
int arr =new int[]{1,2,3};
System.out.println(arr); //输出的确实是地址值

char[] arr1 = new char[]{'a','b','c'};
System.out.println(arr1); //输出的是abc
}
}

第一个输出用的是println(Object x)方法;第二个用的是println(char x[]),方法体会遍历数组。

练习5
1
2
3
4
5
6
7
8
9
10
11
12
public class ValueTransferTest {
public static void main(String[] args) {
String s1 = "hello";
ValueTransferTest test = new ValueTransferTest();
test.change(s1);
System.out.println(s1);//大部分人认为是hi~~ 实际是hello
}

public void change(String s2){
s2 = "hi~~";
}
}

String在字符串常量池,是不可变的字符序列,记住存的是地址值,传的就是地址值。

练习5

递归方法

递归方法:一个方法体内调用它自身。
📌 方法递归包含了一种隐式的循环,它会重复执行某段代码,但这种重复执行无须循环控制。
📌 递归一定要向已知方向递归,否则这种递归就变成了无穷递归,类似于死循环。

1
2
3
4
5
6
7
8
//例1:计算1到n之间的所有自然数之和
public int getSum(int n){
if(n == 1){
return 1;
}else{
return n + getSum(n-1);
}
}
1
2
3
4
5
6
7
8
9
10
//例2:已知有一个数列: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);
}
}
1
2
3
4
5
6
7
8
9
//例3:输入一个数据n,计算斐波那契数列(Fibonacci)的第n个值(1  1  2  3  5  8  13  21  34  55) 
//规律:一个数等于前两个数之和 要求:计算斐波那契数列(Fibonacci)的第n个值,并将整个数列打印出来
public int fibonacci(int n){
if(n == 1 || n == 2){
return 1;
}else{
return fibonacci(n-1) +fibonacci(n-2);
}
}
  • 本文作者: susin3x
  • 本文链接: https://susin3x.cn/posts/a702a3c4.html
  • 版权声明: 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!