Thắc mắc về static constructor

Có phải câu này sai đề không ạ? Em chọn A nhưng đáp án là B

Static constructor chỉ execute 1 lần duy nhất khi class loader, việc call static method không liên quan gì đến satic constructor.

Chúc giáng sinh vui vẻ ạ :santa: :snowman:

P/S: Cả 2 ngôn ngữ C# và ABAP đều có static constructor.

1 Like

bạn có thể viết vài dòng code đơn giản để tự test mà, cần gì phải suy đoán mà không có căn cứ hoặc căn cứ không chắc chắn như vậy
hơn nữa câu hỏi này phải ở trong ngữ cảnh cụ thể, ví dụ như đang nói về ngôn ngữ lập trình nào, vì biết đâu ngôn ngữ khác nó khác thì sao

method phải call nó mơi hoạt động chứ bạn, định nghĩa là 1 chuyện call là 1 chuyện khác chứ

Dạ kết quả đây ạ

C#

public class Demo
    {
        public static int myData;
          static Demo()                               // Đây là constructor
          {
            myData += 1;
          }
           public static void myStaticMethod() {}       
    }

test trong hàm main C#

    Demo.myStaticMethod();
    Demo.myStaticMethod();
    Demo.myStaticMethod();
    Demo.myStaticMethod();

    Console.WriteLine(Demo.myData);

Kết quả ra số 1.


Vói ngôn ngữ ABAP

class Demo definition.
  public section.
   class-data myData type I.
   class-methods class_constructor.
   class-methods myStaticMethod.
endclass.

class Demo implementation.
  method class_constructor.             //đây là constructor
        myData += 1.
  endmethod.

  method myStaticMethod.             
  endmethod.

endclass.

test trong hàm main

  METHOD if_oo_adt_classrun~main.
  
        Demo=>myStaticMethod(  ).
        Demo=>myStaticMethod(  ).
        Demo=>myStaticMethod(  ).
        Demo=>myStaticMethod(  ).
        
        out->write( Demo=>myData ).      // Dấu => để gọi static member
                                        // Dấu -> để gọi instance menber     
  ENDMETHOD.

Kết quả vẫn số 1.

Constructor chỉ execute khi có cái gì đó được tạo ra:

  • Instance constructor thực thi sau khi từ khóa new yêu cầu cấp phát ô nhớ.
  • Static constructor chỉ chạy đúng 1 lần duy nhất suốt cả vòng đời của app là khi class được load (chạy sau khi cấp phát ô nhớ cho biến static).

Chính vì thế không có trường hợp nào khi gọi method mà kích hoạt được static constructor cả, kể cả 2 loại constructor luôn đó bạn.

1 Like

vậy bạn thấy câu trắc nghiệm trên sai chỗ nào?

kiến thức này bạn đọc được ở đâu, ngôn ngữ nào? có link hay tài liệu cụ thể không?

Nếu đoạn code C# phía trên em không gọi bất kỳ phương thức static nào cả thì lúc in biến myData ra vẫn có giá trị là 1. Trong hàm main chỉ có đúng 1 dòng in myData thì nó vẫn là 1.

Câu trắc nghiệm trên nó sai ở chỗ là chọn câu B nghĩa là có mối quan hệ gì đó giữa việc call static method với static constructor

Tài liệu đây ạ https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/static-constructors

Code ABAP cũng tương tự thôi vì cái này liên quan OOP, 2 ngôn ngữ chỉ implement OOP với 2 syntax khác nhau.

https://help.sap.com/doc/abapdocu_751_index_htm/7.51/en-us/abenstatic_constructor_glosry.htm

1 Like

Nếu theo câu trả lời của của admin thì phải chọn đáp án A. Nhưng đây là trang web chính chủ của cty tỷ đô top đầu thế giới nên em nghĩ khó có thể sai đề.

1 Like

It is called automatically before the first instance is created or any static members are referenced.

Có thể hiểu, static constructor được gọi khi class được truy cập lần đầu tiên (tạo instance hoặc truy cập static members trong class).

Vậy,

  1. Câu A sai, vì chương trình phải thực thi câu lệnh nào đó truy cập class, mới gọi được static constructor, chứ không phải bắt đầu thì đã gọi static constructor.
  2. Câu B đúng, vì lúc gọi static method trong class, nếu là lần đầu tiên, sẽ tự động gọi luôn cả static constructor.

Ngoài ra, mình thấy đáp án C cũng đúng luôn.

3 Likes

Kết quả ra số 1 là vì static constructor được gọi một lần duy nhất thôi.

Bạn kiểm tra đoạn code sau sẽ in ra thứ tự nào.

// Demo.cs
public class Demo
{
	static Demo()
	{
		Console.WriteLine("2");
	}
	public static void callMe() { }
}

// Program.cs | Main

Console.WriteLine("1");
Demo.callMe();
Console.WriteLine("3");
2 Likes

vậy chắc bên c# nó khác java, bên java ko có chuyện hàm tự được gọi, hơn nữa bên java constructor cũng ko có static đc

Bên java constructor tự chạy sau mỗi khi dùng từ khoá new đó bạn :smiley:

Có đấy bạn:

public class Main
{
    static {
        System.out.println("STATIC CONSTRUCTOR");
    }
    
	public static void main(String[] args) {
		System.out.println("Main entry");
	}
}

Bên java thì hàm dựng tĩnh sẽ được gọi ngay khi máy ảo nạp xong bytecode của lớp đó.
Xin sửa sai:
Khối khởi tạo - Static Initialization Blocks chỉ được gọi một lần duy nhất ngay trước khi có bất kì thành viên tĩnh nào được gọi lần đầu (khởi tạo lớp).
Thành viên tĩnh - static member bao gồm bất kì trường (field) hoặc phương thức (method) có từ khóa static.


3 Likes

Em hiểu rồi, cảm ơn @SITUVN.gcd@duydang

đó là block code ko phải hàm dựng, ngay trong các link bạn đựa cũng là block chứ ko phải constructor?

2 Likes

thì dùng new là gọi hàm dựng đấy, ko dùng new thì làm gì có chuyện tự gọi hàm dựng

2 Likes

Từ khóa new và method constructor có mục đích khác nhau:

Đây là thứ tự thực thi và mối quan hệ giữa toán tử new và constructor

Car car = new Car();
When the Java runtime system encounters this statement, it does the following, and in this order:

  1. Allocates memory for an instance of class Car
  2. Initializes the instance variables of class Car
  3. Executes the constructor Car()

mình vẫn chưa hiểu ý bạn lắm ? sử dụng từ khóa new + tên constructor để gọi đến hàm dựng của 1 class

giờ ko dùng từ khóa new, sao bạn liên kết đến constructor đc?
Car car = Car(); ???

bạn nói mục đích khác nhau vậy chỉ ra mục đích của từ khóa new xem nào?

Bạn bảo dùng từ khoá new để gọi hàm dựng là chưa đúng, không có sách nào viết dùng từ khóa new để gọi method constructor cả. new dùng để cấp phát vùng cho cho object là bước 1. Đến bước thứ 3 theo thứ tự bên trên mới đến lượt constructor thực thi. Mà nó lại tự động thực thi chứ không cần thao tác lời gọi hàm nào cả. Constructor giống như side effect vậy đó. VD bạn tạo class Person có thuộc tính tuổi age, bạn new Person() thì lúc này age vẫn là 0, sau đó constructor tự động execute để set lại giá trị age.

Bạn đang hiểu là viết toán tử new để gọi constructor như kiểu object.method()

Còn mục đích thì như 3 bước bên trên. 3 bước này tự động diễn ra trong môi trường runtime mỗi khi có từ khoá new.

  • new chỉ có 1 mục đích duy nhất là tạo một ô nhớ trong bộ nhớ heap thôi. Sau bước 1 thì tất cả thuộc tính đều là default value vd int là 0 string là null
  • vd trong java bạn viết private int age = 18; thì đây là bước 2.
  • còn contructor logic như method thông thường chỉ khác ở 3 điểm là nó tự động execute sau khi bước 1, 2 xong và không có kiểu trả về và cùng tên với class

Bạn cũng không thể trực tiếp gọi constructor, vì vậy bạn nói “tôi dùng new để gọi hàm dựng” là sai

tôi đâu có nói là new gọi hàm như thế này đâu? ý tôi chỉ nói là new nó như 1 từ khóa, đặt trước hàm dựng và có ý của nó là hãy chạy cái hàm dựng này

cái này bạn tự suy diễn à ? chứ cái quote của bạn nó chỉ nói là sẽ thực hiện những công việc kia chứ có nó là new sẽ làm như vậy đâu?

83% thành viên diễn đàn không hỏi bài tập, còn bạn thì sao?