java学习笔记: 基础知识: day05: 方法、方法参数传递问题(基本数据类型、引用数据类型、String类型)、返回的区别

====
day05
java学习笔记: 基础知识: day05: 方法、方法参数传递问题(基本数据类型、引用数据类型、String类型)、返回的区别

一、方法
1.方法的定义:方法就是完成特定功能的代码块。

2.格式
修饰符 返回值类型 方法名(参数类型 参数名1, 参数类型 参数名2, ...){
  方法体;
  return 返回值;
}

3.格式解释
修饰符:目前记住使用public static即可
返回值类型:用于限定返回值的数据类型
方法名:方便我们调用方法
参数类型:用于限定调用方法时,传入的数据的数据类型
方法体:完成特定功能的代码
return 返回值:结束方法,并且把返回值带给调用者

比喻:活猪赶进去,香肠拿出来。一个香肠制造机。

4.两个明确
(1)返回值类型:其实就是要我们明确方法结果的数据类型。
(2)参数列表:其实就是要我们明确有几个参数参加,并且每个参数都是什么数据类型。

5. 注意事项:方法与方法是平级关系,不能嵌套定义。

6.调用方法
(1)不仅要看方法名,还要看方法的参数(个数和类型)。人家返回什么数据类型,你就应该用什么数据类型。
(2)方法的调用(有明确返回值的方法的调用)
  A.单独调用(没有意义)
  B.赋值调用(推荐)
  C.输出调用

7.命名的习惯
(1)类:
如果是一个单词,首字母大写。
如果是多个单词,每个单词的首字母都大写。
(2)方法
和变量名的命名是一样的规则。
如果是一个单词,首字母小写。
如果是多个单词,从第二个单词开始,每个单词的首字母大写。
动词+名词,如:getMax。

8.如果一个方法没有明确的返回值类型,也不能把返回值类型的地方空出来。这里应该写void,表示该方法无返回值类型。

9.方法调用(void修饰的方法)
单独调用。
不可以用输出调用,因为编译时会出错。

10.java可变参数列表...
定义格式:修饰符 返回值类型 方法名(参数类型 参数名1, 参数类型 参数名2, ..., 参数类型... 参数名n)
举例说明:
public static int sum(int... arr){//(1)接数组。(2)接无数个参数。(3)可变参数列表必须写在最后一个位置。(4)sum(int[] arr)这个方法只能接收数组
  int sum = 0;
  for(int i = 0; i < arr.length; i++){
    sum += arr[i];
  }
  return sum;
}

11.数据类型的取值范围
Byte.MAX_VALUE;
Byte.MIN_VALUE;
Short, Integer也类似
char类型的没有最大值和最小值的取法,因为字符集不同。

12.方法重载
1.一些区别
overload 重载:同一个类中的同名方法。
overwrite 覆盖 :基类-子类的同名方法。

concurrent 并发:在同一个cpu中依次执行task1和task2。
parallel 并行:在不同的cpu中执行,比如task1在CPU1中执行,task2在CPU2中执行。

2.overloading 方法重载:在同一个类中,出现了方法名相同的情况。
特点:
(1)方法名相同,参数列表不同,与返回值无关。
(2)参数列表不同:A.参数个数不同。或者B.参数对应的数据类型不同。或者C.数据类型的顺序不同。

注意事项:
(1)在调用方法的时候,java虚拟机会根据方法名及参数列表的不同来区分方法。
(2)double, float类型的变量在做算数运算的时候,要注意有精度丢失的问题。如果做关系运算,就不需要考虑精度丢失的问题了。


二、方法参数传递问题
(一)方法参数是基本数据类型
1.详见“方法参数是基本类型的情况和图解.bmp”

java学习笔记: 基础知识: day05: 方法、方法参数传递问题(基本数据类型、引用数据类型、String类型)、返回的区别
2.图片描述:
(1)初始操作
方法区中放(从上到下):
ArgsDemo(类中从下到上)
change(int a, int b)
main(String[] args)

(2)从main方法开始起,把main方法加载到栈内存(栈是先进后出的,从下到上放),
change方法调用完毕,从内存中消失
a变为20           b变为40
int a = 10        int b = 20
change(int a, int b)

int a = 10        int b = 20
main(String[] args)

3.代码:
public class ArgsDemo{
  public static void main(String[] args){
    int a = 10;
    int b = 20;
    System.out.println("a: " + a + ", b: " + b);//10, 20
    change(a, b);
    System.out.println("a: " + a + ", b: " + b);//10, 20
  }

  public static void change(int a, int b){
    System.out.println("a: " + a + ", b: " + b);//10, 20
    a = b;
    b = a + b;
    System.out.println("a: " + a + ", b: " + b);//20, 40
  }
}

4.总结:
基本数据类型作为方法的参数,形式参数的改变不影响实际参数。
形式参数:用于接收实际参数的变量。
实际参数:实际参与运算的数据,用于传递给方法的参数变量。


(二)方法参数是引用类型时,方法参数的传递问题
1.详见“方法参数是引用类型的情况和图解.bmp”

java学习笔记: 基础知识: day05: 方法、方法参数传递问题(基本数据类型、引用数据类型、String类型)、返回的区别
2.图片描述:
(1)初始操作
方法区中放(从上到下):
ArgsDemo2(类中从下到上)
change(int[] arr)
main(String[] args)

(2)从main方法开始起,把main方法加载到栈内存(栈是先进后出的,从下到上放),
int[] arr
main(String[] args)

(3)堆
new int[5]
堆中分配5块int大小的连续的内存,以索引0-5表示。
数组中每一个元素的初始值都是0。
数组中每个元素的值依次被赋值为1-5。
将这块内存的起始地址001标记给这个数组名。
将这个地址001赋值给栈中的变量arr。

(4)这样,栈中的数组变量arr的地址001就指向了堆中数组的首地址001。
栈中循环打印数组中每个元素的值,系统先根据arr的地址找到堆中对应的地址,然后根据索引值找到arr元素的值,打印出来。1-5。
调用change(int[] arr)方法,实参arr将自己的地址值001传给change方法的形参arr。
change方法里的arr变量也指向堆中的地址001。

(5)在栈中,change方法执行,遇到元素是偶数时,就把数组在堆内存中相应元素的值变成从前的2倍。堆中数组arr中的元素值变为1,4,3,8,5。
change方法调用完毕,从栈内存中消失。这时栈内存中change方法里的arr变量不再指向堆中的地址。
(6)栈中循环打印数组中每个元素的值,系统先根据arr的地址找到堆中对应的地址,然后根据索引值找到arr元素的值,打印出来。1,4,3,8,5。

3.代码:
public class ArgsDemo2{
  public static void main(String[] args){
    int[] arr = {1,2,3,4,5};
    for(int i = 0; i < arr.length; i++;){
      System.out.println(arr[i]);//1,2,3,4,5
    }

    change(arr);

    for(int i = 0; i < arr.length; i++;){
      System.out.println(arr[i]);
    }
  }

  public static void change(int[] arr){
    for(int i = 0; i < arr.length; i++){
      //如果数据元素是偶数,值就变成了从前的2倍
      if(arr[i] %2 == 0){
        arr[i] *= 2;
      }
    }
  }
}

4.总结:
基本数据类型作为参数传递,形式参数的改变不影响实际参数。
引用数据类型作为参数传递,形式参数的改变直接影响实际参数。


(三)方法参数是String类型时,方法参数的传递问题
1.详见“方法参数是String类型的情况和图解.bmp”

java学习笔记: 基础知识: day05: 方法、方法参数传递问题(基本数据类型、引用数据类型、String类型)、返回的区别
2.图片描述:
(1)初始操作
方法区中放(从上到下):
StringDemo(类中从下到上)
change(String s)
main(String[] args)

(2)从main方法开始起,把main方法加载到栈内存(栈是先进后出的,从下到上放),创建String类型的变量s
String s
main(String[] args)

(3)方法区的常量池中开辟一块内存,写入字符串"我爱苍老师",这块内存的地址为001。将这个地址赋值给栈中的s变量。
(4)程序调用change方法,将main方法中的s变量指向的地址001传递给change方法的形参s,这时change方法的形参s指向的地址为001。
(5)栈中change方法执行到s = "我爱波老师";,在方法区的常量池中开辟一块内存,写入字符串"我爱波老师",这块内存的地址为002。将这个地址赋值给栈中change方法内的s变量指向的地址。
(6)change方法调用完毕,从栈内存中消失。change方法内的s变量不再指向常量池中的002地址。
(7)main方法继续往下执行,此时main方法里的s变量指向的地址仍然是001。
如果其他程序也需要使用常量池中已经存在的字符串,那么常量池不会再创建新的字符串,而是使用现有的字符串。如果使用不存在的字符串,那么会创建一个新的字符串。

3.代码:
public class StringDemo{
  public static void main(String[] args){
    String s = "我爱苍老师";
    change(s);
    System.out.println(s);//苍
  }

  private static void change(String s){
    System.out.println(s);//苍
    s = "我爱波老师";
    System.out.println(s);
  }
}
4.总结:
具体的String存放在方法区的常量池中。


三、返回的区别
没有返回值的方法void method(...)  可以有return,代表着方法的结束。
return是结束整个方法。
break是结束循环语句。
System.exit(0);正常结束整个java程序。
====