คำตอบคือ "เพราะสแกนเนอร์มีสถานะ"
ดูรหัสสำหรับ java.util.Scannerคุณจะเห็นจำนวนฟิลด์ส่วนตัวเช่นบัฟเฟอร์และข้อมูลที่เกี่ยวข้อง, Matcher, รูปแบบ, แหล่งอินพุต, ข้อมูลเกี่ยวกับว่าแหล่งข้อมูลถูกปิดหรือไม่, ประเภท ของสิ่งสุดท้ายที่ตรงกันข้อมูลเกี่ยวกับสิ่งสุดท้ายคือการจับคู่ที่ถูกต้องหรือไม่ Radix ที่ใช้สำหรับตัวเลขตำแหน่งที่ตั้ง (ข้อมูลเกี่ยวกับว่าคุณกำลังใช้.
หรือ,
เป็นตัวคั่นหลักพัน) และแคช LRU ของตัวเองสำหรับรูปแบบที่ใช้ล่าสุด ข้อมูลเกี่ยวกับข้อยกเว้นสุดท้ายที่พบข้อมูลเกี่ยวกับการแยกตัวเลขบางข้อมูลเกี่ยวกับการแยก booleans ข้อมูลเพิ่มเติมเล็กน้อยเกี่ยวกับการแยกจำนวนเต็ม ... และฉันคิดว่ามันเกี่ยวกับมัน
อย่างที่คุณเห็นนั่นเป็นบล็อกข้อความขนาดใหญ่พอสมควร นั่นคือสถานะของเครื่องสแกน เพื่อที่จะทำให้สแกนเนอร์เป็นคลาสที่คงที่สถานะนั้นจะต้องถูกเก็บไว้ที่อื่น วิธีการทำ C จริงๆมันไม่ได้มีสถานะที่มากด้วย fscanf
คุณมี ไฟล์จะรักษาสถานะบางอย่างเกี่ยวกับตำแหน่งที่มันอยู่ที่ (แต่ต้องผ่านในแต่ละครั้งที่เรียกใช้fscanf
) หากมีข้อผิดพลาดคุณต้องดำเนินการ (และจากนั้นคุณเริ่มเขียนโค้ดที่มีลักษณะเช่นนี้ ) - และนั่นไม่ได้บอกข้อมูลเช่น "ฉันคาดหวังว่ามีจำนวนเต็ม แต่พบสตริง"
เมื่อมีคนดูที่เครื่องสแกนแบบคงที่ในทางทฤษฎี - สถานะทั้งหมดถูกเก็บรักษาไว้ภายนอกคลาสนั้นจะไม่ถูกห่อหุ้มภายในคลาส บิตของรหัสอื่นสามารถแก้ไขด้วยตัวแปรเหล่านั้น เมื่อรหัสอื่นสามารถคนจรจัดกับสถานะของชั้นมันจะยากมากที่จะให้เหตุผลเกี่ยวกับสิ่งที่ชั้นจะทำในสถานการณ์ใดก็ตาม
คุณอาจจะเขียนสิ่งที่ชอบScannerState { Locale loc; ... }
และมีรหัสที่เป็นผลลัพธ์:
ScannerState state = new ScannerState(a whole lot of arguments);
int foo = Scanner.nextInt(state);
แต่สิ่งนี้ยุ่งยากกว่าการห่อหุ้มสถานะของวัตถุสแกนเนอร์ในตอนแรก (และไม่จำเป็นต้องผ่านในสถานะ)
สุดท้ายสแกนเนอร์ใช้อินเทอร์เฟซIterator<String>
ซึ่งหมายความว่าหนึ่งสามารถใช้ในรหัสเช่น:
Scanner in = new Scanner(someFile);
whie(in.hasNext()) { ... }
โดยไม่สามารถรับอินสแตนซ์ของคลาสสแกนเนอร์ได้โครงสร้างประเภทนี้จะยุ่งยากกว่าในภาษาเชิงวัตถุ