全面理解java中的构造方法以及this关键字的用法(超详细)

Hello,各位铁汁们!我是小🐟儿哈!今天我又来更新我的Java基础学习博客了。

本篇主要内容概述:

1、🍚如何用构造方法初始化对象

2、🍚为啥要有this这个关键字

3、🍚this.属性名访问成员变量、成员方法

4、🍚this.方法名 || this.()的用法

目录

初识构造方法 

构造方法的使用 

初识this 

this.xx的用法

this()用于构造函数的调用


初识构造方法 

我们上篇讲了java中类的创建,那么让我们来实战演练一下:创建一个学生类,里面有学生的基本信息,包括姓名、性别、年龄、学号,你可能会写出这样的代码:

class Student {
    String name;
    String gender;
    int age;
    long studentID;
}
public class TestDemo2 {
    public static void main(String[] args) {
        Student stu1 = new Student();
        stu1.name = "张三";                  // 给stu1对象的各个成员变量赋值
        stu1.gender = "男";
        stu1.age = 19;
        stu1.studentID = 231245431;
        // 打印输出
        System.out.println("姓名:" + stu1.name + " 性别:" + stu1.gender + " 年龄:" + stu1.age + " 学号:" + stu1.studentID);
    }
}

 🍑但你在写的时候,是不是感觉给对象的成员变量一个一个的赋值太繁琐,能不能一下子就把值赋好呢?还真能,用Java中的构造方法就能做到这一点

那么快来看看什么是构造方法吧!

🍑构造方法是类的一种特殊方法,用来初始化类的一个新的对象,在创建对象(new 运算符)之后自动调用,Java中的每个类都有一个默认的构造方法,并且可以有一个以上的构造方法。

Java 构造方法有以下特点:

  • 方法名必须与类名相同
  • 可以有 0 个、1 个或多个参数
  • 没有任何返回值,包括 void
  • 默认返回类型就是对象类型本身
  • 只能与 new 运算符结合使用


🔔值得注意的是,如果为构造方法定义了返回值类型或使用 void 声明构造方法没有返回值,编译时不会出错,但 Java 会把这个所谓的构造方法当成普通方法来处理

🍑下面就是一个构造方法的使用例子

class Student {
    String name;   //学生类的属性
    int age;
    public void eat() {
        System.out.println(name + "在吃饭");   // 学生类的行为(方法)
    }
    public Student() {
        System.out.println("这是自定义的一个不带参数的构造方法");
    }
}
public class TestDemo3 {
    public static void main(String[] args) {
        Student student1 = new Student();
    }
}

看到输出结果,你是不是感到:咦?不对啊,我的main方法里明明就只是实例化了一个对象啊😮!我没输出啊,为啥还会输出构造方法中的内容啊

  Student student1 = new Student();

🍑原因就是:当类的对象被创建时,该构造方法将被自动调用

🍑其实我们在用new关键字实例化对象时 , 程序一定干了这两件事(但可能不只有这两步)

  1. 📝在堆区分配对象需要的内存
  2. 📝调用合适的构造方法

🍑看到这,你可能又有问题了,我们之前实例化对象的时候明明没定义构造方法呀!怎么能说实例化对象时程序一定调用构造方法呢?

😊是这样的,当一个类中没有提供任何构造方法,系统默认提供一个无参数的构造方法,就像这样

Student() {
}

🔔 但如果类中显式地定义了一个或多个构造方法,则系统不再提供默认构造方法。
 

在一个类中,与类名相同的方法就是构造方法。每个类可以具有多个构造方法,但要求它们各自包含不同的方法参数,比如这样:

Student() {
    System.out.println("这是自定义的一个没有参数的构造方法");
}
Student(String name) {
    this.name = name;
    System.out.println("这是自定义的带有一个参数的构造方法");
}

  • 🌻 该示例就定义了两个构造方法,分别是无参构造方法和有参构造方法。
  • 🌻如果在一个类中定义多个具有不同参数的同名方法,称作方法的重载。
  • 🌻这两个构造方法的名称都与类名相同,均为Student。在实例化该类时可以调用不同的构造方法进行初始化。


构造方法的使用 

 那么,就让我们来看一下,调用构造方法是怎样解决上面那个麻烦的问题的,嘻嘻😎

class Student {
    String name;
    String gender;
    int age;
    long studentID;
    // 该构造方法可由IDEA自动生成
    public Student(String name, String gender, int age, long studentID) {  
        this.name = name;
        this.gender = gender;
        this.age = age;
        this.studentID = studentID;
    }
}
public class TestDemo2 {
    public static void main(String[] args) {
        Student stu1 = new Student("张三", "男", 19, 231245431);
        System.out.println("姓名:" + stu1.name + " 性别:" + stu1.gender + " 年龄:" + stu1.age + " 学号:" + stu1.studentID);
    }
}

 🍑怎么样,是不是一下子就把值赋好,哈哈😉,并且类中的构造方法的定义还不用自己写,在IDEA有相应的快捷键可以自动生成,就像这样:

在IDEA里点击鼠标右键,弹出窗口-->在窗口中选择Generate-->点进去后选择Constructo-->按住ctrl键的同时点击鼠标,把那几个参数全选上,点击OK😎

嘻嘻,是不是IDEA帮你自动生成了🥰,方便吧


初识this 

 不过,构造方法中的this.name是什么意思啊,以前不都是 "对象名.成员变量" 吗,来接下来,我们慢慢说这个this到底是什么东东🤔

首先,咱先来看一段代码😉

class Date {
    int year;
    int month;
    int day;
    // 通过构造函数传参来赋值
    public Date(int year, int month, int day) {
        year = year;
        month = month;
        day = day;
    }

    public void printDate() {
        System.out.println(year + "/" + month + "/" + day);
    }
}

public class TestDemo2 {
    public static void main(String[] args) {
        Date date1 = new Date(2022, 4, 2);
        date1.printDate();
    }
}

这段代码有什么问题吗?细心的同学可能以经发现了 :在Date类中,传入构造方法的参数名称和Date的成员变量名字相同🤔,那么在Date类中的构造方法中就会出现一个问题:

public Date(int year, int month, int day) {
        // 那函数体中到底是谁给谁赋值?成员变量给成员变量?参数给参数?参数给成员变量?
        // 成员变量给参数?估计自己都搞不清楚了
        year = year;            // 当传入的参数相同是怎么办!
        month = month;
        day = day;
}

大家觉得在上面的main方法中会输出什么?是2022/4/2吗😉? 

让我们一起来看看吧?

😮输出竟然是0/0/0,好像我们根本没给year,month,day赋值似的? 

其实当构造方法的参数与类所定义的属性同名时,对于方法中的year = year,虚拟机不清楚在这里year到底是传过来的参数还是对象的成员变量,那么为了让虚拟机知道我们是把参数2022赋值给当前对象的成员变量year,我们就需要借助java中this这个关键字:

class Date {
    int year;
    int month;
    int day;
    // 添加了this关键字的构造函数
    public Date(int year, int month, int day) {
        this.year = year;
        this.month = month;
        this.day = day;
    }

    public void printDate() {
        System.out.println(year + "/" + month + "/" + day);
    }
}

public class TestDemo2 {
    public static void main(String[] args) {
        Date date1 = new Date(2022, 4, 2);
        date1.printDate();
    }
}

 

 💡那为什么用this.name = name 赋值就好了呢?


this.xx的用法

🏀按照官方正规的解释,this关键字的意义被解释为“指向当前对象的引用”,比如在上述代码中当前所实例化的对象是date1,那么this其实就指向date1,是date1的一个引用(也可以理解为是date1的一个别名)那么this.xxx其实就代表了date1.xxx😎

🏀所以在执行”this.name=name;”这条语句的时候,虚拟机就会把参数year的值”2022”赋值给对象date1的year成员变量。也就是说在这条赋值语句中,”=”左边的”this.year”表示对象date1的year成员变量,而”=”右边的year表示传给我们构造方法的参数

🏀讲到这里,有的小伙伴可能会问:”this.year”为什么不能被解释为”当前对象date1自己的year参数”呢🤔?

🍑因为”参数”这个概念是就某个方法而言的,它相当于某个方法的”局部变量”,只是这个”局部变量”比起在方法中定义的真正的局部变量来讲有点特殊,🧢它能够接收从主调方法中传递过来的值因此,当我们说到”参数”这个概念的时候,都是相对于一个”方法”而不是一个”对象”而言的,所以也就不会有”某个对象的参数”这一说法。因此,”this.year”只能被虚拟机认定为当前对象date1自己的year成员变量,绝不会被当作参数。

不知道大家理解💡了吗

 🧢可能现在你还有点模糊,但没关系,我们现在只是刚接触到this这个关键字,先能模仿着用就行,以后可以慢慢理解😂

🧢刚才我们用this.成员变量名访问了我们当前对象的成员变量,那么我们能不能用this.成员方法名去访问我们的方法呢?当然可以呀this.xxx此时的作用不就相当于对象名.xxx吗😎,直接上代码😁

class Cat {
    public void jump() {
        System.out.println("这个猫在跳!!!");
    }
    public void run() {
        this.jump();        // 在run方法中用this.方法名调用当前对象的一个成员方法jump
        System.out.println("这个猫在跑!!!");
    }
}
public class TestDemo2 {
    public static void main(String[] args) {
        Cat cat = new Cat();
        cat.run();
    }
}

🍑 可以看出在我们成功的在run方法中用this.方法名调用了同一个类下的其他方法。

注意🔔:

虽然调用本类的普通方法前可以不使用this关键词。但是建议追加是this,这样的目的是可以区分方法的定义来源🤔


this()用于构造函数的调用

🍑咱们之前说了,同一个类中可以同时有多个构造函数,通过this()还可以在一个构造函数里调用另一个构造函数。

class Cat {
    String name;
    int age;
    Cat() {
        System.out.println("这是自定义的一个不带参数的构造函数");
    }

    public Cat(String name, int age) {
        this();            // 调用另一个不带参数的构造方法
        
        this.name = name;
        this.age = age;
        System.out.println(this.name + this.age + "岁了");
        System.out.println("这是自定义的一个带两个参数的构造函数");
    }
}
public class TestDemo2 {
    public static void main(String[] args) {
        Cat cat = new Cat("小花", 3);
    }
}

 从输出结果可以看出通过💡this(),我们成功在一个构造方法中调用另一个不带参数的构造方法

🔔但有几个问题需要我们注意一下 

  • this( ) 不能在普通方法中使用,只能写在构造方法中。
  • 在构造方法中使用时,必须是第一条语句。

另外,再补充一些小细节📝 

很多小伙伴可能不理解,为什么要通过这种方式来调用构造方法呢?我们在上面调用Cat类中一个不带参数的构造方法时,难道不能直接写一个🍑Cat();来调用吗?

🐟🐟🐟🐟🐟🐟🐟🐟🐟🐟🐟🐟🐟🐟🐟🐟

🔔这里必须做出解释:在Java语言中,一个类的构造方法与类名相同。但是,一个类当中也可以定义一个与类名相同的”普通方法”,💡换句话说就是:并不是只有构造方法与类名相同,”普通方法”也可以取和类相同的名称(只不过全世界的程序员都不会这么干)。

🔔那么,在这种情况下,编译器如何区分这个方法是”普通方法”还是”构造方法”呢?💡很简单,”普通方法”的名称前面必须定义返回值类型,而”构造方法”的名称前面则没有返回值类型的定义。这样,编译器就能够分得清哪个是”构造方法”,哪个是”和类同名的普通方法”。

🔔定义的时候分得清,但是在调用的时候,都是通过方法名来调用的💡,这时如何分得清代码中哪一句调用的是”构造方法”, 哪一句调用的是”和类同名的普通方法”呢?为了解决这个问题,Java语言规定,在本类中调用构造方法的时候,需要通过”🍑this(参数)”的方式来调用

今天有关java中构造方法和this的使用分享就到这里了😊,下一篇博客让我们搞清楚public、static到底是个什么东东 🤔

码字不易😅,各位铁汁们,都看到这里了,点个赞再走好吗😍

  • 735
    点赞
  • 1412
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 92
    评论
### 回答1: 在Java,拷贝构造函数并不像C++那样直接支持。但我们可以通过实现一个类的 clone() 方法来实现拷贝构造函数的功能。clone() 方法是 Java 提供的一种浅拷贝(Shallow Copy)的方法,它可以用于创建一个对象的拷贝。 下面是一个示例代码,演示了如何实现一个拷贝构造函数: ``` public class Person { private String name; private int age; public Person(String name, int age) { this.name = name; this.age = age; } // 拷贝构造函数 public Person(Person another) { this.name = another.name; this.age = another.age; } // clone() 方法 public Person clone() { try { return (Person) super.clone(); } catch (CloneNotSupportedException e) { // 如果类没有实现 Cloneable 接口,则会抛出该异常 return null; } } } ``` 在上面的代码,我们定义了一个 Person 类,并实现了一个拷贝构造函数。拷贝构造函数接受一个 Person 类型的参数,用于创建一个新的 Person 对象,该对象与传入的参数对象具有相同的属性值。 此外,我们还实现了 clone() 方法,该方法可以用于创建一个 Person 对象的拷贝。在该方法,我们调用了 Object 类的 clone() 方法,并将其返回类型转换为 Person 类型。 需要注意的是,clone() 方法是 Object 类的方法,如果需要使用该方法,必须在 Person 类实现 Cloneable 接口。如果没有实现该接口,则在调用 clone() 方法时会抛出 CloneNotSupportedException 异常。 ### 回答2: 在Java,拷贝构造函数是一种特殊的构造函数,它用于创建一个对象的副本。拷贝构造函数允许我们将一个对象的值复制到另一个对象,而不是仅仅复制其引用。这在需要克隆或复制对象时非常有用。 要创建一个拷贝构造函数,我们需要在类定义一个与类名相同的方法,并传入一个参数为该类的对象。例如,假设我们有一个名为Person的类,其包含name和age两个属性。 public class Person { private String name; private int age; public Person(Person other) { this.name = other.name; this.age = other.age; } } 在上面的例子,我们创建了一个在类定义的拷贝构造函数。在该函数,我们使用另一个Person对象的属性值来初始化新对象的属性。这样一来,我们就可以通过传递一个现有的Person对象来创建一个新的Person对象。 使用拷贝构造函数有几个好处。首先,它允许我们创建一个新对象,该对象与现有对象具有相同的属性值。这对于不修改现有对象但需要创建新对象的情况非常有用。其次,它避免了浅拷贝(只复制引用而不复制实际值)可能导致的问题。 在Java,拷贝构造函数的使用是可选的。如果我们不定义一个拷贝构造函数Java默认提供一个浅拷贝的拷贝构造函数。但是,如果我们需要执行深拷贝(复制对象及其所有子对象的值),就需要自己定义拷贝构造函数。 总之,拷贝构造函数是在Java创建一个对象副本的一种特殊函数。它允许我们通过将一个对象的属性值复制到另一个对象来创建新对象。这在复制、克隆对象或创建新对象时非常有用。 ### 回答3: 在Java,拷贝构造函数是一种特殊的构造函数,用于创建一个新对象,该对象的内容与现有对象相同。拷贝构造函数的主要作用是复制一个对象的值到另一个新的对象。 在Java,拷贝构造函数的定义如下: public class MyClass { private int myInt; // 拷贝构造函数 public MyClass(MyClass obj) { this.myInt = obj.myInt; } // 构造函数 public MyClass(int myInt) { this.myInt = myInt; } // Getter和Setter方法 public int getMyInt() { return myInt; } public void setMyInt(int myInt) { this.myInt = myInt; } } 在上面的示例,我们定义了一个名为MyClass的类,该类具有一个整型成员变量myInt。我们使用两个构造函数来创建对象,一个是拷贝构造函数,一个是普通构造函数。 拷贝构造函数的参数类型是与该类相同的对象,通过该参数将现有对象的值复制到新对象。在拷贝构造函数,我们可以使用this关键字引用当前对象,使用点操作符(.)访问对象的成员变量。 使用拷贝构造函数创建对象的示例代码如下: MyClass obj1 = new MyClass(10); // 使用普通构造函数创建对象 MyClass obj2 = new MyClass(obj1); // 使用拷贝构造函数创建对象 System.out.println(obj1.getMyInt()); // 输出:10 System.out.println(obj2.getMyInt()); // 输出:10 通过以上代码,我们可以看到obj2对象的myInt值与obj1对象的myInt值相同,这是因为拷贝构造函数将obj1对象的值复制给了obj2对象。 总之,拷贝构造函数是一种创建一个新对象并复制现有对象值的常用技术,它在Java的定义和使用方法如上所述。
评论 92
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

是小鱼儿哈

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

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

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

打赏作者

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

抵扣说明:

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

余额充值