3.1. 类与对象

一. 方法

在Java语言当中应该有这样一个机制:

  • 某个功能代码只需要写一遍
  • 要使用这个功能,只需要给这个功能传递具体的数据
  • 这个功能完成之后返回一个最终的结果。

这样代码就可以重复使用了,提高代码的复用性。【这就是 “方法” 】

使用这个方法我们称为 “调用/invoke”

1. 方法的本质

方法就是一段代码片段,并且这段代码片段可以完成某个特定的功能,并且可以被重复使用。 方法,对应的英语单词:Method,在 C 语言中叫做函数:Function、

方法定义在类体中,在一个类当中可以定义多个方法,方法编写的位置没有先后顺序,可以随意。

方法体中不能再定义方法!!!!!!

2. 方法的基础语法

2.1. 语法结构

[修饰符列表] 返回值类型 方法名(形式参数列表){
    方法体;
}

2.2 对以上语法结构进行解释说明:

2.2.1. 关于修饰符列表

  • 可选项,不是必须的
  • 目前统一写成public static
  • 方法的修饰符列表当中”有static关键字”的话,怎么调用这个方法?
    类名.方法名(实际参数列表);

2.2.2. 返回值类型

1、什么是返回值?

一个方法是可以完成某个特定功能的,这个功能结束之后大多数都是需要返回最终执行结果的,执行结果可能是一个具体存在的数据。而这个具体存在的数据就是返回值。

2、返回值类型?

返回值就是一个具体存在的数据,数据都是有类型的,此处需要指定的是返回值的具体类型。

3、返回值类型都可以指定哪些类型呢?

java任意一种类型都可以,包括基本数据类型和所有的引用数据类型。

4、也可能这个方法执行结束之后不返回任何数据,java中规定,当一个方法执行结束之后不返回任何数据的话,返回值类型位置必须编写:void 关键字。

5、返回值类型可以是: byte,short,int,long,float,double,boolean,char,string,void…

6、返回值类型若不是 void,表示这个方法执行结束之后必须返回一个具体的数值。当方法执行结束的时候,没有返回任何数据的话,编译器报错。怎么返回值呢?代码怎么写呢?“return 值;”并且要求“值”的数据类型必须和“方法的返回值类型”一致,不然编译器报错。

7、返回类型是void的时候,在方法体当中不能编写“return 值;”这样的语句。但是要注意可以编写“return;”这样的语句。

8、只要带有关键字的语句执行,return语句所在的方法结束。【不是JVM结束,是return所在的方法结束】

2.2.3. 方法名

  • 只要是合法的标识符就行
  • 方法名最好见名知意
  • 方法名最好是动词
  • 方法名首字母要求是小写,后面每个单词首字母大写

2.2.4 形式参数列表:简称形参

  • 形参是局部变量:int a;double b;…
  • 形参的个数可以是 0~N 个
  • 多个形参之间用“逗号”隔开
  • 形参中起决定性作用的是形参的数据类型,形参的名字就是局部变量的名字。
  • 方法在调用的时候,实际给这个方法传递的真实数据被称为:实际参数,简称实参
  • 实参列表和形参列表必须满足:
    1. 数量相同
    2. 类型对应相同

2.2.5. 方法体必须由大括号括起来,方法体中的代码有顺序

实例:

//public表示公开的
//class表示定义类
//MethodTest是一个类名
public class MethodTest{ //表示定义一个公开的类,起名MethodTest,由于是公开的类,所以源文件名必须为:MethodTest
    //类体
    //类体中不能出现直接编写java语句,除声明变量之外
    //方法出现在类体当中

    //方法
    //public表示公开的
    //static表示静态的
    //void表示方法执行结束后不返回任何数据
    //main是方法名:主方法
    //(String[] args):形式参数列表,其中String[]是一种引用数据类型,args是一个局部变量的变量名
    //所以以下只有args这个局部变量的变量名是随意的
    //主方法就需要这样固定编写,这是程序的入口。【SUN公司规定的,必须这样写】
    public static void main(String[] args){

    //这里的程序是一定会执行的
    //main方法是JVM负责调用的,是一个入口的位置
    //从这里作为起点开始执行程序
    //既然是这样,我们就可以在这里编写java语句来调用其他方法
    //调用MethodTest的sum方法,传递两个实参
    MethodTest.sum(10,20);//(10,20)实参列表

    //注意:方法体当中的代码是有顺序的,遵循自上而下的顺序以此执行
    //上一行代码的程序执行不结束,无法执行下一行代码。    
    
    //一个方法可以被重复使用,重复调用
    int a=100;
    MethodTest.sum(a,500);// (a,500)实参列表

    //再次调用方法
    int k=90;
    int f=10;
    MethodTest.sum(k,f);//(k,f)实参列表
    }

    //自定义方法,不是程序的入口
    //方法的作用:计算两个int类型数据的和,不要求返回结果,但是要求将结果直接输出到控制台
    //修饰符列表:public static
    //返回值类型:void
    //方法名:sum
    //形式参数列表:(int x,int y)
    //方法体:主要任务是求和之后输出计算结果
    public static void sum(int x, int y){
        System.out.println(x+'+'+ y +'='+ (x+y))
    }
}

3. 方法怎么调用?

方法只定义不去调用是不会执行的,只有在调用的时候才会执行。
语法规则:《方法的修饰符列表当中有static》

类名.方法名(实参列表);<这是一条java语句,表示调用某个类的某个方法,传递这样的实参。>

二. Java语言的方法

实例

public class MethodTest01(){
    public static void sum(int a,int b){
        System.out.println(a+"+"+b+"="+(a+b));
        //调用doSome方法
        MethodTest.doSome();
    }
    //主方法
    public static void main(String[] args){
        //调用sum方法
        MethodTest.sum(1,2);
    }

    public static void doSome(){
        System.out.println("do some!");
    }
}

以上代码了看出:方法的调用不一定在main方法当中。只要是程序可以执行到的位置,都可以调用其他的方法。

1. 方法调用的时候实参和形参要求个数对应相同,数据类型对应相同。

类型不同的时候要求能够进行相应的自动类型转换

public class MethodTest02(){
    //主方法
    public static void main(String[] args){
        MethodTest02.sum();//编译错误:参数数量不同
        MethodTest02.sum(true,false);//编译错误:实参和形参的类型不是对应相同的
        MethodTest02.sum(10L,20L);//编译通过
        MethodTest02.sum(10,20);//编译通过:存在自动类型转换:int-->long
        MethodTest02.sum(3.0,20);//编译错误:参数类型不是对应相同的
        MethodTest02.sum((long)3.0,20);//编译通过
    }

    public static void sum(long a,long b){
        System.out.println(a+"+"+b+"="+(a+b));

    }
}

2. 方法调用

1、方法的修饰符列表当中有static字,完整的调用方法是:类名 . 方法名(实参列表)
2、但是,有时候 “ 类名.” 可以省略,什么情况下可以省略呢?

  • 对于方法的修饰符列表当中有static关键字的:“类名.” 可以省略不写。
  • 调用同个类中的方法可省略不写
public class MethodTest03(){

    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("m2 over");
        }
        
    public static void m2(){
        System.out.println("m2 begin");
        m3();
        System.out.println("m2 over");
        }
        
    public static void m3(){
        System.out.println("m3 begin");
        System.out.println("m3 over");
    }
}

输出结果:

image.png

方法中的代码是自上而下的顺序依次执行的

2.1. 方法的返回值类型不是void的时候

  • 返回值类型不是void的时候:要求方法必须保证百分百的执行“return 值;”这样的语句来完成值的返回。没有这个语句编译器会报错。
  • 一个方法有返回值的时候,当我们调用这个方法的时候,方法返回了一个值,对于调用者来说,这个返回值可以选择接收,也可以选择不接收。
public class MethodTest04(){

    public static void main(String[] args){
        //调用方法
        divide(10,3);//这里没有接收这个方法的返回数据
        
        //这里接收返回值
        //采用变量接收
        //变量的数据类型需要和返回值的数据类型相同,或者可以自动类型转换
        int i = divide(10,3);
    }
    
`    /*
    需求:
        请定义并实现一个方法,该方法可以计算两个int类型数据的商,
        要求将最终计算结果返回给调用者。
    */

    //编译错误:缺少返回值
    /*public static int divide(int a, int b){
        return;
    }

    //编译错误:方法定义的时候要求返回一个int类型,此时返回布尔类型,类型不兼容
    public static int divide(int a, int b){
        return true;
    }

    //可以:但是具体方法体中编写的代码无法满足当前的需求
    public static int divide(int a, int b){
        return 1;
    }
    
    public static int divide(int a, int b){
        int c=a/b;
        return c;
    }*/
    
    public static int divide(int a, int b){
        return a/b;
    }
}

2.2. 深入return语句

  • 带有return关键字的java语句只要执行,所在的方法执行结束。
  • 在“同一个作用域”当中,return语句下面不能编写任何代码,因为这些代码永远都执行不到,所以编译报错。
public class MethodTest05(){

    public static void main(String[] args){
        int reValue=m();
        System.out,println(reValue);
    }
    
    //编译报错:缺少返回语句,以下程序编译器认为无法百分百保证“return 1;”会执行
    /*public static int m(){
        int a=10;
        if(a>3){
            return 1;
        }
    }
    */

    public static int m(){
        int a=10;
        if(a>3){
            return 1;
            //这里不能编写代码,编译错误,因为无法执行访问的语句
            //System.out.println("Hello");
        }
        //这里的代码可以执行
        System.out.println("Hello");
        return 0;
    }

}

在返回值类型是void的方法当中使用“return;”语句。“return;”语句当中出现在返回值为void的方法当中主要是为了终止方法的执行。

return;直接终止方法;break只是终止循环。  
return更强

三. 方法执行过程中内存分析

1. 方法在执行过程当中,在JVM中的内存是如何分配的呢,内存是如何变化的?

  • 方法只定义,不调用,是不会执行的,并且在JVM中也不会给该方法分配“运行所属”的内存空间。只有在调用这个方法的时候,才会动态的给这个方法分配所属的空间。


  • 在JVM内存划分上有这样三块主要的内存空间:

    1. 方法区内存
    2. 堆内存
    3. 栈内存
  • 关于栈数据结构:

    1. 栈:stack,是一种数据结2、数据结构反应的是数据的存储形态。
    2. 数据结构是独立的学科,不属于任何编程语言的范畴,只不过在大多数编程语言当中要使用数据结构。
    3. 作为程序员需要提前精通:数据结构+算法【计算机专业必修的一门语言】
    4. 常见的数据结构:数组、队列、栈、链表、二叉树、哈希表…
  • 方法代码片段存在哪里?方法执行的时候执行过程的内存在哪里分配?

    1. 方法片段属于.class字节码文件的一部分,字节码文件在类加载的时候,将其放到了方法区当中。所以JVM中的三块主要的内存空间中的方法区内存最先有数据,存放了代码片段。
    2. 代码片段虽然在方法区内存当中只有一份,但是可以被重复调用。每一次调用这个方法的时候,需要给该方法分配独立的活动场所,在栈内存中分配。【栈内存中分配方法运行的所属空间】
  • 方法在调用的时候,会给该方法分配独立的内存空间,在栈中分配,此时发生压栈动作,方法执行结束之后,给该方法分配的内存空间全部释放,此时发生弹栈动作。

    • 压栈:给方法分配内存。
    • 弹栈:释放该方法的内存空间。
  • 局部变量在栈中存储。局部变量在运行阶段内存在栈中分配。


image.png

栈内存:

  1. 是为 java 方法提供运行空间的
  2. 方法一旦被调用就会在栈中创建对应的栈帧,而方法的整个执行过程就是方法对应的栈帧从入栈到出栈的过程。换言之,就是方法被调用进栈(压栈入栈),方法执行结束出栈(弹栈)。
  3. 栈是先进后出后进先出(先被调用的方法最后结束,后被调用的方法最先结束)
  4. 栈中的变量都是属于方法的,所以都是局部变量,且局部变量必须初始化值。
  5. 栈生命周期与其所属线程的生命周期一致,可以认为栈具有自动销毁机制。

堆内存:

  1. 是为实体对象来开辟空间的,换言之就是实体对象的空间都在堆中开辟。凡是被 new 出来的都是对象。
  2. 堆中的变量是对象变量,因为是属于对象的,且是随着对象的创建而产生随着对象的销毁而销毁。
  3. 堆中的变量(对象变量)都有默认值:
    • 整数:0
    • 浮点型:0.0
    • 布尔型:false
    • char型:”
    • 对象:null
  4. 堆没有自动销毁机制,它里面的垃圾由垃圾回收器负责收集(通过收集算法判断哪个对象属于垃圾然后再清理)
  5. 堆中的空间都有一个16进制的首地址作为地址进行区分。

方法区:

方法区中存放已经被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。
常量是存放在方法区中的运行时常量池中的。

重点:方法调用的时候,在参数传递的时候,实际上传递得是变量中保存的那个“值”传过去了。

四. 方法重载(overload)

  • 功能虽然不同,但是“功能相似”的时候,方法重载机制可以让相似的方法就像在用一个方法一样。【Java支持这种机制而有些语言则不支持,例如JavaScript】
  • 功能相似的时候,方法名可以相同。

1. 什么时候考虑使用方法重载?

  • 功能相似的时候,尽可能让方法名相同【但是功能不同/不相似的时候,尽可能让方法名不同】

2. 什么条件满足之后构成了方法重载

  • 在同一个类当中
  • 方法名相同
  • 参数列表不同:
    1. 数量不同: public static void m1(){} 与 public static void m1(int a){}
    2. 顺序不同: public static void m2(int a,double b){} 与 public static void m2(double a, int b){}
    3. 类型不同: public static void m3 (int x){} 与 public static void m3(double x){}
方法重复,编译错误。
public static void m4(int a,int b){}
public static void m4(int b,int a){}

3. 方法重载和什么有关系,和什么没有关系

  • 方法重载和方法名+参数列表有关系
  • 方法重载和返回值类型无关
  • 方法重载和修饰符列表无关

五. 方法递归

  • 什么是递归?
    即:方法自身调用自身。
a(){
    a();
}
  • 递归是很耗栈内存的,递归算法可以不用的时候尽量别用。
  • 以下程序运行的时候发生这样的一个错误【不是异常,是错误 error】:
    Java. Lang. StackOverflowError
    栈内存溢出错误
    错误发生无法晚挽回,只有一个结果。就是 JVM 停止工作。
  • 递归必须有结束条件,没有结束条件一定会发生栈内存溢出错误。
  • 递归即使有了结束条件,即便结束条件是正确的,也可能会发生栈内存溢出错误,因为递归太深了。

注意:

  • 递归可以不使用尽量别用。
  • 但是有些情况下该功能的实现必须依靠递归方式。

例子

递归计算前n个数的和:
public class RecursionTest01{
    publci static void main(String[] args){
        int n=4;
        int reValue=sum(n);
        System.out.println(reValue);
    }
    
    public static int sum(int n){
        if(n==1){
            return 1;
        }
        return n+sum(n-1);    
    }
}
递归计算n的阶乘:
public class RecursionTest02{
    publci static void main(String[] args){
        int n=5;
        int reValue=method(n);
        System.out.println(reValue);
    }
    public static int method(int n){
        if(n==1){
            return 1;
        }
        return n*method(n-1);
    }
}

六. 面向对象和面向过程的区别

  • 面向过程:
    主要关注点是:实现的具体过程,因果关系【集成显卡的开发思路】
    优点: 对于业务逻辑比较简单的程序,可以达到快速开发,前期投入成本较低。
    缺点: 采用面向过程的方式开发很难解决非常复杂的业务逻辑,另外面向过程的方式导致软件元素之间“耦合度”非常高,只要其中一环出现了问题,整个系统受到影响,导致最终的软件扩展力差。另外,由于没有独立体的概念,所以无法达到组件复用。


  • 面向对象:
    主要关注点是:主要关注对象【独立体】能完成哪些功能。【独立显卡的开发思路】
    优点: 耦合度低,扩展能力强。更容易解决现实世界当中更复杂的业务逻辑,组件复用性强。
    缺点: 前期投入成本高,需要进行独立体的抽取,大量的系统分析与设计。


C 语言是纯面向过程的,C++半面向对象、Java 纯面向对象

七. 面向对象的三大特征

  • 封装
  • 继承
  • 多态

注:所有面向对象的编程语言都有这三大特征。

采用面向对象的方式开发一个软件,生命周期当中:【整个生命周期中贯穿使用OO面向对象方式】

  • 面向对象的分析:OOA
  • 面向对象的设计:OOD
  • 面向对象的编程:OOP

八. 类的对象的概念

什么是类?

  • 类在现实世界当中是不存在的,是一个模板,是一个概念。是人类大脑思考抽象的结果。
  • 类代表了一种事物。
  • 在现实世界中,对象 A 与对象 B 之间具有共同特征,进行抽象总结出一个模板,这个模板被称为类。

什么是对象?

  • 对象是实际存在的个体。现实世界当中实际存在。

软件开发的过程:

  • 程序员先观察现实世界,从现实世界当中寻找对象
  • 寻找了 N 个对象之后,发现所有的对象都有共同特征
  • 程序员在大脑中形成一个模板【类】
  • Java 程序员可以通过 java 代码来表述这个类
  • Java 程序中有了类的定义
  • 然后通过类就可以创建对象
  • 有了对象之后,可以让对象直接协作起来形成一个系统。

类–【实例化】->对象

对象又被称为实例/instance

对象–【抽象】–>类

重点:

  • 类描述的是对象的共同特征。
  • 共同特征例如:身高特征
    这个身高特征在访问的时候,必须先创建对象,通过对象去访问这个特征。因为这个特征具体的某个对象上之后,值不同。有的对象身高 1.80,有的对象身高 2.80.

一个类主要描述什么信息呢?

一个类主要描述的是:状态+动作。 状态信息:名字、身高、性别、年龄 动作信息:吃、喝、玩、乐

  • 状态–>一个类的属性
  • 动作–>一个类的方法
类{
    属性; //描述对象的状态信息
    方法; //描述对象的动作信息
    }

注意:状态和动作当具体到某个对象上之后,发现最终的结果可能不一样。

九. 类的定义

语法结构:

[修饰符列表] class 类名{
    属性;
    方法;
}

重点:属性通常是采用一个变量的形式来完成定义的。

定义一个类,类名Student
Student是一个类。代表了所有的学生对象,是一个学生模板
public class Student{//定义一个公开的类

//属性【描述的是对象的状态信息】
//属性通常采用变量的方式来定义
//在类体当中,方法体之外定义的变量被称为“成员变量”
//成员变量没有赋值,系统赋默认值:一切向0看齐。
int no;//学号
String name;//姓名
boolean sex;//性别
int age;//年龄
String address;//住址
//方法
//方法描述的是对象的动作信息
//当前例子就只描述属性,不描述方法。
}

Java语言中所有的class都属于引用数据类型。

十. 对象的创建和使用

public class OOTest01{
    publci static void main(String[] args){
        int i=10;
        Student s = new Student();

        int StuNo=s.no;
        System.out.println("学号 =" + StuNo);//0【默认值】
        System.out.println("学号 =" + s.no);//0【默认值】
        s.no=10;
        System.out.println("学号 =" + s.no);//10

        //再通过类实例化一个全新的对象
        //stu是一个引用
        //stu同时也是一个局部变量
        //Student是变量的数据类型
        Student stu = new Student();
        System.out.println("学号 =" + stu.no);// 0

        System.out.println("学号 =" + Student.no);//编译错误,不能直接采用“类名”的方式访问
        //因为no是实例变量,对象级别的变量,变量存储在java对象的内部,必须先有对象,通过对象才能访问no这个实例变量,不能直接通过“类名”访问
    }
}
//学生类
//学生类是一个模板
//描述了所有学生的共同特征【状态+行为】
//当前类只描述学生的状态信息【属性】
public class Student{
//类体=属性+方法

//属性【存储数据采用变量的形式】
//由于变量定义在类体当中,方法体之外,这种变量称为成员变量
//所有学生都有学号信息
//但是每一一个学生的学号都是不同的
//所以要访问这个学号必须先创建对象,通过对象去访问学号信息
//学号信息不能直接通过"类"去访问,所以这种成员变量又被叫做:实例变量
//对象又被称为实例,实例变量又被称为对象变量。【对象级别的变量】
//不创建对象,这no变量的内存空间是不存在的,只有创建了对象,这个no变量内存空间才会创建。
int no;
String name;//姓名
boolean sex;//性别
int age;//年龄
String address;//住址
  • 通过一个类可以实例化 N 个对象,
  • 实例化对象的语法:new 类名 ()
  • New 是 java 语言当中的一个运算符
  • New 运算符的作用是创建对象,在 JVM 堆内存当中开辟新的内存空间
  • 方法区内存:在类加载的时候,class 字节码代码片段被加载到该内存空间当中。
  • 栈内存(局部变量):方法代码片段执行的时候,会给该方法分配内存空间,在栈内存中压栈。
  • 堆内存:new 的对象在堆内存中存储

对于 Student s = new Student ();

  • Student 是一个引用数据类型
  • S 是一个变量名
  • New Student () 是一个学生对象
  • S 是一个局部变量【在栈内存中存储】:引用
  • 什么是对象? New 运算符在堆内存中开辟的内存空间称为对象。
  • 什么是引用? 引用是一个变量,只不过这个变量中保存了另一个 java 对象的内存地址。
  • Java 语言当中,程序员不能直接操作堆内存,java 中没有指针,不像 C 语言
  • Java 语言当中,程序员只能通过“引用”去访问堆内存当中对象内部的实例变量。

1. 访问实例变量的语法格式:

读取数据:引用.变量名
修改数据:引用.变量名 = 值
int StuNo=s.no;

局部变量在栈内存中存储
成员变量中的实例变量在堆内存的java对象内部存储

实例变量是一个对象一份,100个对象有100份

public class Customer
{
    int id;
}

public class OOTest02
{
    public static void main(String[] args){
        Customer c= new Customer();
        System.out.println(c.id); //0

        c=null;
        //以下程序编译可以通过,因为符合语法
        //运行出现空指针异常
        //空引用访问“实例”相关的数据一定会出现空指针异常
        //java.lang.NullPointerException
        System.out.println(c.id);
    }
}

“实例”相关的数据表示:这个访问的时候必须有对象的参与。这种数据就是实例相关的数据。

重点: 实例变量必须先创建对象,通过引用的方式访问,不能直接使用 类名. 的方式访问

十一. 内存分析

  1. JVM ( Java 虚拟机) 主要包括三块内存空间. 分别是: 栈内存、堆内存、方法区内存。


  2. 堆内存和方法区内存各有 1 个。一个线程一个栈内存。


  3. 方法调用的时候, 该方法所需要的内存空间在栈内存中分配, 称为压栈。方法执行结束之后, 该方法所属的内存空间释放, 称为弹栈。


  4. 栈中主要存储的是方法体当中的局部变量。


  5. 方法的代码片段以及整个类的代码片段都被存储到方法区内存当中, 在类加载的时候这些代码片段会载入。


  6. 在程序执行过程中使用 new 运算符创建的 java 对象. 存储在堆内存当中。对象内部有实例变量, 所以实例变量存储在堆内存当中。


  7. 变量分类:

    • 局部变量[方法体中声明]
    • 成员变量[方法体外声明]
    • 实例变量[前边修饰符没有 static]
    • 静态变量[前边修饰符中有 static]
  8. 静态变量存储在方法区内存当中。[先背会]


  9. 三块内存当中变化最频繁的是栈内存, 最先有数据的是方法区内存, 垃圾回收器主要针对的是堆内存。


  10. 垃圾回收器[自动垃圾回收机制、GC 机制]什么时候会考虑将某个 java 对象的内存回收呢?

    • 当堆内存当中的 java 对象成为垃圾数据的时候. 会被垃圾回收器回收。
  11. 什么时候堆内存中的 java 对象会变成垃圾呢?

    • 没有更多的引用指向它的时候。这个对象无法被访问, 因为访问对象只能通过引用的方式访问。

十二. 构造方法

1. 关于java类中中的构造方法:

1、构造方法又被称为构造函数/构造器/Constructor

2、构造方法语法结构: [修饰符列表] 构造方法名 (形式参数列表){ 构造方法体; }

3、回顾普通方法的语法结构: [修饰符列表] 返回值类型方法名 (形式参数列表){ 方法体; }

4、对于构造方法来说,“返回值类型”不需要指定,并且也不能写 void。只要写上 void,那么这个方法就成为普通方法了。

5、对于构造方法来说,构造方法的方法名必须与类名保持一致。

6、构造方法的作用?

  • 构造方法存在的意义是,通过构造方法的调用,可以创建对象。

7、构造方法应该怎么调用?

  • 普通方法是这样调用的:方法修饰符中有 static 的时候:类名. 方法名(实参列表)、方法修饰符列表中没有 static 的时候:引用. 方法名(实参列表)
  • New 构造方法名(实参列表)

8、构造方法调用执行之后,有返回值吗?

  • 每一个构造方法实际上执行结束之后都有返回值,但是这个“return 值;”这样的语句不需要写。构造方法结束的时候 java 程序自动返回值。
  • 并且返回值类型是构造方法所在类的类型。由于构造方法的返回值类型就是类本身,所以返回值类型不需要编写。

9、注释和取消注释:Ctrl + /、多行注释:ctrl + shift +/\

10、当一个类中没有定义任何构造方法的话,系统默认给该类提供一个无参数的构造方法,这个构造方法被称为缺省构造器。

11、当一个类显示的将构造方法定义出来了,那么系统则不再默认为这个类提供缺省构造器。建议开发中手动的为当前类提供无参数的构造方法。因为无参数的构造方法太常用了。

2. 构造方法的作用

  • 1、创建对象
  • 2、创建对象的同时,初始化实例变量的内存空间。

成员变量之实例变量,属于队象级别的变量,这种变量必须先有对象才能有实例变量。

实例变量没有手动赋值的时候,系统默认赋值,那么这个系统默认赋值是在什么时候完成的呢?是在类加载的时候么?

  • 不是的,因为类加载的时候只加载了代码片段,还没来得及创建对象。所以此时实例变量并没有初始化。
  • 实际上,实例变量的内存空间是在构造方法执行过程当中完成开辟的,完成初始化的。
  • 系统在默认赋值的时候,也是在构造方法执行过程当中完成的赋值。

十三. 对象与引用

1. 对象与引用的概念

  • 对象:目前在使用 new 运算符在堆内存中开辟的内存空间称为对象。
  • 引用:是一个变量,不一定是局部变量,还可能是成员变量。引用保存了内存地址,指向了堆内存当中的对象。
  • 所有访问实例相关的数据,都需要通过“引用.”的方式访问,因为只有通过引用才能找到对象。
  • 只有一个空的引用,访问对象的实例相关的数据会出现空指针异常。

参数传递

主要研究和学习的是方法在调用的时候,涉及到参数传递的问题,到底是怎样传递数据的呢?

  • 值传递
Int i = 10;
Int j = i ; i 传递给 j,实际上只是将 i 变量中保存的 10 传递给了 j,j 实际上是一个全新的内存空间
User u = 0 x 1234;
User u 2 = u;
U 传递给 u 2,实际上是将 0 x 1234 这个值赋给 u 2 了,u 和 u 2 实际上是两个不同的局部变量,但是他们这两个变量指向堆内存中的同一个 java 对象。

Java 语言当中方法调用的时候涉及到的参数传递的问题

参数传递实际上传递的是变量中保存的具体值

例一:

public class Test01()
{
    public static void main(String[] args){
        
        //int i = 10;
        //add(i)等同于:add(10)
        int i = 10;
        add(i);//add方法调用的时候,给add方法传递了一个变量i,实际上传递的是变量中保存的具体值
        System.out.println("main-->"+ i );
    }

    public static void add(int i){
        i++;
        System.out.println("add-->"+ i);
    }
}

编译结果:

image.png

例二:

public class Test02(){
 public static void main(String[] args){
        User u = new User(20);
      
       //User u =0x1234;
       //add(u)等同于:add(0x1234)
        add(u);//传递u给add方法的时候,实际上传递的是U变量中保存的值,只不过这个值是一个java对象的内存地址
        System.out.println("main-->"+ u.age);
    }

    public static void add(User u ){
        u.age++;
        System.out.println("add-->"+ u.age);
    }
}

class User
{
    int age;
    public User(int i){
        age = i;
    }
}

编译结果:

image.png

最终结论:

方法调用的时候,涉及到参数问题,传递的时候,java只遵循一种语法机制,就是将变量中保存的“值”传递过去了,只不过有时候这个值是一个字面值10,有的时候是另一个java对象的内存地址0x1234。

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇