2011-12-19 32 views
52

Trong OpenJDK, cho phương pháp:Tại sao Double.valueof javadoc lại nói nó lưu trữ các giá trị, khi nó không?

public static Double valueOf(double d) 

Các javadoc nói:

Trả về một ví dụ đúp đại diện cho giá trị tăng gấp đôi quy định. Nếu một đối tượng Double mới không được yêu cầu, phương pháp này thường được sử dụng tùy thuộc vào hàm tạo Double (double), vì phương thức này có khả năng mang lại hiệu suất thời gian và không gian tốt hơn đáng kể bằng cách lưu các giá trị được yêu cầu.

Dưới đây là đoạn code thực tế:

public static Double valueOf(double d) { 
    return new Double(d); 
} 

Cache là một lời nói dối! Những gì đang xảy ra ở đây?

+31

Tài liệu luôn sai. Nhớ lấy. –

+5

Bạn lấy mã từ đâu? OpenJDK6? OpenJDK7? Apache Harmony? GNU Classpath? – scravy

+0

@scravy Tôi đang xem OpenJDK7 nhưng mã này đã không thay đổi trong nhiều năm trong bản phát hành chính thức của Sun. –

Trả lời

54

Phương pháp này tồn tại cho nhiều loại: Integer, Long, BigDecimal và những người khác và các tài liệu luôn luôn là như nhau: Trong một số trường hợp (trong đó không được định nghĩa), phương pháp thể trả lại kết quả tương tự.

AFAIK, bộ nhớ đệm chỉ được triển khai cho các loại số nguyên và nó trả về các phiên bản được lưu trong bộ nhớ cache cho các giá trị giữa -128 và 127 (các giá trị phổ biến nhất). Đối với BigDecimal, bộ nhớ cache hiện hoạt động với các giá trị từ 0 đến 10.

Phiên bản sau của Java có thể mở rộng hành vi này sang các giá trị khác/nhiều loại khác. Vì vậy, thông minh để sử dụng mã này ngay hôm nay vì nó có thể làm cho mã của bạn nhanh hơn vào ngày mai (và mã sẽ không chậm hơn ngày hôm nay).

Trình biên dịch Java, ví dụ, sử dụng API này khi tạo mã cho autoboxing.

6

Nhà thiết kế API có thể không muốn hạn chế triển khai thay thế. Giờ đây, những người này có thể tự do thêm bộ nhớ đệm vào lớp Double.

29

Không có gì sai với doc API là:

Phương pháp này có khả năng để mang lại ...

Đó là, một thực hiện được phép làm bộ nhớ đệm ở đây, đó là đơn giản là không thể với một hàm tạo. Tuy nhiên, nó không được yêu cầu. Nhưng, vì rất có thể là bạn có một triển khai thực hiện bộ nhớ đệm, nên sử dụng phương thức này hơn là sử dụng một hàm tạo.

+4

+1. IMHO, điểm mấu chốt là OP viết "* mã * thực tế", nhưng những gì anh ta cung cấp chỉ là * một * thực hiện. Các triển khai khác có thể và tồn tại cho các nền tảng khác. (Đặc biệt, nó sẽ không làm tôi ngạc nhiên khi thấy sự khác biệt ở đây trong quá trình thực hiện chương trình cơ sở.) – ruakh

+0

@ruakh Tôi đã nghĩ rằng một triển khai thay thế cũng sẽ đi kèm với javadoc thay thế. Mã và javadoc đi cùng nhau, nó không phải là một tài liệu đặc tả mức cao. Điều đó sẽ không thuộc về mã. –

+7

Các javadoc của java. * Classes * là * thông số kỹ thuật, vì khác của họ là các nhà cung cấp khác ngoài Oracle viết Java triển khai và họ phải cung cấp các chức năng tương tự cho tất cả các lớp này. –

2

Những phương pháp valueOf() này tồn tại trong mọi loại số nhằm mục đích hỗ trợ bộ nhớ đệm. Trong thực tế, đối với Double, nó không sử dụng bất kỳ bộ nhớ cache nào nhưng cho IntegerLong.

12

Từ Java 1.5+, JVM/JIT đảm bảo bộ nhớ đệm của Integer s -127 đến 127. Vì vậy, đó là lý do tại sao cho Integer cách tiếp cận ưa thích là sử dụng valueOf. Thông thường, bạn nên sử dụng valueOf bằng cách sử dụng hàm tạo cho double vì sau đó JIT có thể tối ưu hóa mã của bạn khi nó thấy phù hợp.Ví dụ, hãy xem xét vòng lặp sau:

for (Object o: objectList) { 
    o.setValue(Double.valueOf(0.0)); 
} 

Trong trường hợp này, JIT có thể precalculate đối tượng đôi và gán giá trị như nhau trên mỗi lần lặp của vòng lặp, trong khi đó nếu bạn đã sử dụng new Double(0.0); nó sẽ không thể Để làm việc đó.

+0

+1 để làm nổi bật trường hợp sử dụng bộ nhớ đệm. – Luke

+2

Xin chúc mừng, bạn hiện có đại diện năm 2013, chúc mừng năm mới 2013 :) –

+0

@MohamedSakherSawan cảm ơn - đã làm cho ngày của tôi :) – Deco

2

Hãy nhớ rằng JVM đã được tạo để giảm kích thước mã cho các thiết bị nhúng (chủ yếu) - đó là hệ điều hành hộp set-top. Tôi đã làm việc trên một vài nền tảng java nhúng và trên những giá trị "value of" valueOf sẽ rõ ràng hơn, nó sẽ tiết kiệm khá nhiều không gian trong một số trường hợp.

Chủ yếu là phương thức tồn tại vì "mới" không bao giờ có thể sử dụng các phiên bản được lưu trong bộ nhớ cache. valueOf CÓ THỂ được thực hiện để sử dụng các thể hiện được lưu trong bộ nhớ cache (nếu không bạn sẽ luôn luôn sử dụng mới) và có khả năng ở bất cứ nơi nào nó chứng minh là tiết kiệm thời gian.

Nếu họ (hoặc bạn) thay thế phương thức đó bằng giá trị bộ nhớ cache thì tất cả mã của bạn sẽ có lợi thế về thay đổi đó, nhưng không chuẩn bị bằng cách cung cấp phương thức như "valueOf". thực tế không bao giờ - bạn có thể tinh chỉnh trình biên dịch/thực thi bytecode để có các giá trị được lưu lại "mới" nhưng tôi nghĩ điều đó sẽ phá vỡ một số hợp đồng)

Vì vậy, bộ nhớ cache không thực sự là một lời nói dối.

+2

Bạn có thể tham chiếu đến tuyên bố về lý do cho jvm không?Các phương thức valueOf là mới, để hỗ trợ autoboxing. Không bao giờ nên có các nhà xây dựng cho những điều này, điều này đặc biệt dành cho Boolean. – stolsvik

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