2016-03-22 15 views
11

Tại sao java.text.DecimalFormat đánh giá kết quả sau:Tại sao DecimalFormat ". #" Và "0. #" có kết quả khác nhau trên 23.0?

new DecimalFormat("0.#").format(23.0)  // result: "23" 

new DecimalFormat(".#").format(23.0)   // result: "23.0" 

tôi dự kiến ​​sẽ có kết quả là 23 trong cả hai trường hợp, bởi vì đặc biệt nhân vật # bỏ qua số không. Làm thế nào để ký tự đặc biệt hàng đầu 0 ảnh hưởng đến phần phân số? (Cố gắng để phù hợp/hiểu nó với BNF được đưa ra trong javadoc, nhưng không làm như vậy.)

+0

Tôi tự hỏi nếu '". # "' Là một định dạng hợp lệ và nếu nó không phải là '#. #', Cũng có kết quả là '23'. – Tom

+0

@Tom: DecimalFormat (". 0") cũng hoạt động. Không thấy bất cứ điều gì trong javadoc cấm các công cụ như ". #". – MGn

+0

* "Không thấy bất kỳ thứ gì trong javadoc cấm các nội dung như". # "" * Tôi cũng vậy, nhưng điều đó không có nghĩa là mã có thể xử lý chính xác điều này. Các tác phẩm 'DecimalFormat (". 0 ")' có thể trùng hợp ngẫu nhiên khi '. #' Hoặc '.0' không hợp lệ và" dự phòng "chỉ in số, vì nó sẽ dẫn đến cùng một chuỗi (' "23.0" '). Nhưng một lần nữa, nó chỉ là một phỏng đoán. – Tom

Trả lời

7

Định dạng thứ hai có vẻ không hợp lệ theo JavaDoc, nhưng bằng cách nào đó nó phân tích mà không có lỗi.

Pattern: 
     PositivePattern 
     PositivePattern ; NegativePattern 
PositivePattern: 
     Prefixopt Number Suffixopt 
NegativePattern: 
     Prefixopt Number Suffixopt 
Prefix: 
     any Unicode characters except \uFFFE, \uFFFF, and special characters 
Suffix: 
     any Unicode characters except \uFFFE, \uFFFF, and special characters 
Number: 
     Integer Exponentopt 
     Integer . Fraction Exponentopt 
Integer: 
     MinimumInteger 
     # 
     # Integer 
     # , Integer 
MinimumInteger: 
     0 
     0 MinimumInteger 
     0 , MinimumInteger 
Fraction: 
     MinimumFractionopt OptionalFractionopt 
MinimumFraction: 
     0 MinimumFractionopt 
OptionalFraction: 
     # OptionalFractionopt 
Exponent: 
     E MinimumExponent 
MinimumExponent: 
     0 MinimumExponentopt 

Trong trường hợp này tôi mong đợi hành vi của các định dạng được xác định. Đó là, nó có thể tạo ra bất kỳ điều cũ và chúng ta không thể dựa vào đó là phù hợp hoặc có ý nghĩa trong bất kỳ cách nào. Vì vậy, tôi không biết tại sao bạn đang nhận được 23.0, nhưng bạn có thể giả định rằng nó là vô nghĩa mà bạn nên tránh trong mã của bạn.

Cập nhật: Tôi vừa chạy trình gỡ rối thông qua thư viện DecimalFormat của Java 7. Mã không chỉ cho biết rõ ràng rằng '. #' Được cho phép, có một chú thích trong đó (java.text.DecimalFormat: 2582-2593) cho biết nó được cho phép và thực hiện cho phép nó (dòng 2597). Điều này có vẻ là vi phạm của BNF tài liệu cho mẫu.

Cho rằng đây không phải là hành vi được ghi lại tài liệu, bạn thực sự không nên dựa vào nó vì nó chịu trách nhiệm thay đổi giữa các phiên bản Java hoặc thậm chí triển khai thư viện.

3

Nhận xét nguồn sau đây giải thích việc xử lý khá không trực quan của ".#". Dòng 3383-3385 ​​trong DecimalFormat.java tập tin của tôi (JDK 8) có những nhận xét sau đây:

// Handle patterns with no '0' pattern character. These patterns 
// are legal, but must be interpreted. "##.###" -> "#0.###". 
// ".###" -> ".0##". 

Có vẻ như các nhà phát triển đã chọn để giải thích ".#" như ".0##", thay vì những gì bạn mong đợi ("0.#").

+0

Tôi vừa xem mã nguồn cho DecimalFormat và thấy điều này. – callyalater

+0

Tôi đã ghi lại rằng trong câu trả lời của tôi, nhưng tôi có số dòng khác nhau cho bạn. Tôi tự hỏi nguyên nhân gây ra sự khác biệt đó là gì? Bạn chưa đề cập đến phiên bản java nào bạn đang tham chiếu ở đây. Bạn có thể thêm điều đó cho rõ ràng vì nó có thể có trách nhiệm không? –

+0

Tôi đang sử dụng JDK 8, đó là sự khác biệt. – MicSim

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