ฉันเจอสองวิธีในการดึงวัตถุ BigDecimal ออกจาก d สองเท่า
1. new BigDecimal(d)
2. BigDecimal.valueOf(d)
จะเป็นแนวทางไหนดี มูลค่าของการสร้างวัตถุใหม่หรือไม่?
โดยทั่วไป (ไม่ใช่แค่ BigDecimal) สิ่งที่แนะนำ - new หรือ valueOf?
ขอบคุณ.
ฉันเจอสองวิธีในการดึงวัตถุ BigDecimal ออกจาก d สองเท่า
1. new BigDecimal(d)
2. BigDecimal.valueOf(d)
จะเป็นแนวทางไหนดี มูลค่าของการสร้างวัตถุใหม่หรือไม่?
โดยทั่วไป (ไม่ใช่แค่ BigDecimal) สิ่งที่แนะนำ - new หรือ valueOf?
ขอบคุณ.
คำตอบ:
คำถามสองข้อนี้แยกกัน: "ฉันควรใช้เพื่อBigDecimal
อะไร" และ "ฉันทำอะไรโดยทั่วไป"
สำหรับBigDecimal
: นี่คือบิตหากินเพราะพวกเขาไม่ได้ทำในสิ่งเดียวกัน BigDecimal.valueOf(double)
จะใช้การแสดงค่าตามมาตรฐานString
ของdouble
ค่าที่ส่งผ่านเพื่อสร้างอินสแตนซ์ของBigDecimal
วัตถุ ในคำอื่น ๆ : ค่าของวัตถุจะเป็นสิ่งที่คุณเห็นเมื่อคุณทำBigDecimal
System.out.println(d)
ถ้าคุณใช้new BigDecimal(d)
อย่างไรแล้วBigDecimal
จะพยายามที่จะเป็นตัวแทนของdouble
ความคุ้มค่าอย่างถูกต้องที่สุด นี้จะมักจะส่งผลให้เกิดมากขึ้นตัวเลขถูกเก็บไว้มากกว่าที่คุณต้องการ พูดอย่างเคร่งครัดถูกต้องมากกว่าvalueOf()
แต่ใช้งานง่ายกว่ามาก
มีคำอธิบายที่ดีเกี่ยวกับสิ่งนี้ใน JavaDoc:
ผลลัพธ์ของตัวสร้างนี้อาจไม่สามารถคาดเดาได้บ้าง อาจสันนิษฐานได้ว่าการเขียน
new BigDecimal(0.1)
ใน Java จะสร้างBigDecimal
ซึ่งมีค่าเท่ากับ 0.1 (ค่าที่ไม่ได้ปรับขนาดเป็น 1 โดยมีมาตราส่วนเป็น 1) แต่จริงๆแล้วมันเท่ากับ 0.1000000000000000055511151231257827021181583404541015625 เนื่องจาก 0.1 ไม่สามารถแทนค่าเป็น adouble
(หรือสำหรับเรื่องนั้นเป็นเศษส่วนไบนารีของความยาว จำกัด ใด ๆ ) ดังนั้นค่าที่ส่งผ่านไปยังตัวสร้างจึงไม่เท่ากับ 0.1 แน่นอนแม้ว่าจะปรากฏก็ตาม
โดยทั่วไปหากผลลัพธ์เหมือนกัน (เช่นไม่ใช่ในกรณีของBigDecimal
แต่ในกรณีอื่น ๆ ส่วนใหญ่) valueOf()
ควรเลือกใช้: สามารถแคชค่าทั่วไป (ตามที่เห็นInteger.valueOf()
) และยังสามารถเปลี่ยนพฤติกรรมการแคชได้โดยไม่ต้อง ต้องเปลี่ยนผู้โทร new
จะสร้างอินสแตนซ์ค่าใหม่เสมอแม้ว่าจะไม่จำเป็นก็ตาม (ตัวอย่างที่ดีที่สุด: new Boolean(true)
กับBoolean.valueOf(true)
)
new BigDecimal()
ดีกว่าBigDecimal.valueOf()
ไหม?
new BigDecimal()
จะเป็นที่ต้องการและตัวอย่างของเวลาที่BigDecimal.valueOf()
จะเป็นที่ต้องการ?
new BigDecimal(1.0/30.0);
และBigDecimal.valueOf(1.0/30.0)
. ดูว่าผลลัพธ์ใดอยู่ใกล้เศษส่วนตัวเลข 1/30 มากขึ้น
หากคุณใช้อBigDecimal
อบเจ็กต์ของคุณเพื่อจัดเก็บค่าสกุลเงินฉันขอแนะนำอย่างยิ่งว่าคุณไม่ต้องเกี่ยวข้องกับค่าสองค่าใด ๆ ในการคำนวณ
ตามที่ระบุไว้ในคำตอบอื่นมีปัญหาความแม่นยำที่ทราบกันดีเกี่ยวกับค่าสองค่าและสิ่งเหล่านี้จะกลับมาหลอกหลอนคุณ
เมื่อคุณผ่านพ้นจุดนั้นมาได้คำตอบสำหรับคำถามของคุณก็ง่าย มักจะใช้วิธีการสร้างมูลค่า String เป็นอาร์กิวเมนต์ที่จะสร้างเป็นไม่มีวิธีการvalueOf
String
หากคุณต้องการหลักฐานให้ลองทำดังต่อไปนี้:
BigDecimal bd1 = new BigDecimal(0.01);
BigDecimal bd2 = new BigDecimal("0.01");
System.out.println("bd1 = " + bd1);
System.out.println("bd2 = " + bd2);
คุณจะได้รับผลลัพธ์ต่อไปนี้:
bd1 = 0.01000000000000000020816681711721685132943093776702880859375
bd2 = 0.01
ดูคำถามที่เกี่ยวข้องนี้ด้วย
โดยทั่วไป valueOf (double val) ทำสิ่งนี้:
return new BigDecimal(Double.toString(val));
ดังนั้น -> ใช่วัตถุใหม่จะถูกสร้างขึ้น :)
โดยทั่วไปฉันคิดว่ามันขึ้นอยู่กับรูปแบบการเข้ารหัสของคุณ ฉันจะไม่ผสมค่าของและ "ใหม่" ถ้าทั้งสองผลลัพธ์เหมือนกัน
valueOf()
มีมากขึ้นใช้งานง่ายพฤติกรรมในขณะที่new BigDecimal(d)
มีมากขึ้นที่ถูกต้องอย่างใดอย่างหนึ่ง ลองทั้งสองอย่างและดูความแตกต่าง
new BigDecimal(1) != new BigDecimal(1)
แต่BigDecimal.valueOf(1) == BigDecimal.valueOf(1)
BigDecimal
จะไม่เปลี่ยนรูปมันควรจะได้รับการปฏิบัติเช่นเดียวกับที่ห่อดั้งเดิม ( Integer
, Byte
, ... ) และString
ได้รับการรักษา: ตัวตนของวัตถุที่ไม่ควรเรื่องรหัสของคุณเพียงค่าควรเรื่อง
valueOf()
ควรเป็นที่ต้องการ แต่โปรดทราบว่าไม่ได้ทำการแคชใด ๆ (และอาจจะไม่คุ้มค่าด้วย) BigDecimal.valueOf(double)