zoukankan      html  css  js  c++  java
  • java学习笔记(6)方法、内存、重载

    方法

    /*
        以下程序不使用"方法",分析程序存在哪些缺点?
            *以下代码都是计算两个int类型数据的和,相同的代码写了两遍(只不过每次参与求和的数据不同)。
            代码没有得到重复使用。
            *java语言当中应该有这样的一种机制:
                -某个功能代码只需要写一遍。
                -要使用这个功能,只需要给这个功能传递具体的数据。
                -这个功能完成之后返回一个最终结果。
                这样代码就可以重复利用了,提高代码复用性。【这就是"方法"】
            *使用这个方法,我们称为:调用/invoke
    
     */
     public class Method01{
         public static void main(String[] args){
            // 需求1:请编写程序计算10和20的和,并将结果输出【功能是 计算两个int类型数据的和】
            int a = 10;
            int b = 20;
            int c = a + b;
            System.out.println(a + " + " + b +" = " + c);
    
            // 需求2:请编写程序计算666和888的和,并将结果输出【功能是 计算两个int类型数据的和】
            int x = 666;
            int y = 888;
            int z = a + b;
            System.out.println(x + " + " + y +" = " + z);
            // 以上的两个需求其实就是一个需求,需求是:计算两个int类型的和,功能相同
            // 只不过每次参与计算的具体数据不同。
    
         }
     }
    /*
        以下直接使用方法这种机制【这个例子不讲方法的语法】,分析程序的优点?
            *代码得到了重复使用
        *方法的本质是什么?
            -方法就是一段代码片段,并且这段代码片段可以完成某个特定的功能,并且可以被重复的使用。
            -方法对应的英语单词是:Method
            -方法在c语言中叫作函数/Function,在java语言中叫方法
    
        *方法定义在类体当中,方法体之外。
        *在一个类体重可以定义多个方法,方法编写的位置没有先后顺序,可以随意。
        *方法体当中不能再定义方法
        *方法体有java语句构成,方法体当中的代码遵守自上而下的顺序执行。
    
    
     */
     public class Method01{
        //  类体
         public static void main(String[] args){
            //  方法体
            
    
            // 下面是调用方法计算int的和
            sumint(30,40);//30 + 40 = 70
            Method01.sumint(50,60);//50 + 60 = 110
         }
        //  方法
        // 单独定义一个方法
        // 该方法完成计算两个int类型的和,并且将结果输出
        public static void sumint(int a,int b){
            // 方法体
            int c = a + b;
            System.out.println(a + " + " + b + " = " + c);
        }
     }

     方法定义规则:

    /*
        关于java语言中的方法:
            1、方法怎么定义?语法结构:
                [修饰符列表] 返回值类型 方法名(形式参数列表){
                    方法体;
                }
            2、对以上的语法结构进行解释说明:
                2.1、关于修饰符列表
                    *可选项,不是必须的
                    *目前可统一写成:public static 【以后再说】
                    *方法的修饰符列表当中有static关键字的话,怎么调用这个方法?
                        -类名.方法名(实际参数列表);
                2.2、返回值类型
                    *什么是返回值?
                        -一个方法是可以完成某个特定功能的,这个功能结束之后大多数都是需要
                            返回最终的执行结果,执行结果可能是一个具体存在的数据。只要是数据一定
                            会有类型,而这个存在的数据就是返回值。
    
                    *返回值类型是什么?
                        -返回值是一个具体存在的数据,数据都是由类型的,此处需要指定的是
                        返回值的具体类型
                    
                    *返回值类型都可以指定哪些类型呢?
                        -java中任意一种类型都可以,包括基本数据类型和所有的引用数据类型。
                    
                    *也可能这个方法执行之后不返回任何数据,java中规定,当一个方法执行结束之后
                    不返回任何数据,返回值类型位置必须编写:void关键字
                    
                    *返回值类型可以是什么?
                        byte、short、int、long、float、double、boolean、char、String、void......
                    
                    *返回值类型若不是void,表示这个方法执行结束之后必须返回一个具体的数值。
                    当方法执行结束的时候没有返回任意数据的话编译器报错。
                    
                    *怎么返回值呢?
                        return 值; 并且要求"值"的数据类型,必须和"方法的返回值类型一致"。不然编译器报错。
                    
                    *当返回值类型是void的时候,在方法体当中不能编写"return 值;"这样的语句
                    但是可以编写"return;"这样的语句
                    
                    *只要带有return关键字的语句执行,return语句所在的方法结束。【不是jvm结束,是所在的方法结束】
                2.3、方法名
                    *只要是合法的标志符就行
                    *方法名最好见名知意
                    *方法名最好是动词
                    *方法名要求首字母小写,后面的单子首字母大写,驼峰命名方式
                2.4、形式参数列表:简称 形参
                    *形参是局部变量
                    *形参的个数可以是:0-N个
                    *多个形参之间用"逗号"隔开
                    *实参和形参列表必须满足:
                        -数量相同
                        -类型对应相同
                    *形参中起决定性作用的是 形参的类型,形参的名字只是一个标识符,形参的名字
                        就是局部变量的名字。
                        例如:
                            方法定义
                            public static int sum(int a,int b){//(int a,int b)是形参列表
    
                            }
                            方法调用:
                            sum("abc","def");//编译器会报错,
                            sum(10,20);//编译通过  (10,20)是实参列表
                2.5、方法体
                    方法体必须有大括号括起来,方法体当中的代码有顺序,由上而下执行。
                    并且方法体由java语句构成,java语句有";"结尾。
            3、方法怎么调用?
                方法只定义时不会执行的,只有调用的时候才执行
                语法规则:【这里只说方法的修饰符当中有static关键字的方法】
                    类名.方法名(是参列表);这是一条java语句,表示调用某个类的某个方法,传递这样的参数
    
    
    
    
    
     */
     public class Method01{//类相当于汽车工厂
        //  类体
         public static void main(String[] args){
            //  方法体
         }
        //  定义一个方法
        // 一个车间
    
        public static int sumint(int a,int b){
            // 方法体
            int c = a + b;
            System.out.println(a + " + " + b + " = " + c);
        }
     }
    /*
    */
    // public表示公开的
    // class表示定义类的关键字
    // Method01是一个类名
     public class Method01{//表示定义一个公开的类,起名Method01,由于是公开的类,所以源文件名必须是Method01
        //  类体
        // 类体中不能直接编写java代码,除声明变量之外
        // 方法出现在类体当中
    
        // 方法
        // public表示公开的
        // static表示静态的
        // void表示方法执行结束之后不返回任何数据
        // main是方法名:主方法
        // (String[] args):形式参数列表,其中String是一种引用数据类型,args是一个局部变量的变量名
        // 所以以下只有args这个局部变量的变量名是可以随意写的
        // 主方法就需要这样固定编写,这是程序的入口。【sun规定的,必须这样写才行】
         public static void main(String[] args){
            //  方法体
            // 这里的程序是一定会执行的
            // main方法是JVM负责调用的,是一个入口的位置
            // 从这里来时起点开始执行程序
            // 既然是这样,我们就可以在这里编写java语句来调用其它方法
            // 调用Method01的sum方法  (只有static修饰符的方法可以这样调用,类名也可以省略
            Method01.sum(10,20);
            // 也可以这样
            sum(20,40);//只有static修饰符的方法才可以这样调用
    
         }
        //  自定义方法 ,不是程序入口
        // 方法作用:计算两个int类型数据的和,不要求返回结果,但是要求将结果直接输出到控制台
        // 修饰符列表:public static
        // 返回值类型:void
        // 方法名:sum
        // 形式参数列表:(int x,int y)
        // 方法体:主要任务是,求和之后,输出计算结果
        public static void sum(int i,int j){
            System.out.println(i + " + " + j + " = " + (i + j));
        }
    
    
     }
    /*
    方法的难点:
       public static ???(返回值)  方法名(返回什么参数合适){
          //如何编写代码
       }
       方法的调用不一定在main方法当中,
       只要程序可以执行到的位置,都可以执行其他方法。
     */
    public class Method01{
       public static void sum(int a,int b){
          System.out.println(a +" + " + b + " = " + (a + b));
          // 调用dosome方法
          Method01.doSome();
       }
       public static void doSome(){
          System.out.println("do some");
       }
       // 主方法
       public static void main(String[] args){
          // 调用 sum方法
          Method01.sum(1,2);
          System.out.println("hello world");
       }
    }
       

    执行javac -encoding UTF-8 Method01.java(编译)

    java Method01(执行)

    /*
    方法调用
       1、方法的修饰符列表当中有static关键字,完整的调用方法是:类名.方法(是参列表);
       2、但是有的时候"类名."可以省略。什么情况下可以省略呢?
          m1(){
             m2();
          }
          //上述调用省略"类名.",只有在m1和m2方法在同一个类体当中时,可以省略
       3、一个java源文件中建议只定义一个class,比较清晰,这里只是举例方便才在java源文件当中写多个class
    
    */
    public class Method01{
       public static void main(String[] args){
          // 调用方法
          Method01.m();
          // 对于方法的修饰符列表当中有static关键字的,"类名."可以省略不写吗?
          m();//执行成功  "类名."可以省略不写
          
          // 调用其它类,【不是本类中】的方法
          A.doOther();//调用成功
          // 省略"类名.",试试 (此时,是在当前类中找doOther方法,在当前类中不存在。
          // 编译错误: 找不到符号
          // doOther();
    
       }
       public static void m(){
          System.out.println("m Method execute!");
          // 调用当前类中的方法,可以省略"类名."
          m2();
          // 完整的方式调用m2方法,在其它类中也可以这样调用
          Method01.m2();
          // 不想调用本类中的m2方法,想调用其它类中的m2方法
          // 类名.方法();
          // 以后只要调用方法,都不省略"类名.",规范上比较好,如果知道这个语法,可以少写几句代码
          A.m2();
       }
       public static void m2(){
          System.out.println("m2 execute!");
       }
    }
    
    class A{
       public static void doOther(){
          System.out.println("'A's doOther method invoke");
       }
       public static void m2(){
          System.out.println("'A's m2 execute!");
       }
    }
    /*
    分析程序的输出结果:
    main begin!
    m1 begin!
    m2 begin!
    m2 over!
    m1 over!
    main over!
    
    对于当前的程序来说,main方法最先调用,也是最后一个结束。
    最后调用的方法是m2,该方法最先结束
       方法中的代码是自上而下执行的即可,上一行代码未执行结束,下一行代码不会执行
    */
    public class Method01{
       public static void main(String[] args){
          System.out.println("main begin!");
          m1();
          System.out.println("main over!");
    
       }
       public static void m1(){
          System.out.println("m1 begin!");
          m2();
          System.out.println("m1 over!");
       }
       public static void m2(){
          System.out.println("m2 begin!");
          
          System.out.println("m2 over!");
       }
    }
    /*
    方法的返回值类型不是void的时候
       1、返回值类型不是void的时候,要求方法必须保证百分百的执行"return 值;"这样的语句来完成值的返回。
          没有这个语句,编译器会报错。
       2、一个方法有返回值的时候,当我们调用这个方法的时候,方法返回一个值,
          对于调用者来说,这个返回值可以选择接受,也可以选择不接受。
          但是大部分情况下,我们是选择接收的。
    */
    public class Method01{
       public static void main(String[] args){
          // 方法调用
          divide(10,3);//这里没有接收这个方法的返回数据
          // 这里接收一下方法的返回值
          // 采用变量接收
          // 变量的数据类型需要和方法的返回值类型相同,或者可以自动类转换
          // boolean b = divide(10,3);//编译报错  不兼容的类型: int无法转换为boolean
          // 赋值运算符的右边线执行,将执行结果赋值给左边的变量
          int i = divide(10,3);
          System.out.println(i);//3
    
          long x = divide(10,3);//小类型想大类型存在自动类型转换
          System.out.println(x);//3
       }
       /*
       需求:
          请定义并实现一个方法,该方法可以计算两个int类型的商;
          要就将最终的调用结果返回给调用者。
       */
       // 编译报错:缺少返回语句
       // public static int divide(int a,int b){
    
       // }
       // 编译错误:缺少返回值
       // public static int divide(int a,int b){
       //    return;
       // }
       // 不兼容的类型: boolean无法转换为int
       // public static int divide(int a,int b){
       //    return true;
       // }
       public static int divide(int a,int b){
          return a / b;
       }
    }
    /*
    深入return语句
       *带有return关键字的java语句只要执行,所在的方法执行结束。
    
       *在"同一个作用域"当中,return语句下面不能编写任何代码,因为这些代码永远都执行不到。
          所以编译报错。
       
    */
    public class Method01{
       public static void main(String[] args){
          int returnValue = m();
          System.out.println(returnValue);//1
          System.out.println(m());//1
       }
       // public static int m(){
       //    int a = 10;
       //    if(a>3){//截止到这,m方法无法保证,这个方法百分之百的有返回语句,所以会编译报错
       //       return 1;
       //    }else{//这样 加上else语句后,就能够百分百保证这个方法有返回语句,殡仪就会通过
       //       return 0;
       //    }
       // }
       // 将m方法改进一下,去掉else语句
       // public static int m(){
       //    int a = 10;
       //    if(a>3){
       //       return 1;
       //       // return 语句后面加上语句后 无法执行,因为return后的语句执行不到,会编译报错
       //       // System.out.println("hello");
       //    }
       //    return 0;
       //    // 在同一作用域下,return后面不能有语句,因为执行不到,会导致编译错误
       //    // System.out.println("hello");
       // }
    
       // 将m方法再次改进
       public static int m(){
          int a = 10;
          return a > 3 ? 1 : 0;
       }
       
    }
    /*
    在返回值类型为void的方法中使用return语句。
    "return;"可以出现在返回值为void方法当中,主要用来终止方法的执行。
    
    
       
    */
    public class Method01{
       public static void main(String[] args){
          m();
          s();
       }
       public static void m(){
          // return 0;//不兼容的类型: 意外的返回值
          return;
       }
       public static void s(){
          for(int i =0;i<10;i++){
             if(i==5){
                // return;//return不是终止的for循环,而是终止整个方法
                break;//终止for循环
             }
             System.out.println("i--->"+i);
          }
       }
       
    }

     内存

    栈的介绍:

     队列是先进先出

     

    /*
    方法在执行过程当中,在JVM中的内存是如何分配的?内存是如何变化的?
       1、方法只定义,不调用,是不会执行的,并且也不会给该方法分配运行所属的内存空间。
          只有在调用这个方法的时候,才会动态的给这个方法分配所属的内存空间。
    
       2、在jvm内存划分上有这样三块主要的内存空间(当然,除了这三块之外还有其它的内存空间)
          *方法区内存
          *堆内存
          *栈内存
       3、关于栈的数据结构:
          *栈 stack ,是一种数据结构
          *数据结构反应的是数据的存储形态。
          *数据结构是独立的学科,不属于任何编程语言的范畴,只不过在大多数编程语言当中要使用数据结构。
          *作为程序员需要提前精通:数据结构  + 算法【计算机专业必修的一门课程】
          *java程序员在不精通数据结构和算法的前提下,也可能进行java开发,因为java有一套庞大的类库支撑。
             说白了就是别人写好了,拿过来直接用,【javase当中集合章节使用了大量的数据结构】
          *常见的数据结构:
             - 数组
             - 队列
             - 栈
             - 链表
             - 二叉树
             - 哈希表/散列表
             ......
       4、方法执行的时候代码片段存在哪里?方法执行的时候执行过程的内存在哪里分配?
          *方法代码片段属于.class字节码文件的一部分,字节码文件在类加载的时候,
          将其放到了方法区当中,所以JVM中的三块只要内存空间中,方法区内存最先有。
          存放了代码片段。
          *代码片段虽然再内存区当中只有一份,但是可以被重复调用。
             没一次调用这个方法的时候,需要给该方法分配独立的活动场所,
             在栈内存中分配。
       5、方法调用的时候,会给该方法分配独立的内存空间,在栈中分配,此时发生压栈动作,
          方法执行结束后,给该方法分配的内存空间全部释放,此时发生图弹栈动作。
             *压栈:给方法分配内存空间push
             *弹栈:释放该方法的内存空间pop
       6、局部变量在栈中存储,局部变量运行阶段内存在栈中分配。
          
    
    
    */
    public class Method01{
       public static void main(String[] args){
    
       }
    }

     继续说内存:

     上面是下面代码执行时,方法分配内存空间的情况

    /*
    重点:方法调用的时候,在参数传递的时候,实际上传递的是变量汇总保存的那个"值"传过去了。
    
    */
    public class Method01{
       public static void main(String[] args){
          int a = 10;
          int b = 20;
          int retValue = sumInt(a,b);
          System.out.println(retValue);//10
       }
       public static int sumInt(int i,int j){
          int result = i + j;
          int num = 3;
          int retValue = divide(result,num);
          return retValue;
       }
       public static int divide(int x,int y){
          int z = x / y;
          return z;
       }
    }

     下面再次根据代码,画一下方法执行时内存的分配情况:

    /*
    
    */
    public class Method01{
       public static void main(String[] args){
          int i = 10;
          method(i);
          System.out.println("method--->"+i);//10
       }
       public static void method(int i){
          i++;
          System.out.println("method--->"+i);//11
       }
    }

     下面开始说方法重载,先不说方法重载,先看看下面的代码有什么缺点:

    /*
    以下代码不使用方法重载机制,不使用overload,分析程序存在缺点。
    */
    public class Method01{
       public static void main(String[] args){
          // 调用方法
          int result1 = sumInt(1,2);
          System.out.println(result1);//3
          double result2 = sumDouble(1.0,2.0);
          System.out.println(result2);//3.0
          long result3 = sumLong(1L,2L);
          System.out.println(result3);//3
       }
       // 定义一个方法,可以计算两个int类型的和
       public static int sumInt(int a,int b){
          return a + b;
       }
       // 定义一个方法,可以计算两个double类型的和
       public static double sumDouble(double a,double b){
          return a + b;
       }
       // 定义一个方法,可以计算两个long类型数据的和
       public static long sumLong(long a,long b){
          return a + b;
       }
    }

    缺点:以上方法,都是计算数据的和,但是我们写了3个不同的方法,方法名称也不想同,程序员调用需要记好多方法名称,那么有没有办法,让这些方法名称相同,

    当传入long类型数据时就是计算long类型数据的和,当传入int或double数据时,计算的就是对应数据类型的和。java语言中有这种机制,叫方法重载机制。

     下面体验一下方法重载的优点:

    /*
    一下代码体验一下方法重载的优点:
    1、调用时只需要记住一个方法名即可,调用比较方便,代码美观。
       前提:功能相似的时候,方法名可以相同
       但是,功能不同的时候尽可能让这两个方法的名字不同。
    
    */
    public class Method01{
       public static void main(String[] args){
          // 调用方法的时候就想调用一个方法一样
          // 参数的类型不同,对应调用的方法不同
          // 此时区分方法,不再依靠方法名了,依靠的是参数的数据类型
          System.out.println(sum(1,2));//3
          System.out.println(sum(1.0,2.0));//3.0
          System.out.println(sum(1L,2L));//3
       }
       public static int sum(int a,int b){
          System.out.println("sum(int,int)");
          return a + b;
       }
       public static double sum(double a,double b){
          System.out.println("sum(double,double)");
          return a + b;
       }
       public static long sum(long a,long b){
          System.out.println("sum(long,long)");
          return a + b;
       }
    }

     详细介绍方法重载:

    /*
    1、方法重载,又被称为overload
    
    2、什么时候考虑使用方法重载?
       *功能相似的时候,尽可能让方法名相同
       但是,功能不同/不相似的时候尽量让方法名不同
    
    3、什么条件满足之后构成了方法重载?
       *在同一个类当中
       *方法名相同
       *参数列表不同
          -数量不同
          -顺序不同
          -类型不同
    
    4、方法重载和什么有关系和什么没有关系?
       *方法重载和方法名字和参数列表有关
       *方法重载和返回值类型无关
       *方法重载和修饰符列表无关
    
    
    */
    public class Method01{
       public static void main(String[] args){
         m1();
         m1(10);
    
         m2(1,2.0);
         m2(2.0,1);
    
         m3(1);
         m3(2.0);
       }
       // 以下两个方法构成重载
       public static void m1(){}
       public static void m1(int a){}
       // 以下两个方法构成重载
       public static void m2(int a,double b){}
       public static void m2(double b,int a){}
       // 以下两个方法构成重载
       public static void m3(int a){}
       public static void m3(double a){}
       // 以下不是方法重载,是发生了方法重复了
       // public static void m4(int a,int b){};
       // public static void m4(int b,int a){};
       // 方法重载和返回值类型无关,以下方法重复,编译报错
       // public static void x(){}
       // public static int x(){return 1;}
       // 方法重载和修饰符列表无关,以下方法重复,编译报错
       // void y(){}
       // public static void y(){}
    
       
    }

     方法重载的使用

    /*
    方法重载的具体应用
    
    
    */
    public class Method01{
       public static void main(String[] args){
          U.p("哈哈");
          U.p(1);
       }
       
    
       
    }
    // 自定义类
    class U{
       public static void p(byte b){
          System.out.println(b);
       }
       public static void p(short b){
          System.out.println(b);
       }
       public static void p(int b){
          System.out.println(b);
       }
       public static void p(long b){
          System.out.println(b);
       }
       public static void p(boolean b){
          System.out.println(b);
       }
       public static void p(float b){
          System.out.println(b);
       }
       public static void p(double b){
          System.out.println(b);
       }
       public static void p(char b){
          System.out.println(b);
       }
       public static void p(String b){
          System.out.println(b);
       }
    }

    我们可以将这个U类前面加上public,单独写个java源文件,编译,之后就可以在其它的java源文件调用了,!!

    U.java

    public class U{
        public static void main(String[] args){
            
        }
        public static void p(byte b){
            System.out.println(b);
        }
        public static void p(short b){
            System.out.println(b);
        }
        public static void p(int b){
            System.out.println(b);
        }
        public static void p(long b){
            System.out.println(b);
        }
        public static void p(boolean b){
            System.out.println(b);
        }
        public static void p(float b){
            System.out.println(b);
        }
        public static void p(double b){
            System.out.println(b);
        }
        public static void p(char b){
            System.out.println(b);
        }
        public static void p(String b){
            System.out.println(b);
        }
    }

    Method01.java

    /*
    方法重载的具体应用
    
    
    */
    public class Method01{
       public static void main(String[] args){
          U.p("哈哈");
       } 
    }

  • 相关阅读:
    linux中断子系统
    注释规范
    linux下C获取文件的大小
    oracle 11g 修改内存示例
    联想system sr650安装windows
    iphone 手机音乐制作
    canon dpp 编辑相机raw软件
    浪潮nf5270m5 安装2012
    三种刻录工具及用法
    centos7.5 连接存储配置iscsi
  • 原文地址:https://www.cnblogs.com/fqh123/p/12114151.html
Copyright © 2011-2022 走看看