2012-12-18 47 views
6

classloaders Java Gần đây đã được xúc động và bất ngờ nhận ra rằng không hoàn toàn hiểu những gì xảy ra bước-by-step khi ai đó gọiĐiều gì xảy ra khi chương trình java bắt đầu?

java -jar App.jar 

Vâng, tôi đoán

  1. một trường hợp mới của JVM là tạo ra
  2. sử dụng Lớp tải để tải lớp chính và các lớp khác
  3. mã byte được bắt đầu thực hiện từ phương thức main()

Nhưng tôi vẫn cho rằng có rất nhiều điều tôi cần biết thêm về nó.

  • Ai và cách quyết định lớp nào sẽ được tải khi khởi động và khi nào cần?

Tôi đã tìm thấy hai câu hỏi liên quan nhưng ở đó không giải thích cách áp dụng điều đó vào thực tế Java.

What happens when a computer program runs?

What happens when you run a program?

+1

Thông số kỹ thuật có thể trợ giúp (ví dụ một chút không thích hợp, do đó nhận xét không phải là câu trả lời): http://docs.oracle.com/javase/specs/jls/se7/html/jls-12.html#jls-12.1 – Charlie

+0

Ngoài ra liên kết đó đề cập đến Java VM Spec: http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-5.html#jvms-5.2 – Charlie

Trả lời

2

• Ai và làm thế nào quyết định những lớp nên được nạp lúc khởi động và đã từng cần thiết?

chúng ta cần hiểu các nguyên tắc cơ bản của tải lớp java. Ban đầu bootstrap classloader (nó được thực thi nguyên bản như một phần của bản thân VM) có trách nhiệm tải các lớp hệ thống lõi. Sau đó, có các trình nạp lớp khác cũng như các trình nạp lớp mở rộng, hệ thống, do người dùng định nghĩa (tùy chọn) quyết định thời gian và cách thức các lớp sẽ được nạp. Fundamentals of class loading

1

Quyết định này được thực hiện bởi trình nạp lớp. Có các triển khai khác nhau, một số trong đó tải trước tất cả các lớp mà chúng có thể và một số chỉ tải các lớp khi chúng cần thiết.

Chỉ một lớp học cần để được tải khi được truy cập từ mã chương trình lần đầu tiên; quyền truy cập này có thể là sự khởi tạo của một đối tượng từ lớp đó hoặc truy cập vào một trong các thành viên static của nó. Thông thường, trình nạp lớp mặc định sẽ lười biếng tải các lớp khi chúng cần thiết.

Một số lớp không thể dựa vào để được tải sẵn trong mọi trường hợp. Tuy nhiên: Các lớp được truy cập qua Class.forName(...) có thể không được xác định cho đến khi mã này thực sự được gỡ bỏ.

Trong số các tùy chọn khác, đối với các thử nghiệm đơn giản, bạn có thể sử dụng mã khởi tạo tĩnh để xem thời gian và thứ tự thực tế trong đó các lớp thực sự được tải; mã này sẽ được thực hiện khi lớp được nạp lần đầu tiên; Ví dụ:

class SomeClass { 

    static { 
     System.out.println("Class SomeClass was initialized."); 
    } 

    public SomeClass() { 
     ... 
    } 

    ... 

} 
0

dụ bạn thấy một jar thực thi, mà chỉ đơn giản là một java lưu trữ bình thường (jar) với một cặp khóa/giá trị thêm vào đó là file manifest (nằm trong thư mục "META_INF").Khóa là "Main-Class" và giá trị tên lớp đủ điều kiện của lớp đó có phương thức "chính" sẽ được thực hiện, nếu bạn "chạy" bình giống như trong ví dụ của bạn.

Bình là tệp zip và bạn có thể xem bên trong bằng mọi công cụ lưu trữ zip.

0

Bất cứ khi nào bạn biên dịch một chương trình Java các bước sau đây diễn ra

  1. Đầu tiên Loader Lớp tải lớp thành JVM.
  2. Sau khi đưa ra lệnh javac filename.java trình biên dịch kiểm tra lỗi thời gian biên dịch và nếu mọi thứ đều ổn thì nó sẽ tạo tệp .Class (mã byte).

Đây sẽ là giai đoạn đầu tiên.

Sau đó, trình thông dịch sẽ kiểm tra lỗi thời gian chạy và nếu mọi thứ đều ổn mà không có ngoại lệ thì trình thông dịch sẽ chuyển mã byte thành mã thực thi.

Giai đoạn đầu tiên trong java được thực hiện bởi trình biên dịch JIT (Chỉ trong thời gian).

Các vấn đề liên quan