01/10/2018, 16:36

Hỏi về Java Enum

Chào các bạn.
Khi tìm hiểu về enum trong Java, mình gặp một câu hỏi thế này, nhưng mình không hiểu đáp án.
Mình thắc mắc vài chổ:

  1. Trong 1 lớp thì gồm method và properties. Vậy phần { System.out.println(1); } và static { System.out.println(2); } được gọi là gì ???
  2. Tại sao đáp án lại ra như vậy ??? Tại sao phần nội dung của static lại ra kết quả sau cùng ???

Bạn nào biết xin hãy giải thích dùm mình.
Mình cảm ơn.

Aragami1408 viết 18:47 ngày 01/10/2018

Code trên thấy hơi lạ thật!

Vậy phần { System.out.println(1); } và static { System.out.println(2); } được gọi là gì ???

Đâu phải cứ 1 class là phải có method và properties. Còn câu hỏi đó thì có thể vô đây để xem: static initializer in java

Tại sao đáp án lại ra như vậy ??? Tại sao phần nội dung của static lại ra kết quả sau cùng ???

Cái block in ra 1 thì đương nhiên là nó chạy rồi kể cả cái enum không gọi C hay bất cứ thằng nào ra. Còn cái hàm khởi tạo thì cũng tương tự. Cái static kia tức là khởi tạo giá trị cho các biến static mà A, B, C đều được gán thuộc tính static cả(bạn học static trong java sẽ hiểu bản chất vấn đề hơn).

Trần Ngọc Vĩnh Nhơn viết 18:41 ngày 01/10/2018

Mình hiểu rồi. Cảm ơn bạn

Hung viết 18:51 ngày 01/10/2018

Block này gọi là Initializing Instance Members, ngoài ra còn có final method và constructor. Cả 3 đều có nhiệm vụ khởi tạo (initialize) các instance variables của class.

{
    System.out.println(1);
}

Về thứ tự: final method -> initializing block member -> constructor

class Person {
	
    // use final method
    private String name = setupName();

    // Initializing Block Member	
    {
		System.out.println("in initializing block member");
	}
	
    // Constructor
	public Person() {
		System.out.println("in person constructor");
	}
	
	protected final String setupName() {
        System.out.println("in final method setupName()");
		return "Drgnz";
	}
	
	public String getName() {
		return name;
	}
}

public class TestPerson {
    public static void main(String[] args) {
        Person p = new Person();
        System.out.println(p.getName());
    }
}

Output

in final method setupName()
in initializing block member
in person constructor
Drgnz

Với static variables, thứ tự: final method -> static block initializer


Trở lại ví dụ của bạn.
Sau khi qua bước parsing, sinh được bytecode bằng javac, java runtime đọc từ trên xuống dưới mã nguồn (thực chất là đọc bytecode, 1 biểu diễn khác của Java code).

  • java đọc enum, khởi tạo enum, bắt đầu từ instance variables, sau đó sang static variables.
  • Bước instance variables, java thấy A, init cho A, chạy block member, in ra 1, sau đó chạy tiếp constructor, in ra 3.
  • Tương tự cho B, C, in ra các giá trị lần lượt 1, 3, 1, 3. Kết thúc instance variables initialization.
  • Chuyển sang static variables, java đọc tiếp static block initializer static { ... }, chạy block để khởi tạo static members, in ra 2.
Trần Ngọc Vĩnh Nhơn viết 18:51 ngày 01/10/2018

Wow. Bạn giải thích rất hay, chi tiết. Nhờ bạn mà mình biết thêm 3 cách init và thứ tự ưu tiên của từng cái, cũng hiểu về thắc mắc ban đầu của mình. Cảm ơn rất nhiều

Bài liên quan
0