2013-07-05 34 views
5

Tôi đã đọc ở khắp mọi nơi khi bạn xác định Số nguyên từ -128 đến 127 trong Java, thay vì tạo đối tượng mới, nó trả về một đối tượng đã được tạo.Nhóm Java Integer. Tại sao?

Tôi không thấy điểm nào khác ngoài việc cho phép người lập trình mới so sánh các đối tượng Integer với == để xem chúng có cùng số không, nhưng tôi nghĩ điều này là xấu vì chắc chắn họ nghĩ rằng họ có thể so sánh bất kỳ số nguyên nào với == và cũng đang dạy một phương pháp không tốt trong bất kỳ ngôn ngữ lập trình nào: so sánh nội dung của hai đối tượng 'khác nhau' với ==.

Có lý do nào khác giải thích tại sao việc này được thực hiện không? Hoặc là nó chỉ là một quyết định xấu khi thiết kế ngôn ngữ (Theo quan điểm của tôi) như dấu chấm phẩy tùy chọn trong JavaScript?

EDIT: Tôi thấy ở đây là họ giải thích các hành vi: Why does the behavior of the Integer constant pool change at 127?

Tôi hỏi tại sao họ thiết kế nó để có hành vi này, và không tại sao hành vi này xảy ra.

+3

Có một chút không cần thiết để phân bổ các đối tượng mới và mất bộ nhớ khi chúng không thay đổi và có thể được chia sẻ. –

+0

Có lẽ tối ưu hóa bộ nhớ là một câu trả lời, đừng nghĩ về nó. –

+0

Nó tiết kiệm bộ nhớ, nhanh hơn và giảm áp lực lên bộ thu gom rác. Việc sử dụng lại các đối tượng có thể nhanh hơn đáng kể và một số tùy chọn tăng kích thước bộ nhớ cache Integer lên 10.000 hoặc 20.000 vì lý do này. –

Trả lời

10

Nó được gọi là Flyweight pattern và được sử dụng để giảm thiểu mức sử dụng bộ nhớ.

Những con số này rất có thể được sử dụng nhiều lần và các loại hộp số tự động như Integer là không thay đổi (lưu ý điều này được thực hiện không chỉ cho Integer). Caching chúng làm cho nó như vậy không có nhiều trường hợp và làm giảm GC (Garbage Collection) làm việc là tốt.

Các JLS diện này trong 5.1.7. Boxing Conversion đặc biệt bằng cách nói:

Nếu p giá trị được đóng hộp là đúng, sai, một byte, hoặc một char trong khoảng \ u0000 để \ u007f, hoặc một int hoặc ngắn giữa -128 và 127 (bao gồm), sau đó cho r1 và r2 là kết quả của bất kỳ chuyển đổi đấm bốc nào của p. Nó luôn luôn là trường hợp r1 == r2.

Lý tưởng nhất, hãy đấm một giá trị nguyên thủy p, sẽ luôn mang lại một tham chiếu giống nhau. Trong thực tế, điều này có thể không khả thi khi sử dụng các kỹ thuật triển khai hiện có. Các quy tắc trên là một sự thỏa hiệp thực dụng. Điều khoản cuối cùng ở trên yêu cầu các giá trị chung nhất định luôn được đóng hộp thành các đối tượng không thể phân biệt được. Việc triển khai có thể lưu vào bộ nhớ cache, lười biếng hoặc háo hức. Đối với các giá trị khác, công thức này không cho phép bất kỳ giả định nào về danh tính của các giá trị đóng hộp trên phần của lập trình viên. Điều này sẽ cho phép (nhưng không yêu cầu) chia sẻ một số hoặc tất cả các tài liệu tham khảo này.

Điều này đảm bảo rằng trong hầu hết các trường hợp phổ biến, hành vi sẽ là hành vi mong muốn, không áp đặt hình phạt hiệu suất quá mức, đặc biệt là trên các thiết bị nhỏ. Ví dụ, ít triển khai bộ nhớ hạn chế hơn, có thể lưu trữ tất cả các giá trị char và ngắn, cũng như các giá trị int và long trong phạm vi từ -32K đến + 32K.

+0

Đây không phải là câu trả lời đầu tiên, nhưng là một câu trả lời chi tiết hơn. Tôi không thích java tối ưu hóa phần mềm cho tôi. Tôi nghĩ rằng phần mềm tối ưu hóa thuộc về nhà phát triển. Ý tôi là, họ đã thay đổi cách đối tượng nên hoạt động chỉ để tối ưu hóa phần mềm người dùng. Nếu một nhà phát triển muốn tối ưu hóa điều đó, họ nên làm việc trên nó làm cho nhóm Integer của riêng họ. Nhưng đó là ý kiến ​​của tôi: P –

+1

Và bây giờ tôi đã đọc về chỉnh sửa Chuyển đổi quyền anh và có ý nghĩa hơn. Java hoạt động dưới hàng triệu thiết bị có sự khác biệt lớn về phần cứng, vì vậy họ phải suy nghĩ về việc giảm mức sử dụng bộ nhớ bằng mọi giá. Làm việc tốt Java: P –

+1

Tôi cho rằng toàn bộ * điểm * của một ngôn ngữ cấp cao như Java đang ẩn chi tiết gory từ người dùng cuối khi có thể;) Nhưng điều này đặc biệt ... eh, tôi có thể đi theo một trong hai cách. –

2

Tôi nghĩ rằng việc tạo bất kỳ đối tượng nào mất nhiều thời gian hơn lấy nó từ bảng biểu tượng. Hơn nữa, nếu tôi không nhầm, mọi đối tượng trên heap chiếm 24 byte không gian bổ sung cho tiêu đề. Bây giờ, nếu một lập trình viên viết chương trình của mình, hầu hết các hoạt động được thực hiện trên các int nhỏ (trong trường hợp này là các số nguyên nhỏ). Vì vậy, nó cho phép tiết kiệm rất nhiều không gian và cải thiện hiệu suất một chút.

+0

Tôi tò mò .. Tại sao 24? Trên JVM nào? – Joni

+0

Vâng, bây giờ có ý nghĩa hơn ... Không nghĩ về trí nhớ, thật là xấu hổ lol: P Cảm ơn bạn. –

+0

Tôi nghĩ rằng hầu hết trong số họ. Tôi không biết tại sao chính xác 24 cho tiêu đề. Tôi nghĩ rằng phải có một chữ ký hoặc sth như thế. + nếu tổng bộ nhớ không chia hết cho 8, đệm cũng được thêm (trong trường hợp số nguyên là một trình bao bọc cho int - 24 (tiêu đề) + 4 (int) + 4 (đệm)) –

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