เหตุใดการใช้ไวด์การ์ดที่มีคำสั่งการนำเข้า Java ไม่ดี?


419

มันสะดวกกว่าและสะอาดกว่าหากใช้คำสั่งเดียวเช่น

import java.awt.*;

กว่าจะนำเข้ากลุ่มของแต่ละคลาส

import java.awt.Panel;
import java.awt.Graphics;
import java.awt.Canvas;
...

เกิดอะไรขึ้นกับการใช้สัญลักษณ์แทนในimportคำสั่ง

คำตอบ:


518

ปัญหาเดียวของมันคือมัน clutters namespace ท้องถิ่นของคุณ ตัวอย่างเช่นสมมุติว่าคุณกำลังเขียนแอปสวิงและเพื่อความต้องการjava.awt.Eventและยังมีการเชื่อมต่อกับระบบปฏิทินของ บริษัท ฯ com.mycompany.calendar.Eventซึ่งมี หากคุณนำเข้าทั้งสองโดยใช้วิธีไวด์การ์ดวิธีหนึ่งในสามสิ่งนี้จะเกิดขึ้น:

  1. คุณมีความขัดแย้งระหว่างการตั้งชื่อทันทีjava.awt.Eventและcom.mycompany.calendar.Eventและเพื่อให้คุณไม่สามารถแม้แต่จะรวบรวม
  2. คุณจัดการเพื่อนำเข้าเพียงรายการเดียว (มีเพียงหนึ่งในสองการนำเข้าของคุณเท่านั้น) แต่เป็นการนำเข้า.*ที่ผิดและคุณพยายามหาสาเหตุที่รหัสของคุณอ้างว่าเป็นประเภทที่ไม่ถูกต้อง
  3. เมื่อคุณรวบรวมรหัสของคุณไม่มีcom.mycompany.calendar.Eventแต่เมื่อพวกเขาเพิ่มหนึ่งรหัสที่ถูกต้องก่อนหน้านี้ของคุณก็หยุดรวบรวม

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


7
มันเป็นสถานการณ์แรกที่จะเกิดขึ้น คอมไพเลอร์แจ้งว่ามีคลาสเหตุการณ์สองคลาสและให้ข้อผิดพลาด
jan.vdbergh

38
ตรวจสอบให้แน่ใจเพื่อตรวจสอบความคิดเห็นของฉันด้านล่าง - มีปัญหามากขึ้นกับประเภทที่ถูกเพิ่มไปยัง libs บุคคลที่สามในช่วงเวลา คุณสามารถมีรหัสการคอมไพล์ที่หยุดการคอมไพล์หลังจากมีคนเพิ่มชนิดลงใน jar ที่คุณพึ่งพา
Scott Stanchfield

6
เกี่ยวกับปัญหาที่ 1: ในทางเทคนิคคุณสามารถรวบรวมได้ แต่คุณจะต้องใช้ชื่อคลาสที่ผ่านการรับรองทุกครั้ง
กีบ

1
คุณสามารถแก้ไขข้อขัดแย้งประเภทนี้ได้โดยไม่ต้องแสดงรายการทุกคลาสอย่างชัดเจนซึ่งทำให้เกิดปัญหาของตัวเอง
rpjohnst

196

นี่คือการลงคะแนนสำหรับการนำเข้าดาว คำสั่งการนำเข้ามีวัตถุประสงค์เพื่อนำเข้าแพคเกจไม่ใช่ชั้นเรียน มันสะอาดกว่าการนำเข้าแพ็คเกจทั้งหมด; ปัญหาที่ระบุที่นี่ (เช่นjava.sql.Datevs java.util.Date) นั้นสามารถแก้ไขได้อย่างง่ายดายด้วยวิธีการอื่นไม่ใช่เรื่องจริงการแก้ไขโดยการนำเข้าที่เฉพาะเจาะจงและแน่นอนไม่ได้ปรับการนำเข้าอวดความรู้เมามันในชั้นเรียนทั้งหมด ไม่มีอะไรที่ทำให้สับสนมากกว่าการเปิดไฟล์ต้นฉบับและต้องผ่านคำสั่งนำเข้า 100 รายการ

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

แม้ว่า Eclipse จะไม่นำเข้าคลาสโดยค่าเริ่มต้นทุกคนจะยังคงนำเข้าดาว ฉันขอโทษ แต่ไม่มีเหตุผลที่สมเหตุสมผลสำหรับการทำการนำเข้าเฉพาะ

นี่คือวิธีจัดการกับความขัดแย้งในชั้นเรียน:

import java.sql.*;
import java.util.*;
import java.sql.Date;

28
ฉันเห็นด้วย. แม้ว่าฉันจะไม่ได้ต่อต้านการใช้การนำเข้าที่ชัดเจน แต่ฉันก็ยังต้องการใช้การนำเข้าดาว พวกเขาเน้นว่า "หน่วยการใช้ซ้ำ" เป็นทั้งแพ็คเกจไม่ใช่ประเภทของแต่ละบุคคล เหตุผลที่คนอื่น ๆ ไม่เห็นด้วยกับการนำเข้าดาวนั้นอ่อนแอและจากประสบการณ์ของฉันที่ใช้การนำเข้าดาวไม่เคยทำให้เกิดปัญหาใด ๆ
Rogério

32
ดูjavadude.com/articles/importondemandisevil.htmlเพื่อดูรายละเอียดว่าทำไมจึงเป็นสิ่งที่ชั่วร้าย แนวคิดพื้นฐาน: อาจทำให้โค้ดหยุดรวบรวมเมื่อมีการเพิ่มคลาสลงในแพ็คเกจที่คุณนำเข้า (เช่นเมื่อเพิ่ม List ไปยัง java.util ... )
Scott Stanchfield

61
ปัญหาทั้งหมดที่คุณพูดถึงสามารถแก้ไขได้โดย IDE ที่ทันสมัย ​​(ซ่อนการนำเข้า, เปลี่ยนชื่อคลาส, ฯลฯ ... )
assylias

15
ฉันไม่ควรใช้ IDE ในการอ่านหรือเขียนซอร์สโค้ด - โค้ดควรอ่านได้ด้วยตัวเองโดยไม่ต้องใช้เครื่องมือพิเศษเว้นแต่ภาษาจะมีการใช้ภาษาที่ยอดเยี่ยม ในกรณีนี้ Java ใช้งานได้ดีเพียงใช้ดาวนำเข้า ไม่มีเหตุผลที่จะไม่ทำ
davetron5000

42
@ davetron5000 หากรหัสของคุณมีการนำเข้าไวด์การ์ดมากกว่า 10+ และคุณใช้คลาสFooและถ้าฉันอ่านรหัสของคุณโดยไม่ใช้ IDE (เนื่องจากข้อโต้แย้งของคุณคือฉันไม่ควรใช้อย่างใดอย่างหนึ่ง) ฉันจะรู้ได้อย่างไรว่าแพคเกจFooมาจากไหน? แน่นอนว่าการใช้ IDE นั้น IDE จะบอกฉัน แต่ข้อโต้แย้งทั้งหมดของคุณคือฉันควรจะสามารถอ่านรหัสได้โดยไม่มีใคร การทำการนำเข้าอย่างชัดเจนช่วยเอกสารรหัส (เหตุผลที่ดีในการหลีกเลี่ยงสัญลักษณ์เสริม)และมีแนวโน้มมากที่ฉันจะอ่านรหัสโดยไม่ใช้ IDE มากกว่าที่ฉันจะเขียนรหัสโดยไม่ใช้ IDE
Andreas

169

โปรดดูบทความการนำเข้าตามความต้องการคือความชั่วร้าย

กล่าวโดยย่อปัญหาที่ใหญ่ที่สุดคือรหัสของคุณอาจแตกเมื่อมีการเพิ่มคลาสลงในแพ็คเกจที่คุณนำเข้า ตัวอย่างเช่น:

import java.awt.*;
import java.util.*;

// ...

List list;

ใน Java 1.1 นี่ใช้ได้ พบรายการใน java.awt และไม่มีข้อขัดแย้ง

ตอนนี้สมมติว่าคุณตรวจสอบรหัสการทำงานที่สมบูรณ์แบบของคุณและอีกหนึ่งปีต่อมามีคนนำมันออกมาเพื่อแก้ไขและใช้ Java 1.2

Java 1.2 เพิ่มอินเตอร์เฟสชื่อ List ไปยัง java.util BOOM! ขัดแย้ง. รหัสการทำงานที่สมบูรณ์แบบไม่ทำงานอีกต่อไป

นี่เป็นคุณสมบัติภาษาEVIL นอกจากนี้ไม่มีเหตุผลว่ารหัสควรจะหยุดการรวบรวมเพียงเพราะเป็นชนิดที่มีการเพิ่มการแพคเกจ ...

นอกจากนี้ยังทำให้ผู้อ่านระบุได้ยากว่า "Foo" ที่คุณใช้อยู่


35
นี่ไม่ใช่ข้อแก้ตัวที่ถูกต้อง หากคุณกำลังเปลี่ยนรุ่นจาวาคุณคาดหวังว่าบางสิ่งบางอย่างจะล้มเหลวเหมือนกันถ้าคุณเปลี่ยนรุ่นของรหัสไบนารีที่คุณใช้ ในกรณีเหล่านี้รหัสจะมีข้อผิดพลาดในการคอมไพล์และเล็กน้อยเพื่อแก้ไข (ดูคำตอบก่อนหน้านี้: stackoverflow.com/a/149282/7595 )
Pablo Fernandez

36
@PabloFernandez - Nope - หากฉันตรวจสอบรหัสที่อยู่ในพื้นที่เก็บข้อมูลเป็นเวลาหนึ่งปีก็ควรจะรวบรวม การนำเข้าตามความต้องการสามารถล้มเหลวได้อย่างง่ายดายเมื่อมีการเพิ่มคลาสใหม่ลงในแพ็คเกจที่มีอยู่ที่ฉันได้นำเข้า ไม่ใช่แค่ปัญหาเมื่ออัพเกรดเวอร์ชั่น Java นอกจากนี้ - ถ้า API ได้รับการออกแบบมาอย่างดีมันไม่ควรทำลายรหัสที่มีอยู่ในการอัพเกรด ครั้งเดียวที่ฉันจำเป็นต้องเปลี่ยนรหัสเมื่ออัปเกรดจาวาเป็นเพราะความต้องการนำเข้าตามความต้องการและเมื่อซันดึง XML APIs ลงในรันไทม์ของจาวา
Scott Stanchfield

3
การเพิ่มคลาส (ด้วยชื่อที่ไม่ซ้ำใครและมีคุณสมบัติครบถ้วน!) ใน classpath ไม่ควรส่งผลกระทบอะไรเลย ประเด็นตรงนี้คือถ้าคุณไม่ใช้ไวยากรณ์นำเข้าตามความต้องการก็จะไม่เกิดขึ้น ดังนั้นอย่าใช้ซินแทกซ์ที่ไม่ดีที่ภาษานั้นน่าเสียดายและนี่เป็นปัญหาที่น้อยมากที่คุณจะได้รับ
Scott Stanchfield

28
ประเด็นของคำตอบคือคุณสมบัติทางภาษาที่ไม่จำเป็นซึ่งทำให้เกิดปัญหา IDEs / บรรณาธิการจำนวนมากจัดการการขยายการนำเข้าโดยอัตโนมัติ ใช้การนำเข้าที่ผ่านการรับรองโดยสมบูรณ์และไม่มีข้อผิดพลาดเกิดขึ้น ฉันได้รับผลกระทบจากสิ่งนี้เมื่ออยู่ภายใต้แรงกดดันเพื่อแก้ไขข้อบกพร่องในโค้ดที่มีอยู่และคุณไม่ต้องการอะไรแบบนี้เพื่อเบี่ยงเบนความสนใจจากงานจริงในมือ java.util.Listvs java.awt.Listไม่เลวเกินไปที่จะคิดออก แต่ลองใช้เมื่อชื่อคลาสเป็นConfigurationและไลบรารีการพึ่งพาจำนวนมากได้เพิ่มเข้าไปในเวอร์ชัน repo maven ล่าสุดของพวกเขา
Scott Stanchfield

5
ถ้าฉันอัปเดต jar โดยที่คลาสที่ฉันใช้นั้นเข้ากันได้กับ API ไปข้างหน้าและฉันไม่ได้ใช้ไวยากรณ์ของการนำเข้าตามความต้องการมันจะไม่ส่งผลกระทบใด ๆ กับฉันเลย นั่นเหมาะสมกับคุณหรือไม่ อย่าขี้เกียจในการกำหนดการนำเข้าและนี่ไม่ใช่ปัญหา ไวยากรณ์การนำเข้าตามคำขอมีข้อผิดพลาดในการกำหนดภาษาจาวา ภาษาที่เหมาะสมไม่ควรให้เกิดข้อผิดพลาดเช่นนี้
Scott Stanchfield

67

การใช้ไวด์การ์ดกับคำสั่งการนำเข้า Java นั้นไม่เลว

ในClean Code , Robert C. Martin แนะนำให้ใช้พวกเขาเพื่อหลีกเลี่ยงรายการนำเข้าที่มีความยาว

นี่คือคำแนะนำ:

J1: หลีกเลี่ยงรายการนำเข้าแบบยาวโดยใช้สัญลักษณ์แทน

หากคุณใช้สองคลาสขึ้นไปจากแพ็คเกจให้นำเข้าแพ็คเกจทั้งหมดด้วย

แพ็คเกจนำเข้า. *;

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

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

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

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


41
ฉันแนะนำให้ Robert C. Martin ใช้รูปแบบที่ดีกว่าเพื่อสร้างแพ็คเกจที่กระชับและคลาสของเขาเองโดยไม่ต้องใช้การนำเข้า 80 บรรทัด คลาสที่จำเป็นสำหรับการนำเข้าภายในคลาสเดียวนั้นเป็นเพียงแค่ขอร้อง 'Entropy, Entropy, ทำลายฉันหน่อยเถอะ ... ' และชี้ให้เห็นเหตุผลที่จะหลีกเลี่ยงการนำเข้า * 's ที่ระบุไว้ใน Scott Stanchfields anwers
Ray

28
เท่าที่ฉันมักจะชอบสิ่งที่ลุงบ๊อบพูดในกรณีนี้ฉันก็ต้องไม่เห็นด้วยกับเขา

33
รายการการนำเข้าแบบยาวนั้นน่ากลัวสำหรับผู้อ่าน - การยืนยันนี้มีข้อสันนิษฐานที่ไม่ถูกต้อง โปรแกรมเมอร์ไม่จำเป็นต้องอ่านซอร์สโค้ดจากบนลงล่าง เราอาจไม่อ่านรายการนำเข้าเลย เมื่อเราทำเราอาจอ่านการนำเข้าเพียงรายการเดียวเพื่อความกระจ่าง ในบางครั้งการนำเข้าอาจถูกยุบทั้งหมดหากเราทำงานใน IDE โดยไม่คำนึงถึงแหล่งที่มาวันนี้เป็นคำแนะนำที่ไม่ดี
Andy Thomas

10
เพียงเพื่อให้น้ำหนักบางอย่างในเมื่อมาถึงการอ้างถึงหน่วยงานในเรื่องนี้: คู่มือสไตล์ Java Javaเช่นเดียวกับคู่มือ Java Style ของ Twitter (ซึ่งส่วนใหญ่ขึ้นอยู่กับ Google เป็นธรรม) โดยเฉพาะห้ามตัวแทนนำเข้า แต่พวกเขาไม่ได้ให้เหตุผลใด ๆ สำหรับการตัดสินใจครั้งนี้
Anothernode

1
อาจเป็นจุดเดียวที่ฉันไม่เห็นด้วยใน Clean Code มันต้องเลื่อนดูข้อความนำเข้าไม่กี่บรรทัดหรือต้องดิ้นรนเพื่อหาว่ามาจากไหน ฉันชอบที่จะระบุได้อย่างง่ายดายว่ามาจากคลาสใด
Ganesh Satpute

27

ประสิทธิภาพการทำงาน : ไม่มีผลกระทบต่อประสิทธิภาพการทำงานเนื่องจากรหัสไบต์เหมือนกัน แม้ว่ามันจะนำไปสู่การรวบรวมค่าโสหุ้ย

การคอมไพล์: บนเครื่องส่วนตัวของฉันการคอมไพล์คลาสเปล่าโดยไม่ต้องอิมพอร์ตอะไรใช้เวลา 100 ms แต่คลาสเดียวกันเมื่ออิมพอร์ต java. * ใช้เวลา 170 ms


3
import java.*นำเข้าอะไร ทำไมมันถึงสร้างความแตกต่าง?
มาร์ควิสแห่ง Lorne

6
มันสร้างความแตกต่างเพราะมันจะถูกค้นหาระหว่างการรวบรวม
LegendLength

25

มันตัดเนมสเปซของคุณโดยกำหนดให้คุณต้องระบุชื่อคลาสที่คลุมเครือ สิ่งที่พบได้บ่อยที่สุดคือ:

import java.util.*;
import java.awt.*;

...
List blah; // Ambiguous, needs to be qualified.

นอกจากนี้ยังช่วยทำให้การอ้างอิงของคุณเป็นรูปธรรมเนื่องจากการอ้างอิงทั้งหมดของคุณแสดงไว้ที่ด้านบนของไฟล์


20
  1. ช่วยระบุความขัดแย้งของชื่อคลาส: สองคลาสในแพ็คเกจที่ต่างกันที่มีชื่อเดียวกัน สามารถถูกหลอกลวงได้ด้วยการนำเข้า *
  2. มันทำให้การอ้างอิงที่ชัดเจนเพื่อให้ทุกคนที่ต้องอ่านรหัสของคุณในภายหลังรู้ว่าคุณหมายถึงการนำเข้าและสิ่งที่คุณไม่ได้ตั้งใจที่จะนำเข้า
  3. มันสามารถทำให้การคอมไพล์เร็วขึ้นเพราะคอมไพเลอร์ไม่จำเป็นต้องค้นหาแพคเกจทั้งหมดเพื่อระบุการพึ่งพาแม้ว่ามันจะไม่ใช่เรื่องใหญ่สำหรับคอมไพเลอร์สมัยใหม่
  4. แง่มุมที่ไม่สะดวกของการนำเข้าอย่างชัดเจนถูกย่อให้เล็กลงด้วย IDE ที่ทันสมัย IDEs ส่วนใหญ่อนุญาตให้คุณยุบส่วนการนำเข้าดังนั้นจึงไม่ใช่วิธีการเติมข้อมูลการนำเข้าโดยอัตโนมัติเมื่อจำเป็นและระบุการนำเข้าที่ไม่ได้ใช้โดยอัตโนมัติเพื่อช่วยล้างข้อมูลเหล่านั้น

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


ฉันชอบคะแนนส่วนใหญ่ของคุณ แต่เป็นข้อที่ 4 โดยเฉพาะที่ทำให้ฉันต้องตอบคำถามของคุณ IDEs ที่ทันสมัยลบข้อโต้แย้งส่วนใหญ่ออกจากการใช้การนำเข้าที่ชัดเจน ...
Sheldon R.

อาจเป็นส่วนหนึ่งของปัญหาที่นี่คือวิธีที่ไลบรารี java มาตรฐานถูกจัดวางด้วยคลาสจำนวนมากภายในแพ็กเกจเดียวกัน ตรงข้ามกับการใช้ 'หลักการความรับผิดชอบต่อเดี่ยว' มากขึ้นกับแพ็คเกจ
LegendLength

11

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


9

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

ผลกระทบด้านข้างของ * -import คือผู้พัฒนาจะคัดลอกและวางบรรทัดการนำเข้าทั่วไปแทนที่จะคิดว่าพวกเขาต้องการอะไร


11
ต้องมีสายการนำเข้าจำนวนมากหรือระบบการพัฒนาที่น่าสมเพชจริงๆเพื่อให้เป็นจริง ฉันใช้ import- * ฉันสามารถรวบรวมcodebase ทั้งหมดของคลาส 2107 ได้ภายใน 2 นาที
Lawrence Dol

6

ในหนังสือ DDD

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

และถ้ามันตัดเนมสเปซในพื้นที่ไม่ใช่ความผิดของคุณ - ตำหนิขนาดของแพ็คเกจ


3
  • ไม่มีผลกระทบต่อรันไทม์เนื่องจากคอมไพเลอร์แทนที่ * ด้วยชื่อคลาสที่เป็นรูปธรรมโดยอัตโนมัติ ถ้าคุณแยกไฟล์ .class import ...*คุณจะไม่เคยเห็น

  • C # มักจะใช้ * (โดยปริยาย) ในขณะที่คุณสามารถusingจัดแพคเกจชื่อ คุณไม่สามารถระบุชื่อคลาสได้เลย Java แนะนำคุณสมบัติหลังจาก c # (Java นั้นค่อนข้างยุ่งยากในหลาย ๆ ด้าน แต่อยู่นอกเหนือจากหัวข้อนี้)

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

  • กรณีที่ระบุไว้โดยการตอบรับที่ยอมรับไม่ถูกต้อง หากไม่มี * คุณยังคงได้รับปัญหาเดียวกัน คุณต้องระบุชื่อ pakcage ในรหัสของคุณไม่ว่าคุณจะใช้ * หรือไม่ก็ตาม


1
ใน IntelliJ ไม่ใช่คุณสมบัติที่จำเป็นและสามารถปิดได้
Bastien7

3

สำหรับบันทึก: เมื่อคุณเพิ่มการนำเข้าคุณจะระบุการอ้างอิงของคุณด้วย

คุณสามารถดูได้อย่างรวดเร็วว่าการพึ่งพาของไฟล์คืออะไร (ไม่รวมคลาสของเนมสเปซเดียวกัน)


ตกลง. แรงจูงใจนั้นไม่ได้มีประสิทธิภาพหรือการรวบรวมมากนัก แต่ความสามารถในการอ่านรหัสของคุณ ลองจินตนาการว่าคุณกำลังอ่านโค้ดโดยไม่มี IDE - บน GitHub เช่น ทันใดนั้นค้นหาทุกการอ้างอิงไม่ได้กำหนดไว้ในไฟล์ที่คุณกำลังอ่านจะกลายเป็นน่าเบื่อน่าเบื่อ
Leo Orientis

2

สิ่งที่สำคัญที่สุดคือการนำเข้าjava.awt.*สามารถทำให้โปรแกรมของคุณเข้ากันไม่ได้กับรุ่น Java ในอนาคต:

สมมติว่าคุณมีระดับที่ชื่อ "เอบีซี" คุณกำลังใช้ JDK 8 java.util.*และคุณนำเข้า ทีนี้สมมติว่า Java 9 ออกมาแล้วและมันมีคลาสใหม่ในแพคเกจjava.utilที่เกิดขึ้นโดยบังเอิญเช่นกันที่เรียกว่า "ABC" โปรแกรมของคุณจะไม่คอมไพล์ใน Java 9 เนื่องจากคอมไพเลอร์ไม่ทราบว่าชื่อ ABC หรือไม่คุณหมายถึงคลาสของคุณเองหรือคลาสใหม่ในjava.awtที่คุณหมายถึงระดับของคุณเองหรือคนชั้นใหม่

คุณจะไม่มีปัญหานั้นเมื่อคุณนำเข้าเฉพาะคลาสเหล่านั้นอย่างชัดเจนจากjava.awtที่คุณใช้จริง

แหล่งข้อมูล:

Java Imports


3
เคล็ดลับ: คุณสามารถใช้Streamเป็นตัวอย่างของคลาสใหม่ที่เพิ่มเข้ามาใน Java ใน java.util ใน Java 8 ...
Clint Eastwood

2

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


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