2011-09-30 26 views
9

Với mã này:.Sự khác nhau giữa ClassLoader.getSystemResourceAsStream và getClass() getResourceAsStream()

/* 1 */ InputStream in1 = ClassLoader.getSystemResourceAsStream("foobar.txt"); 
/* 2 */ InputStream in2 = this.getClass().getResourceAsStream("/foobar.txt"); 

Do cả hai trở lại nguồn giống (tôi nghĩ của "có" câu trả lời)?

Cả hai có truy cập vào đường dẫn lớp "giống nhau" không? Tại sao tên phương thức trong # 1 "nhận được Hệ thống ResourceAsStream", nhưng đối với # 2 thì đó chỉ là "getResourceAsStream"?

Cảm ơn

Trả lời

7

Theo javadoc

mở để đọc, một nguồn tài nguyên của tên được chỉ định từ tìm kiếm con đường sử dụng để tải các lớp học. Phương pháp này tìm nguồn tài nguyên thông qua bộ nạp lớp hệ thống (xem getSystemClassLoader()).

Trình nạp lớp dùng để tải this không nhất thiết là trình nạp lớp hệ thống. Trong một ứng dụng máy tính để bàn đơn giản, điều này có thể sẽ đúng. Nhưng các ứng dụng web - trong số những thứ khác - thường có các phân cấp đường dẫn lớp phức tạp hơn và do đó không nhất thiết phải giống nhau. Trong một classpath phức tạp, do đó những gì được trả về cũng sẽ phụ thuộc vào số lượng bản sao của 'foobar.txt' đang trôi nổi xung quanh classpath của bạn.

Câu trả lời ngắn gọn là bạn không thể giả định rằng họ sẽ trả lại luồng cho cùng một tài nguyên.

+0

Vì vậy, bạn đang nói có nhiều classpath trong ứng dụng web? – Michael

+0

@Michael - Sắp xếp. Thông thường, mỗi ứng dụng web đều có trình nạp lớp riêng, chịu trách nhiệm về nội dung của WAR, EAR, vv Các trình nạp lớp này có một lớp cha chung và do đó các lớp trong các thư mục lib chung được chia sẻ giữa các ứng dụng web khác nhau. Nhưng các hệ thống phân cấp này có thể là một số bộ tải sâu. Trình nạp lớp hệ thống sẽ ở trên cùng, nhưng có thể có một số ở giữa. – sblundy

+0

Các ứng dụng web khác nhau có thể sẽ có các trình nạp lớp khác nhau. Ví dụ, trong Glassfish, chúng có một hệ thống phân cấp được chỉ định ở đây: http://download.oracle.com/docs/cd/E19798-01/821-1752/6nmndgmhr/index.html#fvxzq. – g051051

11

Sự khác biệt chính là trình tải lớp.

Sau đây sử dụng hệ thống ClassLoader
ClassLoader.getSystemResourceAsStream("foobar.txt");

Trong khi người ta này sử dụng Classloader trả về bởi getClass()
this.getClass().getResourceAsStream("/foobar.txt");

Nói cách khác, cho dù cả hai câu lệnh cư xử giống hệt nhau hay không, phụ thuộc vào trình nạp lớp ứng dụng. Đối với một ứng dụng đơn giản, cả hai tham chiếu đến cùng một trình nạp lớp. Tuy nhiên, đối với hầu hết các ứng dụng (như một ứng dụng web chạy trong vùng chứa Servlet), điều đó sẽ không xảy ra.

Nói chung, tôi sẽ nói getClass(). GetResourceAsStream() sẽ là lựa chọn tốt hơn vì nó sẽ sử dụng cùng trình nạp lớp như lớp Mã thuộc về.

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