Detailed explanation of Java classes and objects (2)

 

this reference

Why is there a this reference

Let's look at an example of a date class first:


public class Date {
    public int year;
    public int month;
    public int day;

    //设置日期方法
    public void setDay(int y, int m, int d){//这里隐藏了一个Date this参数
        year = y;
        month = m;
        day = d;
    }

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

    public static void main(String[] args) {
        //构造三个日期类的对象d1,d2,d3
        Date d1 = new Date();
        Date d2 = new Date();
        Date d3 = new Date();

        //对d1,d2,d3三个日期进行设置
        d1.setDay(1931,9,18);
        d2.setDay(1937,7,7);
        d3.setDay(1932,1,28);

        //打印日期中的内容
        d1.printDate();
        d2.printDate();
        d3.printDate();
    }
}

The above code defines a simple date class, and then creates three objects in the main method, and sets and prints the objects through the member methods in the Date class. The overall logic of the code is very simple without any problems.

But there are several questions:

1. In order to improve the readability of the code, we changed the parameters in setDate to year, month, day. But here is the problem that the formal parameter name is accidentally the same as the member variable .

public void setDay(int year, int month, int day){
        year = year;
        month = month;
        day = day;
    }

At this time, it is difficult for us to figure out who is passing the reference to whom.

2. The three objects are calling the setDate and printDate methods, but there is no description about the object in these two methods. How do they know the setting and which object is printed ? ? ?

what is this reference

The this reference points to the current object (the object that calls the member method when the member method is running), and the operations of all member variables in the member method are accessed through this reference. It's just that this process is hidden from the user (such as the above code public void setDay(int y, int m, int d){//a Date this parameter is hidden here ), that is, the user does not need to pass it, and it will be automatically completed by the compiler.

In short, whoever called this method, this is the reference of which object. (As can be seen in the figure below, the hash codes of the objects are the same, indicating that the same object is used).

 properties referenced by this

1. The type of this: the reference of the corresponding class type, that is, which object is called is the reference type of which object

2.this can only be used in member methods

3. In member methods, this can only refer to the current object, and cannot refer to other objects

4. this is the first hidden parameter of the member method , and the compiler will pass it automatically. When the member method is executed, the compiler will be responsible for passing the reference of the called member method object to the member method, and this is responsible for receiving

Demonstration of the fourth feature

Object construction and initialization 

 How to initialize an object

Through the study of the previous knowledge points, we know that when defining a local variable inside a Java method, it must be initialized, otherwise the compilation will fail.

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

//Error:java:可能为初始化变量a

It is very simple to make the above code pass compilation, you only need to set an initial value for a before officially using a. If object:

public static void main(String[] args) {
    Date d = new Date();
    d.printDate();
    d.setDate(1931, 9, 18);
    d.printDate();
}

//代码正常通过编译

You need to call the previous SetDate method to set the specific date into the object. Through the above example, two problems were found:

1. It is troublesome to call the SetDate method to set the specific date after each object is created. How should the object be initialized?

2. Local variables must be initialized before they can be used. Why can they compile normally without giving a value here?

Construction method

concept

A constructor (also known as a constructor) is a special member method whose name must be the same as the class name . It is automatically called by the compiler when an object is created, and it is called only once in the entire object life cycle .

The following still uses Date to show the construction method:

public class Date {
    public int year;
    public int month;
    public int day;

    //构造方法与类名相同,没有返回类型,设置为void也不行
    //一般情况下使用public修饰
    //在创建对象时由编译器自动调用,并且在对象的生命周期中只调用一次
    //带有参数的构造方法
    public Date(int year, int month, int day) {
        this.year = year;
        this.month = month;
        this.day = day;
        System.out.println("Date(int, int, int)方法被调用了");
    }

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

    public static void main(String[] args) {
        //这里创建了一个Date类型的对象,并没有显式调用构造方法
        Date d = new Date(2021,6,9);//输出Date(int, int, int),表明方法被调用了
        d.printDate();
    }

}

Note: The function of the constructor is to initialize the members of the object, and is not responsible for opening up space for the object.

characteristic

1. The name must be the same as the class name

2. There is no return value type, even void

3. It is automatically called by the compiler when the object is created, and it is called only once in the life cycle of the object

4. The construction method allows overloading , (provide different construction methods according to your own needs)

Constructor overloading:

public class Date {
    public int year;
    public int month;
    public int day;

    //无参的构造方法
    public class Date () {
    }
    //带有三个参数的构造方法
    public class Date (int year, int month, int day) {
        this.year = year;
        this.month = month;
        this.day = day;
    }
}

The above two construction methods: the same name, different parameter lists, constitute method overloading.

5. If the user does not explicitly define it, the compiler will generate a default construction method, which must have no parameters (note: if the user defines it, the compiler will not generate it again) .

public class Date {
    public int year;
    public int month;
    public int day;

    public Date(int year, int month, int day) {
        this.year = year;
        this.month = month;
        this.day = day;
        System.out.println("Date(int, int, int)方法被调用了");
    }

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

    public static void main(String[] args) {
        //如果编译器会生成,则生成的构造方法是无参的,则会通过编译
        //但此处未通过编译
        Date d = new Date();
        d.printDate();
    }
}
//这里没有通过编译,原因是编译器未生成构造方法,而是默认用用户的构造方法
//用户构造的和创建对象时的参数类型不匹配,所以没有通过编译

6. In the construction method, you can call other construction methods through this reference to simplify the code


public class Date {
    public int year;
    public int month;
    public int day;



    //无参的构造方法-内部给各个成员赋初值,该部分功能与三个参数的构造方法相重复
    //但是此处可以通过this调用带有三个参数的构造方法
    //this(1900,1,1);必须是构造方法的第一条语句

    public class Date () {
        //调用当前类的其它构造方法,不让自己构造自己
        this(1900,1,1);
        //this.year = 1900;
        //this.month = 1;
        //this.day = 1;
    }

    //带有三个参数的构造方法
    public class Date (int year, int month, int day) {
        this.year = year;
        this.month = month;
        this.day = day;
    }
}

Note: this(...) must be the first statement in the constructor .

        cannot form a ring:

 //Compile error: use of recursive constructor

7. In most cases, use public to modify, and in special scenarios, it will be modified by private.

default initialization

The same as the second question above: Why must local variables be initialized when they are used, but member variables are not ?

To understand this process, you need to know what happens behind the new keyword:

Date d = new Date(2021, 6, 9);

It may be a simple statement on the surface of the program, but there may be many things to be done at the virtual machine level. The following is a brief introduction:

1. Check whether the class corresponding to the object is loaded, if not loaded, load it

2. Allocate space for the object

3. Dealing with Concurrency Security Issues

For example: multiple threads apply for objects at the same time, and the JVM must ensure that the space allocated to the objects does not conflict

4. Initialize the allocated space

That is: after the object space is applied, the initial values ​​of the members contained in the object have been set, as follows:

5. Set the object header information

6. Call the constructor and assign values ​​to each member of the object

That's all for this issue, thank you for your support! ! !

Guess you like

Origin blog.csdn.net/asdssadddd/article/details/132071125