【JAVASE系列】05_构造方法,this与static

一、构造方法

1、构造方法简介

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

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

2、构造方法语法结构

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

3、普通方法语法结构

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

4、对于构造方法来说,返回值类型不需要指定,并且也不能写void

只要写上void,那么这个方法就成为普通方法了

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

2、构造方法调用

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

  • new 构造方法名(实参列表)

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

  • 定义一个无参的构造方法:

class User {
    public User(){
        System.out.println("Constructor");
    }
}

public class Test {
    public static void main(String[] args) {
        //调用User类的构造方法来完成对象的创建
        new User();
    }
}
  • 当一个类显示的将构造方法定义出来了,那么系统则不再默认为这个类提供缺省构造器。建议开发中手动为当前类提供构造方法。

  • 构造方法支持重载机制,当在一个类当中编写多个构造方法,则这多个构造方法显然已经构成方法重载机制。

public class User {
    
    //无参构造方法
    public User(){
        System.out.println("Constructor");
    }
    
    //构成了方法重载
    public User(String name){
        System.out.println("带有String类型的构造器");
    }
    
    public User(int i,String name){
        System.out.println("1");
    }
}
public class Test {
    public static void main(String[] args) {
        //以下程序创建了4个对象,只要构造方法函数调用,就会创建对象
        // 并且一定是在“堆内存”中开辟内存空间
        User u1=new User();
        User u2=new User(10);
        User u3=new User("hello");
        User u4=new User(10,"hello");
    }
}

构造方法的作用:

  • 1、创建对象
  • 2、创建对象的同时,初始化实例变量的内存空间(如果是无参的话就赋值为0)

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

实例变量没有手动赋值的时候,系统默认赋值,那么系统默认赋值是在构造方法开辟执行过程中完成开辟的,即完成初始化的。

3、相关快捷键

在这里插入图片描述

在一个类当中元素过多,想要快速查看,在当前的类当中使用Ctrl+O,快捷键,然后输入要查找的元素名称,该名称不一定输入全名称。

在这里插入图片描述

ALT+INSERT:能够弹出generate小框,此时就可以快速生成构造方法,或者生成get和set方法。

在这里插入图片描述

二、参数传递

java语言当中方法调用的时候涉及到参数传递问题,则参数传递实际上是传递的是变量当中保存的具体的值。只不过有时候这个值是一个字面值,有时候这个值是一个java对象的内存地址。

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

例子一:

由于u当中是数值型变量,因此传递过去的是值,不会改变main方法当中的局部变量

class User11{
    //实例变量
    int age;
    //构造方法(有参)
    public User11(int i){
        age=i;
    }
}
public class Test03 {
    public static void main(String[] args) {
        int u=10;
        add(u);
        System.out.println("mian-->"+u);//10
    }
    public static void add(int u) {
        u++;
        System.out.println("add-->"+u);//11
    }
}

例子二:

由于这里使用的是引用型参数,传递过去的是地址,因此会改变你main函数当中的局部变量

class User0{
    //实例变量
    int age;
    //构造方法(有参)
    public User0(int i){
        age=i;
    }
}

public class Test02 {
    public static void main(String[] args) {
        User0 u=new User0(20);
        add(u);
        System.out.println("mian-->"+u.age);//21
    }
    public static void add(User0 u) {
        u.age++;
        System.out.println("add-->"+u.age);//21
    }
}

三、this关键字

  • 1、this是一个关键字,翻译为:这个

  • 2、this是一个引用,this是一个变量,this变量中保存了内存地址指向了自身,this存储在JVM堆内存java对象内部

  • 3、创建100个java对象,每个对象都有this,也就是有100个不同的this

  • 4、this可以出现在实例方法当中,表示this指向当前正在执行这个动作的对象(即this代表当前对象)

  • 5、this在多数情况下是可以省略不写的

  • 6、this不能使用在带有static的方法中

下图当中的this其实就分别指定是C1和C2:
在这里插入图片描述

例:关于顾客购物的行为,由于每个顾客购物的最终结果是不一样的,所以购物这个行为是属于对象级别的。因为每个对象在执行购物这个动作的时候最终结果不同。

  • 没有static关键字的方法被称为实例方法,通过引用.访问
  • 没有static关键字的变量被称为实例变量
  • 当一个行为/动作执行的过程中需要对象参与的,那么这个方法一定要定义为“实例方法”,不能带static关键字

1、调用实例方法和静态方法

public void shopping(){
    System.out.println(this.name+"在购物!");
    //这里的this就代表当前对象
}
  • static的方法调用不需要对象,直接使用类名,所以执行过程当中没有当前对象,所以不能使用this

  • 在static里面不能访问直接访问实例变量和实例方法,因为实例变量和实例方法都需要对象的存在。而static的方法当中是没有this的,即当前对象不存在,自然也就无法访问当前对象的实例变量和实例方法。

//调用实例方法和静态方法
public class Test05 {
    public static void main(String[] args) {

            //调用doSome这个静态方法
            Test05.doSome();
            doSome();
            //调用doOther这个实例方法,需要创建对象
            Test05 t=new Test05();
            t.doOther();
            //doOther:这里不能直接这样写,会报错,因为main方法没有引用,是static的
    }

    //静态方法
    public static void doSome() {
        System.out.println("do Some");
    }

    //实例方法
    public void doOther() {
        System.out.println("do Other");
    }

    //实例方法
    public void run(){
        //在大括号中的代码执行过程当中一定存在“当前对象”的,也就是一定存在this
        //run是实例方法,调用run方法的一定是有对象的
        System.out.println("run");
        doOther();//不会报错,doOther是一个实例方法,实例方法调用必须有对象的存在
        //this在大部分的情况下可以省略
        this.doOther();//完整写法
    }
}

2、this使用的地方

  • 1、可以使用在实例方法当中,代表当前对象【语法格式:this.】

  • 2、可以使用在构造方法当中,通过当前的构造方法来调用其他的构造方法【语法格式:this(实参);】

  • 重点:this()这种语法只能出现在构造函数的第一行,说明一个构造方法调用其他的构造方法只能出现一次

public class Date {
    //属性
    private int year;
    private int month;
    private int day;
    //构造函数

    public Date(int year, int month, int day) {
        this.year = year;
        this.month = month;
        this.day = day;
    }
    //当程序员调用无参的构造方法时,默认创建的日期是“1970-1-1”
    public Date(){
        //以下三段代码可以使用调用有参的构造方法来实现,即在无参的构造方法当中调用有参的构造方法
        //但前提是不能创建一个新的对象
        /*this.year = 1970;
        this.month = 1;
        this.day = 1;*/
        //new Date(1970,1,1);//这样写是错误的,因为这样做创建了一个新的对象

        //这种方式不会创建新的java对象,但同时又可以达到调用其他构造方法的目的。
        this(1970,1,1);//并且这个语句只能出现在构造方法当中的第一行

    }

    //setter and getter
    public int getYear() {
        return year;
    }

    public void setYear(int year) {
        this.year = year;
    }

    public int getMonth() {
        return month;
    }

    public void setMonth(int month) {
        this.month = month;
    }

    public int getDay() {
        return day;
    }

    public void setDay(int day) {
        this.day = day;
    }

    //对外提供一个方法将日期输出到控制台
    public void print(){
        System.out.println(this.year+"年"+this.month+"月"+this.day+"日");
    }
}

3、例子

public class Test04 {
    //带有static的方法
    public static void method1(){
        //要求在这里编写程序调用doSome
        //使用完整方式调用
        Test04.doSome();
        //使用省略方式调用
        doSome();

        //要求在这里编写程序调用doOther
        //使用完整方式调用
        Tset04 t=new Tset04();
        t.doOther();
        //使用省略方式调用

        //访问i
        //采用完整方式访问
        System.out.println(t.i);
        //采用省略方式访问

    }

    //不带static的方法
    public void method2(){
        //要求在这里编写程序调用doSome
        //使用完整方式调用
        Tset04.doSome();
        //使用省略方式调用
        doSome();
        //要求在这里编写程序调用doOther
        //使用完整方式调用
        this.doOther();
        //使用省略方式调用
        doOther();

        //访问i
        //采用完整方式访问
        System.out.println(this.i);
        //采用省略方式访问
        System.out.println(i);
    }

    //主方法
    public static void main(String[] args) {
        //要求在这里编写程序调用method1
        //使用完整方式调用
        Test04.method1();
        //使用省略方式调用
        method1();
        //要求在这里编写程序调用method2
        //使用完整方式调用
        Test04 tt=new Test04();
        tt.method2();
        //使用省略方式调用
    }

    //没有static方法
    int i=10;

    //带有static的方法
    public void doOther(){
        System.out.println("do Other!");
    }

    //带有static方法
    public static void doSome(){
        System.out.println("do Some!");
    }
}

四、static关键字

1、静态变量

关于java当中的static关键字:

  • static表示静态的
  • static修饰的方法是静态方法
  • static修饰的变量是静态变量
  • 所有static修饰的元素都称为静态的,都可以使用类名.的方式访问
  • static修饰的所有元素都是类级别的特征,和具体的对象无关
public class Chinese {
    String id;
    String name;
    static String country="中国";
    public Chinese(String id,String name){
        this.id=id;
        this.name=name;
    }
}
public class Test01 {
    public static void main(String[] args) {

        Chinese zhangsan=new Chinese("1","张三");
        System.out.println(zhangsan.id+","+zhangsan.name+Chinese.country);
        //由于country是静态变量,因此前面使用类名进行引用
        Chinese lisi=new Chinese("2","李四");
        System.out.println(lisi.id+","+lisi.name+Chinese.country);
        
        //这里不会出现空指针异常,因为country是一个静态的变量
        zhangsan=null;
        System.out.println(zhangsan.country);

    }
}

类似于国籍这样的属性,可以提升为整个模板的特征,那么就可以在变量前面添加static关键字修饰

  • 静态变量,在类加载的时候就初始化了,不需要创建对象,内存就开辟了。
  • 静态变量存储在方法区内存当中

什么时候成员变量声明为静态变量?

  • 当所有对象都有这个属性,并且所有对象的这个属性的值是一样的,则建议定义为静态变量,节省内存的开销。
  • 静态变量在类加载的时候初始化,内存在方法区当中开辟,访问的时候不需要创建对象,直接使用类名.变量名即可访问
  • 所有静态的数据都可以采用类名,也可以采用引用,但是建议采用类名
  • 采用引用.的方式访问静态变量的时候,即使引用是null,也不会出现空指针异常,因为访问静态的数据不需要对象的存在

2、静态代码块

1、语法格式

static{
	java语句;
}

2、规则

  • 静态代码块在类加载的时候执行,并且只执行一次
  • 静态代码块在一个类中可以编写多个,并且遵循自上而下的顺序依次执行
public class Test02 {
    static{
        System.out.println("类加载1次");
    }
    static{
        System.out.println("类加载2次");
    }
    static{
        System.out.println("类加载3次");
    }

    public static void main(String[] args) {
        System.out.println("main begin");
    }
}

在这里插入图片描述

3、静态代码块的作用

  • 这和具体的需求有关,例如项目中要求在类加载的时候执行代码完成日志的记录。那么这段记录日志的代码就可以编写到静态代码块当中,完成日志记录。
  • 静态代码块是java为程序员准备的一个特殊的时刻,被称为类加载时刻。若希望在此刻执行一段特殊的程序,则这段程序可以直接放到静态代码块当中。
  • 通常在静态代码块当中完成预备工作,先完成数据的准备工作,例如:初始化连接池,解析配置文件等等。

3、实例代码块

  • 1、实例代码块可以编写多个,也是遵循自上而下的顺序依次执行。
  • 2、实例代码块在构造方法执行之前之前执行。构造方法执行一次,则实例代码块也执行一次。
  • 3、实例代码块也是java为程序员准备的一个特殊的时机,这个特殊的时机被称为:对象初始化时机。
public class Test03 {
    //实例代码块
    {
        System.out.println(1);
    }

    {
        System.out.println(2);
    }

    public static void main(String[] args) {
        System.out.println("main begin");
        new Test03();
        new Test03();
    }
}

在这里插入图片描述

4、main方法重载

  • 带有static的方法和普通方法一样可以进行重载
public class Test04 {
    public static void main(String[] args) {
        main(10);
        main("你好");
    }

    public static void main(String args) {
        System.out.println(args);
    }

    public static void main(int args) {
        System.out.println(args);
    }
}

在这里插入图片描述

5、静态方法

方法什么时候定义为静态的方法

  • 方法描述的是动作,当所有的对象执行这个动作的时候,最终产生的影响是一样的,那么这个动作已经不再属于某一个对象动作了,可以将这个动作提升为类级别的动作。
  • 静态方法当中无法直接访问实例变量和实例方法。
  • 大多数等等都定义为实例方法,一般一个行为或者一个动作在发生的时候,都需要对象的参与。但是也有例外:大多数“工具类”中的方法都是静态方法,因为工具类就是方便编程,为了方便方法的调用,不需要new对象。
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

温欣2030

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值