2012-10-30 33 views
25

Tôi đang hợp nhất mã được viết bởi hai người khác nhau và thông báo rằng việc đúc một giá trị String vào một Long đã được thực hiện theo hai cách khác nhau.Sự khác biệt giữa Long.valueOf (java.lang.String) và mới Long (java.lang.String)?

Coder # 1 đã làm điều này:

String strId = "12345678"; 
... 
Long lId = new Long(strId); 

Trong khi coder # 2 đã làm điều này:

String strId = "12345678"; 
... 
Long lId = Long.valueOf(strId); 

Về mặt chức năng, mã hoạt động giống hệt nhau. Có một khối try/catch xung quanh mỗi bit để xử lý bất kỳ NumberFormatException nào được ném. Giá trị chuỗi đến là một chuỗi gồm 8 chữ số đại diện cho một số thập phân: "12345678" và trong cả hai trường hợp, nó được chuyển đổi chính xác thành Long.

Có sự khác biệt về chức năng nào giữa việc truyền chuỗi trong hàm tạo và sử dụng Long.valueOf() không? Tôi đã kiểm tra các nhà xây dựng doc ở đây:

Long(java.lang.String)

và các tài liệu cho valueOf() ở đây:

Long.valueOf(java.lang.String)

Theo như tôi có thể nói, cả hai đều gọi parseLong() để nó không quan trọng được sử dụng. Tôi chỉ muốn chắc chắn rằng tôi không đặt mình lên cho một số hành vi kỳ lạ hơn nữa xuống đường. Ngoài ra, là một trong hai phong cách "chính xác" (haha) hơn khác?

Trả lời

24

Sự khác biệt là sử dụng new Long() bạn sẽ luôn luôn tạo ra một đối tượng mới , trong khi sử dụng Long.valueOf(), có thể trả lại cho bạn giá trị được lưu trong bộ nhớ cache là long nếu giá trị nằm trong khoảng từ [-128 to 127].

Vì vậy, bạn nên sử dụng phương pháp Long.valueOf, vì nó có thể giúp bạn tiết kiệm một số bộ nhớ.

Nếu bạn thấy đoạn mã nguồn cho Long.valueOf(String), nó nội bộ gọi Long.valueOf(long), có mã nguồn Tôi đã đăng tải dưới đây: -

public static Long valueOf(String s) throws NumberFormatException 
{ 
    return Long.valueOf(parseLong(s, 10)); 
} 

public static Long valueOf(long l) { 
    final int offset = 128; 
    if (l >= -128 && l <= 127) { // will cache 
     return LongCache.cache[(int)l + offset]; 
    } 
    return new Long(l); 
} 
+0

Đây chính xác là những gì tôi đã hiểu trước khi tìm kiếm http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/java/lang/Long.java này, bạn có thể chia sẻ liên kết nguồn. –

+2

@ArunManivannan .. Bạn có thể tìm mã nguồn trong thư mục cài đặt jdk. Đi tới 'C: \ Program Files \ Java \ jdk' sẽ có một thư mục' src'. Có thể ở định dạng nén. Giải nén nó. Đi tới 'java -> lang -> Long.class' để xem mã nguồn. –

+0

Điều này rất hữu ích, cảm ơn đoạn mã và giải thích. – AWT

3

Họ có ý nghĩa giống

public static Long valueOf(String s) throws NumberFormatException{ 
     return new Long(parseLong(s, 10)); 
} 

public Long(String s) throws NumberFormatException { 
    this.value = parseLong(s, 10); 
} 

Source JDK 6.0

+0

Arun, chúng giống nhau nếu s nằm ngoài phạm vi nào đó (- 128 t0 127), nếu s ở trong phạm vi, chúng không giống nhau. – kosa

+0

Bạn đang sử dụng phiên bản Java nào? Trong các phiên bản Java 6 và 7 của tôi, một bộ nhớ đệm được sử dụng. –

+0

@Nambari Tôi cũng nghĩ như vậy. Tuy nhiên, việc thực hiện là đáng ngạc nhiên. –

8

Long.valueOf() nên được ưa thích: nó sẽ trả về giá trị được lưu trữ của Long cho một số giá trị thường được sử dụng thay vì xây dựng một trường hợp mới như các nhà xây dựng không.

Thậm chí nếu một số phiên bản Java không sử dụng bộ nhớ cache, sử dụng valueOf() làm cho nó có thể có trong các phiên bản sau, trong khi nhà xây dựng sẽ luôn tạo một phiên bản mới.

+0

+1, điều này là chính xác. Long.valueOf được ưu tiên. – kosa

+0

Phạm vi giá trị đó là '[-128 đến 127]' để cụ thể. Nhưng, tôi nghĩ rằng có thể thay đổi. Không biết chính xác. –

3

Cả hai làm parseLong(String, int) nội bộ (int là radix có giá trị như 10), nhưng valueOf có lợi thế như tài liệu dưới đây:

If a new Long instance is not required, this method should generally be used in preference to the constructor Long(long), as this method is likely to yield significantly better space and time performance by caching frequently requested values.

0

Đây là PMD cắm đặt ra được điều hành trên thực

Mã tôi đã chọn là

Long l = new Long("123456"); 

Trong JDK 1.5, gọi mới Long() gây ra phân bổ bộ nhớ. Long.valueOf() là bộ nhớ thân thiện hơn.

0

tôi đang nghĩ cách thay đổi phạm vi và kích thước của bộ nhớ cache cho ứng dụng của chúng tôi, quá tải với Longs;

sự thay đổi đó không được hỗ trợ bởi api J2SE Một cách là thay đổi nạp mã byte java với ClassLoader hoặc thậm chí với JVMTI (nó cho phép để giữ lừa như vậy ra của dự án, như điều chỉnh bên ngoài)

hoặc , có thể, để tạo bộ đệm ẩn bên ngoài và lưu trữ static cachedValueOf() thẳng về phía trước, nhưng mã tùy thuộc vào một số nhu cầu không ứng dụng là không tốt đẹp

+0

Có phải câu trả lời cho câu hỏi không? Bạn nên sử dụng tùy chọn 'câu hỏi' để đặt câu hỏi. – idlerboris