เหตุผลใดในการล้างการนำเข้าที่ไม่ได้ใช้ใน Java นอกเหนือจากการลดความยุ่งเหยิง


99

มีเหตุผลที่ดีในการหลีกเลี่ยงคำสั่งนำเข้าที่ไม่ได้ใช้ใน Java หรือไม่? ตามที่ฉันเข้าใจมันมีไว้สำหรับคอมไพเลอร์ดังนั้นการนำเข้าที่ไม่ได้ใช้จำนวนมากจะไม่มีผลกระทบใด ๆ กับโค้ดที่คอมไพล์ เป็นเพียงเพื่อลดความยุ่งเหยิงและหลีกเลี่ยงความขัดแย้งในการตั้งชื่อหรือไม่?

(ฉันถามเพราะ Eclipse ให้คำเตือนเกี่ยวกับการนำเข้าที่ไม่ได้ใช้ซึ่งเป็นเรื่องที่น่ารำคาญเมื่อฉันพัฒนาโค้ดเพราะฉันไม่ต้องการลบการนำเข้าจนกว่าฉันจะแน่ใจว่าฉันออกแบบคลาสเสร็จแล้ว)

คำตอบ:


86

ฉันไม่คิดว่าจะมีปัญหาด้านประสิทธิภาพหรืออะไรทำนองนั้นหากคุณไม่ได้ลบการนำเข้าออก

แต่อาจมีความขัดแย้งในการตั้งชื่อในบางกรณีเช่นการนำเข้าอินเทอร์เฟซรายการ

ใน Eclipse คุณสามารถใช้ทางลัด (ขึ้นอยู่กับ OS - Win: Ctrl + SHIFT + Oและ Mac :) COMMAND + SHIFT + Oเพื่อจัดระเบียบการนำเข้า Eclipse แล้วทำความสะอาดส่วนการนำเข้าลบทั้งหมดนำเข้าเก่า ฯลฯ Ctrl + SPACEหากคุณจำเป็นต้องเป็นสิ่งที่นำเข้าอีกครั้งคราสจะเพิ่มให้โดยอัตโนมัติในขณะที่คุณเสร็จสิ้นคำสั่งด้วย ดังนั้นจึงไม่จำเป็นต้องเก็บรหัสที่ไม่ได้ใช้ไว้ในชั้นเรียนของคุณ

เช่นเคยรหัสที่ไม่ได้ใช้จะทำให้คุณและคนอื่น ๆ เสียสมาธิในขณะที่อ่านโค้ดและทิ้งบางอย่างไว้ในโค้ดที่ใช้งานอยู่เพราะบางทีฉันต้องการใช้ในภายหลังส่วนใหญ่ถูกมองว่าเป็นการปฏิบัติที่ไม่ดี


22
จริงๆแล้วมันคือ Ctrl + Shift + O บน windows
Matt Ball

1
Ctrl + Shift + O บน linux ได้ดี อาจเหมือนกันใน BSD
WhyNotHugo

2
อีกวิธีหนึ่งในการเข้าถึงการดำเนินการจัดระเบียบการนำเข้าคือการคลิกctrl+3(อย่างน้อยใน windwos) แล้วพิมพ์การนำเข้า เห็นได้ชัดว่าช้ากว่าแล้ว ctrl + shift + O แต่เป็นวิธีค้นหาได้อย่างรวดเร็ว (และการกระทำอื่น ๆ อีกมากมายที่คุณจำได้หรือพยายามค้นหา) แม้ว่าคุณจะจำทางลัดเฉพาะสำหรับสิ่งนี้ไม่ได้ก็ตาม
epeleg

53

อย่างหนึ่งก็คือถ้าคุณลบคลาสที่อ้างถึงโดยการนำเข้าจาก classpath คุณจะไม่ได้รับข้อผิดพลาดของคอมไพเลอร์โง่ ๆ ที่ไม่มีจุดประสงค์ และคุณจะไม่ได้รับผลบวกที่ผิดพลาดเมื่อคุณทำการค้นหา "ที่ใช้"

อีกประการหนึ่ง (แต่จะมีลักษณะเฉพาะเจาะจงมาก) ก็คือหากการนำเข้าที่ไม่ได้ใช้มีการตั้งชื่อขัดแย้งกับการนำเข้าอื่นทำให้คุณใช้ชื่อที่มีคุณสมบัติครบถ้วนโดยไม่จำเป็น

ภาคผนวก: วันนี้บิลด์เซิร์ฟเวอร์เริ่มการคอมไพล์ล้มเหลว (ไม่ได้ทดสอบการทำงาน) โดยมีข้อผิดพลาดหน่วยความจำไม่เพียงพอ มันทำงานได้ดีตลอดไปและการเช็คอินไม่มีการเปลี่ยนแปลงใด ๆ ในกระบวนการสร้างหรือส่วนเพิ่มเติมที่สำคัญที่สามารถอธิบายสิ่งนี้ได้ หลังจากพยายามเพิ่มการตั้งค่าหน่วยความจำ (กำลังเรียกใช้ JVM 64 บิตบน CentOS 64 บิต!) ไปยังสิ่งที่ดีกว่าที่ไคลเอ็นต์สามารถรวบรวมได้ฉันตรวจสอบเช็คอินทีละรายการ

มีการนำเข้าที่ไม่เหมาะสมซึ่งนักพัฒนาได้ใช้และละทิ้ง (พวกเขาใช้คลาสนี้นำเข้าโดยอัตโนมัติแล้วจึงรู้ว่าเป็นข้อผิดพลาด) การนำเข้าที่ไม่ได้ใช้นั้นดึงระดับแอปพลิเคชันที่แยกจากกันทั้งหมดซึ่งในขณะที่ IDE ไม่ได้กำหนดค่าให้แยกพวกเขากระบวนการสร้างคือ การนำเข้าครั้งเดียวนั้นลากไปในคลาสจำนวนมากที่คอมไพเลอร์พยายามคอมไพล์โดยไม่ต้องมีไลบรารีที่เกี่ยวข้องที่เกี่ยวข้องในคลาสพา ธ ซึ่งทำให้เกิดปัญหามากมายที่ทำให้เกิดข้อผิดพลาดหน่วยความจำไม่เพียงพอ ใช้เวลาหนึ่งชั่วโมงในการแก้ปัญหานี้เนื่องจากการนำเข้าที่ไม่ได้ใช้งาน


4
@Yishai หากคุณใช้ Eclipse ให้มองเข้าไปใน Save Actions ซึ่งสามารถทำให้ซอร์สโค้ดเป็นปกติทุกครั้งที่คุณบันทึก
Thorbjørn Ravn Andersen

2
@EJP แม้ว่าจะไม่มีผลกับ bytecode ที่เป็นผลลัพธ์ แต่คอมไพเลอร์จำเป็นต้องแก้ไขเพื่อให้เข้าใจ bytecode ที่ต้องการสร้าง
Yishai

3
@EJP ภาคผนวกทั้งหมดกำลังพูดถึงเวลาในการคอมไพล์ ("การสร้างเซิร์ฟเวอร์เริ่มการคอมไพล์ล้มเหลว")
Yishai

1
ฉันยังไม่เข้าใจว่าการนำเข้าเพียงอย่างเดียวอาจทำให้เกิดทั้งหมดนี้ได้อย่างไร?
Thorbjørn Ravn Andersen

1
@Yishai ขอโทษนะ แต่ไม่เชื่อ คุณได้วินิจฉัยสิ่งนี้ผิดพลาด การนำเข้าไม่ควรมีผลดังกล่าวเว้นแต่จะมีการใช้คลาสจริง คำสั่งนำเข้าทั้งหมดจะบอกคอมไพลเลอร์ว่าแพ็กเกจนั้นอยู่ในคลาสใดคอมไพเลอร์จะพยายามคอมไพล์โดยปริยายเมื่อต้องการข้อมูลประเภทเกี่ยวกับคลาสนั้นเท่านั้น
Marquis of Lorne

9

จากมุมมองของคนเจ้าระเบียบการพึ่งพาใด ๆ ถือเป็น "ข้อ จำกัด " ของผลิตภัณฑ์และอาจทำให้เกิดปัญหาในการบำรุงรักษาในภายหลัง

ตัวอย่างเช่นสมมติว่าโปรแกรมของคุณใช้คลาส com.XYZObjectPool และหลังจากนั้นคุณตัดสินใจที่จะไม่ใช้ แต่จะไม่ลบการนำเข้า หากตอนนี้มีคนอื่นต้องการสร้างอินสแตนซ์ org.WVYObjectPool และอ้างถึง ObjectPool พวกเขาจะไม่ได้รับคำเตือนใด ๆ เกี่ยวกับเรื่องนี้จนกว่าจะมีปัญหาในการแคสต์หรือปัญหาการเรียกใช้

นี่ไม่ใช่สถานการณ์ที่ไม่สมจริง ทุกครั้งที่คุณมี Eclipse ถามคุณว่าคุณต้องการนำเข้า X เวอร์ชันใดและคุณเลือกหนึ่งจากหลายแพ็กเกจเป็นสถานการณ์ที่หากคุณมีการนำเข้าที่นั่นคุณอาจเลือกผิดโดยไม่รู้ตัว

ไม่ว่าจะด้วยวิธีใดคุณสามารถขอให้ Eclipse ล้างสิ่งเหล่านี้ให้คุณได้


3

คำเตือน? ขอให้ Eclipse ล้างข้อมูลให้คุณโดยอัตโนมัติ นั่นคือสิ่งที่ IntelliJ ทำ หากฉลาดพอที่จะเตือนคุณก็ควรฉลาดพอที่จะทำความสะอาด ฉันขอแนะนำให้มองหาการตั้งค่า Eclipse เพื่อบอกให้หยุดเป็นคนขี้บ่นและทำอะไรบางอย่าง


4
นั่นคือบันทึกการดำเนินการ โดยส่วนตัวแล้วฉันชอบที่ Eclipse จะเปลี่ยนรหัสของคุณเมื่อคุณถามอย่างชัดเจนเท่านั้น
Thorbjørn Ravn Andersen

1
@ Thorbjørn: เห็นด้วยโดยเฉพาะอย่างยิ่งถ้าเป็นคลาสที่ฉันหยุดใช้ไปเล็กน้อย แต่ฉันคาดว่าจะเพิ่มกลับเข้ามาอีกครั้งในไม่ช้า
Donal Fellows

2
@Donal นั่นคือสิ่งที่ Ctrl-Space มีไว้สำหรับ
Thorbjørn Ravn Andersen

3

สิ่งนี้เกี่ยวข้องกับความชัดเจนของโปรแกรมที่มีประโยชน์สำหรับการบำรุงรักษา

หากคุณต้องดูแลโปรแกรมคุณจะพบว่าการนำเข้าคลาสเดียวต่อบรรทัดมีประโยชน์อย่างไร

ลองนึกถึงสถานการณ์ต่อไปนี้:

import company.billing.*;
import company.humanrerources.*;

// other imports 


class SomeClass {
      // hundreds or thousands of lines here... 
    public void veryImportantMethod() {
      Customer customer;
      Employee comployee;
      Department dept. 
      // do something with them
     }
 }

เมื่อคุณแก้ไขข้อผิดพลาดหรือบำรุงรักษาส่วนของโค้ด (หรืออ่านเพียงอย่างเดียว) จะเป็นประโยชน์มากสำหรับผู้อ่านที่จะทราบว่าคลาสที่ใช้เป็นแพ็กเกจใด การใช้การนำเข้าสัญลักษณ์ดังที่แสดงไว้ด้านบนไม่ได้ช่วยในจุดประสงค์ดังกล่าว

แม้จะมี IDE คุณก็ไม่ต้องการที่จะวางเมาส์หรือข้ามไปที่การประกาศและย้อนกลับมันจะง่ายกว่าถ้าคุณเข้าใจในแง่ของฟังก์ชันว่าแพ็กเกจและคลาสอื่น ๆ โค้ดปัจจุบันขึ้นอยู่กับอะไร

หากนี่เป็นโครงการส่วนตัวหรือสิ่งเล็ก ๆ มันไม่สำคัญ แต่สำหรับสิ่งที่ใหญ่กว่าที่นักพัฒนารายอื่นต้องใช้ (และดูแลตลอดหลายปี) นี่คือสิ่งที่ต้องมี

ไม่มีความแตกต่างอย่างแน่นอนกับประสิทธิภาพใด ๆ


3

FYI สิ่งนี้ทำให้ฉันรู้สึกแย่เพราะฉันไม่คิดว่าการจัดระเบียบการนำเข้าจะลบการนำเข้าที่ไม่ได้ใช้ออกไปจริงๆฉันคิดว่ามันแค่จัดเรียง

การลบการนำเข้าโดยอัตโนมัติในระหว่างการดำเนินการบันทึกทำให้ฉันรู้สึกเศร้าเมื่อตัวอย่างเช่นในระหว่างการพัฒนาหรือการทดสอบคุณมีปัญหาและแสดงความคิดเห็นเกี่ยวกับโค้ดเมื่อคุณบันทึกการนำเข้าที่ใช้โดยส่วนที่แสดงความคิดเห็นของโค้ดจะถูกลบออก บางครั้งนี่ไม่ใช่ปัญหาเนื่องจากคุณสามารถยกเลิก ( Ctrl+ Z) การเปลี่ยนแปลงได้ แต่บางครั้งก็ไม่ง่ายอย่างที่คุณอาจทำการเปลี่ยนแปลงอื่น ๆ ฉันยังมีปัญหาที่เมื่อฉันไม่ใส่ความคิดเห็นรหัส (ก่อนหน้านี้ฉันได้แสดงความคิดเห็นแล้วบันทึกไว้ดังนั้นจึงลบการนำเข้าสำหรับรหัสนั้นออก) มันจะพยายามเดาการนำเข้าที่จำเป็นโดยอัตโนมัติและหยิบรหัสที่ไม่ถูกต้อง (เช่นฉันคิดว่าฉัน มีStringUtilsคลาสและเลือกคลาสอื่นที่มีชื่อเดียวกันจากไลบรารีที่ไม่ถูกต้อง)

ฉันชอบจัดระเบียบการนำเข้าด้วยตนเองมากกว่าที่จะให้เป็นการดำเนินการบันทึก


2

สำหรับคราสฉันใช้สิ่งนี้: window -> การตั้งค่า -> java -> ตัวแก้ไข -> บันทึกการดำเนินการ -> เลือกช่องทำเครื่องหมายเพื่อจัดระเบียบการนำเข้า (มีสิ่งที่มีประโยชน์อื่น ๆ อีกมากมายเช่นการจัดรูปแบบการทำให้ฟิลด์เป็นขั้นสุดท้ายและอื่น ๆ .). ดังนั้นเมื่อฉันบันทึกไฟล์ eclipse ของฉันจะลบการนำเข้า unessacry ให้ฉัน ในความคิดของฉันถ้าคุณไม่ต้องการบางสิ่งบางอย่างให้ลบออก (หรือปล่อยให้มันถูกลบออกโดยคราส)


2

คุณสามารถแสดงความคิดเห็นในข้อความนำเข้าที่ไม่ได้ใช้และคำเตือนจะไม่รบกวนคุณ แต่คุณสามารถดูสิ่งที่คุณมีได้


2
@DimaSan เป็นจริง: คำถามบอกว่าฉันไม่ต้องการลบการนำเข้าจนกว่าฉันจะแน่ใจว่าฉันออกแบบชั้นเรียนเสร็จแล้ว
The Vee

1

ไม่มีผลกระทบด้านประสิทธิภาพใด ๆ แม้ว่าคุณสามารถอ่านได้เพื่อความสะอาด การลบการนำเข้าที่ไม่ได้ใช้นั้นค่อนข้างง่ายทั้งใน Eclipse และ IntelliJ IDEA

คราส

Windows / Linux -    Ctrl+ Shift+O

Mac -                        Cmd+ Shift+O

IntelliJ IDEAหรือAndroid Studio

Windows / Linux -    Ctrl+ Alt+O

Mac -                        Cmd+ Alt+O


0

ฉันอ่านที่ไหนสักแห่งเมื่อหลายปีก่อนว่าทุกคลาสที่นำเข้าจะถูกโหลดที่รันไทม์ด้วยคลาสอิมพอร์ต ดังนั้นการลบที่ไม่ได้ใช้โดยเฉพาะอย่างยิ่งทั้งแพ็คเกจจะช่วยลดค่าใช้จ่ายของหน่วยความจำ แม้ว่าฉันคิดว่า java เวอร์ชันใหม่จะจัดการกับสิ่งนั้นได้ดังนั้นอาจไม่ใช่เหตุผลอีกต่อไป

และโดยวิธีการที่ eclipse คุณสามารถใช้Ctrl+ Shift+ Oเพื่อจัดระเบียบการนำเข้า แต่คุณยังสามารถกำหนดค่า "ตัวล้าง" ที่จัดการกับสิ่งเหล่านี้ (และอื่น ๆ อีกมากมาย) ทุกครั้งที่คุณบันทึกไฟล์ java


อืม .. ฉันจะแปลกใจถ้านั่นคือพฤติกรรม .. ฉันรู้ว่าคลาสไม่ได้ถูกเตรียมใช้งาน (เช่นการเรียกตัวเริ่มต้นแบบคงที่) จนกว่าจะใช้งานครั้งแรกหรือจนกว่าจะมีการร้องขอโดยเฉพาะจากตัวโหลดแบบกำหนดเอง แต่ถ้าโดย "โหลด" คุณแค่หมายถึง "อ่านลงในหน่วยความจำ แต่ไม่ได้ประมวลผล" เป็นไปได้แม้ว่าฉันจะสงสัยก็ตาม
กีบ

จริงๆแล้วเมื่อคิดต่อไปมันควรจะทดสอบได้ง่ายพอสมควร คอมไพล์โค้ดด้วยการนำเข้าที่ไม่ได้ใช้งานจากนั้นใช้เครื่องมือ "ถอดรหัส" และดูว่ายังมีการนำเข้าที่ไม่ได้ใช้งานอยู่หรือไม่ ถ้าไม่เช่นนั้นพวกเขาจะถูกลบออกโดยคอมไพเลอร์หรือพวกเขาอยู่ที่นั่นเพื่อความสะดวกสำหรับโปรแกรมเมอร์
กีบ

4
คุณอ่านสิ่งนั้นที่ไหนในโลก มันไม่ถูกต้องอย่างสมบูรณ์และเป็นเช่นนั้นเสมอมา ทุกคลาสที่อ้างอิงโดยโค้ดจะถูกโหลดไม่รวมการนำเข้า
Marquis of Lorne

0

สำหรับฉันการนำเข้าคลาสที่ไม่ได้ใช้งานหนึ่งในคลาสคอนโทรลเลอร์สร้างปัญหาการคอมไพล์ในเจนกินส์บิลด์หลังจากที่ฉันลบคลาสที่นำเข้าระหว่างการล้างโค้ดและยืนยันการลบในคอมไพล์โดยไม่ต้องทดสอบบิลด์ในโลคัล

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.