JAVA学习笔记day06

什么是方法

方法是程序中最小的执行单元

方法有什么作用

如果有重复的代码,就可以将重复的部分打包成方法,要使用的话就可以直接调用这个方法

我们可以将发射的代码进行打包,如有需要就可以直接进行调用

这可以提高代码的复用性和提高代码的可维护性

易于维护: 如果有一天你想把"送人头"改成"拿五杀",你只需要修改 playGame 方法里面的那一行,所有调用它的地方都会跟着变。如果不打包,你得一个一个去改,很容易漏掉。

在实际开发中,我们会将有重复的代码、具有独立功能的代码抽取到方法中,以后有用到就不需要再写可以直接调用方法

方法的格式

方法就是将代码打包在一起,用的时候就调用

**方法的定义:**把一些代码打包在一起,该过程称为方法的定义

**方法的调用:**方法定义后并不是直接运行的,需要手动调用才能执行,该过程称为方法调用

方法的定义格式:

最简单的方法的定义和调用

方法的定义:

复制代码
public static void 方法名() {
    方法体(就是打包起来的代码);
}

方法的调用:

复制代码
方法名();

**主要:**方法必须先定义后调用,否则程序将会报错

方法的定义要写在main方法的外面,类的里面

方法的调用是在main方法里面

调用两次游戏

复制代码
package demo1;
public class Test2 {
    public static void main(String[] args) {
        playGame();
        playGame();
    }
    public static void playGame(){
        System.out.println("选择人物");
        System.out.println("准备开局");
        System.out.println("对线");
        System.out.println("崩盘");
        System.out.println("骂队友");
        System.out.println("送人头");
        System.out.println("GG");
    }
}

练习1:

复制代码
package demo1;
public class Test2 {
    public static void main(String[] args) {
        printGFInfo();
    }
   public static void printGFInfo(){
       System.out.println("姓名:小红");
       System.out.println("年龄:18岁");
       System.out.println("职业:学生");
   }
}

练习2:

看到方法进入方法,执行完毕回到调用处

练习3:

人肉计算器

需求:定义一个方法,在方法内部定义两个变量。

求出他们的和并进行打印

复制代码
package demo1;
public class Test2 {
    public static void main(String[] args) {
        getSum();
    }
   public static void getSum(){
      int number1 = 10;
      int number2 = 20;
      int sum = number1 + number2;
      System.out.println(sum);
   }
}
带参数的方法的定义和调用

当参数值不确定时,我们就可以将参数定义在方法名后面的小括号中,在调用这个方法时根据不同的情况来传入值

注意:方法调用时,参数的数量与类型必须与方法定义中小括号里面的变量一一对应,否则程序将报错。

练习1:

复制代码
package demo1;
public class Test2 {
    public static void main(String[] args) {
        getSum(12,35);
    }
   public static void getSum(int number1,int number2){
      int sum = number1 + number2;
      System.out.println(sum);
   }
}
形参和实参

例如:

练习1:

人肉计算机1

需求:定义一个方法,求长方形的周长,将结果在方法中进行打印。

复制代码
package demo1;
public class Test2 {
    public static void main(String[] args) {
        getLength(35,12);
    }
   public static void getLength(double len,double width){
      double result = len*2+width*2;
      System.out.println(result);
   }
}

练习2:

人肉计算机2

需求:定义一个方法,求圆的面积,将结果在方法中进行打印。

复制代码
package demo1;
public class Test2 {
    public static void main(String[] args) {
        printCircleArea(12);
    }
   public static void printCircleArea(double radius){
      double area = Math.PI*radius*radius;
      System.out.println(area);
   }
}
带返回值方法的定义和调用

带返回值方法的调用

练习1:

人肉计算机

需求:定义一个方法,求一家商场每个季度的营业额。

根据方法结果再计算出全年营业额。

复制代码
package demo1;
public class Test2 {
    public static void main(String[] args) {
        //先计算第一个季度的营业额
        int sum1 = getSum(10,20,30);
        //先计算第二个季度的营业额
        int  sum2 = getSum(20,40,30);
        //先计算第三个季度的营业额
        int sum3 = getSum(10,50,30);
        //先计算第四个季度的营业额
        int sum4 = getSum(40,70,30);
        //求全年的总营业额
        int sum =sum1+sum2+sum3+sum4;
        System.out.println(sum);
    }
   public static int getSum(int num1, int num2, int num3){
              int sum = num1 + num2 + num3;
              return sum;
   }
}

这时参数就有了值,那么在getSum方法中的result就是60,返回的结果就是60,方法的返回值是返回给了调用处,所以int sum = 就是返回值的结果60

练习1:

比较大小

需求:定义方法,比较两个长方形的面积。

写之前要问自己三个问题

1.我要干什么

2.需要什么

3.方法的调用处,是否需要继续使用方法的结果。如果要用那么方法必须有返回值,如果不用,方法可以写返回值,也可以不写返回值

复制代码
package demo1;
public class Test2 {
    public static void main(String[] args) {
        double area1=getArea(5.0,3.0);
        double area2 =getArea(6.0,4.0);
        if(area1>area2){
            System.out.println("第一个长方形更大");
        }else{
            System.out.println("第二个长方形更大");
        }
   }
   public static double getArea(double len , double width){
        double area = len*width;
        return area;
   }
}

方法的注意事项

return

方法没有返回值:可以省略不写。如果书写,表示结束方法

方法有返回值:必须要写。表示结束方法和返回结果

方法的重载

在同一个类中,定义了多个同名的方法,这些同名的方法具有相同的功能。

每一个方法具有不同的参数类型或参数个数,这些同名的方法,就构成了重载关系

**简单记忆:**同一个类中,方法名相同,参数不同的方法,与返回值无关

**参数不同:**个数不同,类型不同,顺序不同

Java虚拟机会通过不同的参数 来区分同名的方法

练习:区分以下方法是否构成重载关系

这个是因为不在一个类中

在同一个类的相同方法,个数相同,类型相同,但是顺序不同,但是不建议使用这种重载关系

练习2:

方法重载

需求:使用方法重载的思想,设计比较两个整数是否相同的方法。要求:兼容全整数类型(byte,short,int,long)

复制代码
package demo1;
public class Test2 {
    public static void main(String[] args) {
        compare(10,20);
        compare((byte) 10,(byte) 10);
        long n1 = 10;
        long n2 = 40;
        compare(n1,n2);
   }
   public static void compare(byte a,byte b){
       System.out.println("byte:");
       System.out.println(a==b);
   }
    public static void compare(short s1,short s2){
        System.out.println("short:");
        System.out.println(s1==s2);
    }
    public static void compare(int c1,int c2){
        System.out.println("int:");
        System.out.println(c1==c2);
    }
    public static void compare(long n1,long n2){
        System.out.println("long:");
        System.out.println(n1==n2);
    }
}

好处:

定义方法的时候可以不用那么多的单词了

调用方法的时候也不需要那么麻烦了。

练习1:

数组遍历

需求:设计一个方法用于数组遍历,要求遍历的结果是在一行上的。例如:[11,22,33,44,55]

复制代码
package demo1;
public class Test2 {
    public static void main(String[] args) {
       //1.先定义一个数组
        int[] array={11,22,33,44,55};
      //3.调用方法遍历数组
        printArray(array);
    }
    //2.定义方法用于数组遍历
    //我要干什么    遍历数组
    //我干这件事情需要什么才能完成  数组
    //方法的调用处是否需要继续使用结果?  不需要返回值
    public static void printArray(int[] array){
        System.out.print("[");
        for(int i=0;i<array.length;i++){
            if(i==array.length-1){
                System.out.print(array[i]);
            }else{
                System.out.print(array[i]+", ");
            }
        }
        System.out.print("]");
    }
}
复制代码
System.out.println("abc");  //先进行打印abc,然后再进行换行
System.out.print("cbf");    //只打印cbf,不换行
System.out.println();       //不打印任何数据,只做换行处理

练习2:

数组最大值

需求:设计一个方法求数组的最大值,并将最大值返回

复制代码
package demo1;
public class Test2 {
    public static void main(String[] args) {
        //1.先定义一个数组
        int[] array = {11, 22, 33, 44, 55};
        //3.调用方法求最大值
        int max = getMax(array);
        System.out.println("数组的最大值:"+max);
    }

    //2.定义方法用于求最大值
    //我要干什么    求最大值
    //我干这件事情需要什么才能完成  数组
    //方法的调用处是否需要继续使用结果?  需要返回值
    public static int getMax(int[] array) {
        int max = array[0];
        for (int i = 1; i < array.length; i++) {
            if(max<array[i]){
                max = array[i];
            }
        }
        return max;
    }
}

练习3:

定义一个方法判断数组中的某一个数是否存在,将结果返回给调用处

复制代码
package demo1;
public class Test2 {
    public static void main(String[] args) {
        //1.先定义一个数组
        int[] array = {11, 22, 33, 44, 55};
        //3.调用方法求是否存在
        boolean flag = contains(array,4);
        System.out.println("是否存在:"+flag);
    }

    //2.定义方法用于求是否存在
    //我要干什么    求是否存在
    //我干这件事情需要什么才能完成  数组 数字
    //方法的调用处是否需要继续使用结果?  需要返回值
    public static boolean contains(int[] array,int number) {
        for (int i = 1; i < array.length; i++) {
            if(array[i]==number){
                return true;
            }
        }
        //当数组中的所有数字全部比较完毕之后,才能断定是false
        return false;
    }
}

练习4:

复制数组

需求:定义一个方法copyOfRange(int[]arr,int from,int to)

功能:将数组arr中从索引from(包含from)开始。到索引to结束(不包含to)的元素复制到新数组中,将新数组返回。

索引3到7

复制代码
package demo1;

public class Test2 {
    public static void main(String[] args) {
        //1.定义原始数组
        int[] array = {1,2,4,6,88,9,45,6};
        //3.调用方法拷贝数据
        int[] copyArr = copyOfRange(array,2,7);
        for(int i=0;i<copyArr.length;i++){
            System.out.println(copyArr[i]);
        }
    }
    //2.将数组中从索引from(包含from)开始,到索引to(不包含to)结束的元素复制到新数组中
    public static int[] copyOfRange(int[]array,int from,int to){
        //定义数组
        int[] newArray=new int[to-from];
        //将原始数组array中的从from到to对应的元素直接拷贝到newArray中
        //伪造索引的思想
        int index=0;
        for(int i=from;i<to;i++){
            //数组名[索引] = 数据值;
           newArray[index]= array[i];
           index++;
        }
        return newArray;
    }
}

方法的内存

1.方法调用的基本内存原理

2.方法传递基本数据类型的内存原理

3.方法传递引用数据类型的内存原理

Java内存结构

方法调用的基本内存原理

方法被调用之后就会进栈执行

复制代码
public class MethodDemo {
public static void main(String[] args) {  
int number = 100;
sout("number的值为:"+ number);
  }
}

1.程序刚运行时main方法就要进栈

2.程序从上往下执行时,第一行是一个变量,所以在main方法里面就会命名一个变量number,它的类型是int,值是100

3.输出number,就是在main方法里找number里面记录的多少,值就是多少

4.代码结束后,main方法就会随之出栈,main方法里面的变量就会随之消失

出栈是先进入的后出去

复制代码
public class MethodDemo {
public static void main(String[] args) {
eat();
}
public static void eat() {
study();
System.out.println("吃饭");
sleep();
}
public static void sleep(){
System.out.println("睡觉");
}
public static void study(){
System.out.println("学习");
}

程序运行先是从上到下依次先是进入main方法,里面记录着eat()方法,

所以下面是eat方法进栈,eat方法的第一行是study方法,

所以study方法进栈,study方法里面是打印输出学习,所以控制行上就出现了学习,当学习打印输出结束后,回到调用处继续往下走,下面是eat方法中的第二行打印输出吃饭,所以在控制行中会出现吃饭,当吃饭打印输出结束后会继续往下执行,eat的第三行是sleep方法,

所以sleep方法会进栈, sleep方法里面是打印输出睡觉,所以控制行上面就会出现睡觉,当睡觉打印输出结束后sleep就会出栈,然后sleep返回调用处,然后继续往下执行,这是eat方法已经全部执行完了,

这是sleep方法出栈后,栈内的情况:

所以eat方法出栈 ,出栈后回到调用处(main方法中)回到调用处后继续往下执行,发现main方法也执行完了,所以main方法出栈

什么基本数据类型和引用数据类型

强行记忆

基本数据类型

在基本数据类型中变量中存储的是真实的数据

引用数据类型

只要是new出来的都是引用数据类型

数组的格式是int[] arr = new int[]{1,2,4,6,88,9,45,6};其中是在栈终main方法里面,而 new int[]{1,2,4,6,88,9,45,6};是在堆内存中的,如果想要获取数据就要先通过arr找到堆内存中对应的地址值,然后在通过索引找到对应的数据

引用数据类型中的变量中存储的是地址值,

引用:使用了其他空间的数据

从内存的角度去解释:

**基本数据类型:**数据值是存储在自己的空间中

特点:赋值给其他变量,也是赋的真实的值。

这样当b的数值发生了变化a是不会受其影响

**引用数据类型:**数据值是存储在其他空间中,自己空间中存储的是地址值。

特点:赋值给其他变量,赋的地址值。

这是如果数组arr1中的值发生了变化,那么arr2中的值也会有所变化

方法传递基本数据类型的内存原理
复制代码
package demo1;

public class Test2 {
    public static void main(String[] args) {
        int number = 100;
        System.out.println("调用change方法前:" + number);
        change(number);
        System.out.println(" 调用change方法后: " + number);
    }
        public static void change(int number){
            number = 200;
        }
    }

变量只能在所属的方法里面有效

所以在栈中,先是进入main方法,在main方法中有一个int类型的变量number,值为100,继续向下执行就是输出number的值,当控制台出现了number的值后结束,继续先下,调用change方法,所以change方法进栈,然后在change方法中有一个int类型的变量number,这个number的值就是100,继续先下执行change里面的代码,我要将200赋值给number,这是change方法里面的number的值为200,**但是要注意是change里面的number的值变成了200,(这是不会影响main里面number的值 ,这是因为变量是有作用范围的,变量只能在所属的方法里面有效),**然后继续向下就是},change方法就要出栈,回到调用处,然后继续向下执行打印输出number的值,所以main方法里面的number还是100,打印完成后代码就结束了,所以main方法也要出栈

传递基本数据类型时,传递的是真实的数据,形参的改变,不影响实际参数的值

如果在change方法处加上返回值(return number)这代表要将number的值返回调用处,然后再将number=change(number),这是第二个返回值就是200

复制代码
package demo1;

public class Test2 {
    public static void main(String[] args) {
        int number = 100;
        System.out.println("调用change方法前:" + number);
        number = change(number);
        System.out.println(" 调用change方法后: " + number);
    }
    public static int change(int number){
        number = 200;
        return number;
    }
}

数组

复制代码
package demo1;

public class Test2 {
    public static void main(String[] args) {
        int[] arr = {10, 20, 30};
        System.out.println("调用change方法前:" + arr[1]);
        change(arr);
        System.out.println("调用change方法后:" + arr[1]);
    }

    public static void change(int[] arr) {
        arr[1] = 200;
    }
}

这段代码在执行时是main方法先进栈,main方法里面有int[] arr =对应的地址值

接着打印输出arr[1]对应的值20(就是现在栈中的main中找到arr对应的地址值,知道地址值后可以到堆内存中找对应1索引的值20)打印完成后

调用change方法,change方法进栈,change方法里面有int[] arr =对应的地址值

但是arr对应的索引1的值是200,所以堆内存的索引1对应的值也要改为200

完成后change方法就要出栈,但是堆内存里面改成200后就不会因为change方法出栈而变化,所以接下来要打印输出arr[1]时找到的堆内存所对应的值为200

传递引用数据类型时,传递的是地址值,形参的改变,影响实际参数的值

结论

相关推荐
Jack.Jia1 小时前
GPS原理笔记三——GPS卫星轨道理论和计算
笔记
毕设源码-郭学长1 小时前
【开题答辩全过程】以 某某协会管理与展示平台为例,包含答辩的问题和答案
java
多云的夏天2 小时前
docker容器部署-windows-ubuntu
java·docker·容器
庞轩px2 小时前
内存区域的演进与直接内存——JVM性能优化的权衡艺术
java·jvm·笔记·性能优化
编码忘我2 小时前
java多线程安全集合
java
悟空码字2 小时前
滑块拼图验证:SpringBoot完整实现+轨迹验证+Redis分布式方案
java·spring boot·后端
编码忘我2 小时前
java类加载器及tomcat为什么不用双亲委派
java
liangshanbo12152 小时前
大模型 RAG 向量数据工程全链路架构笔记
笔记·架构
罗罗攀3 小时前
PyTorch学习笔记|张量的广播和科学运算
人工智能·pytorch·笔记·python·学习