Bất kỳ lý do nào để làm sạch các nhập không sử dụng trong Java, ngoài việc giảm bớt sự lộn xộn?


99

Có lý do chính đáng nào để tránh các câu lệnh nhập không sử dụng trong Java không? Theo tôi hiểu, chúng ở đó cho trình biên dịch, vì vậy rất nhiều lần nhập không sử dụng sẽ không có bất kỳ tác động nào đến mã đã biên dịch. Nó chỉ để giảm bớt sự lộn xộn và tránh xung đột đặt tên xuống dòng?

(Tôi hỏi vì Eclipse đưa ra cảnh báo về các nhập không sử dụng, điều này khá khó chịu khi tôi đang phát triển mã vì tôi không muốn xóa các nhập cho đến khi tôi chắc chắn rằng mình đã thiết kế xong lớp.)

Câu trả lời:


86

Tôi không nghĩ rằng các vấn đề về hiệu suất hoặc điều gì đó tương tự có thể xảy ra nếu bạn không xóa các mục nhập.

Nhưng có thể xảy ra xung đột đặt tên, trong một số trường hợp hiếm hoi như nhập giao diện danh sách.

Trong Eclipse, bạn luôn có thể sử dụng một phím tắt (phụ thuộc vào OS - Win: Ctrl + SHIFT + Ovà Mac COMMAND + SHIFT + O:) để sắp xếp các lần nhập. Sau đó, Eclipse dọn dẹp phần nhập sẽ loại bỏ tất cả các lần nhập cũ, v.v. Nếu bạn đang cần một thứ đã nhập lại, Eclipse sẽ tự động thêm chúng khi bạn đang hoàn thành câu lệnh với Ctrl + SPACE. Vì vậy, không cần thiết phải giữ mã không sử dụng trong lớp của bạn.

Như mọi khi, mã không được sử dụng sẽ khiến bạn và những người khác mất tập trung khi đọc mã và để lại thứ gì đó trong mã đang hoạt động của bạn vì có thể tôi cần nó sau này hầu hết được coi là hành động xấu.


22
Nó thực sự là Ctrl + Shift + O trên windows.
Matt Ball

1
Ctrl + Shift + O trên linux tốt. Có lẽ trên BSD cũng vậy.
WhyNotHugo

2
Một cách khác để thực hiện hành động nhập sắp xếp là bằng cách nhấp vào ctrl+3(ít nhất là trên windwos) và sau đó nhập nhập. Rõ ràng là chậm hơn sau đó ctrl + shift + O nhưng đó là một cách để nhanh chóng tìm thấy nó (và nhiều thao tác khác mà bạn có thể nhớ hoặc chỉ đang cố gắng tìm) ngay cả khi bạn không nhớ phím tắt cụ thể cho việc này.
epeleg

53

Một là nếu bạn xóa lớp được tham chiếu bởi nhập từ classpath, bạn sẽ không gặp lỗi trình biên dịch ngớ ngẩn không phục vụ mục đích. Và bạn sẽ không nhận được kết quả dương tính giả khi thực hiện tìm kiếm "ở đâu đã sử dụng".

Một cách khác (nhưng điều này sẽ rất cụ thể về bản chất) sẽ là nếu lần nhập chưa sử dụng có xung đột đặt tên với một lần nhập khác, khiến bạn không cần thiết phải sử dụng các tên đủ điều kiện.

Phụ lục: Hôm nay máy chủ xây dựng bắt đầu biên dịch không thành công (thậm chí không chạy thử nghiệm) với lỗi hết bộ nhớ. Nó hoạt động tốt mãi mãi và các đăng ký không có bất kỳ thay đổi nào đối với quá trình xây dựng hoặc các bổ sung quan trọng có thể giải thích điều này. Sau khi cố gắng tăng cài đặt bộ nhớ (điều này đang chạy JVM 64 bit trên CentOS 64 bit!) Lên một thứ gì đó vượt xa nơi mà khách hàng có thể biên dịch, tôi đã kiểm tra từng bước kiểm tra một.

Đã có một lần nhập không đúng mà một nhà phát triển đã sử dụng và bỏ qua (họ đã sử dụng lớp, tự động nhập lớp đó và sau đó nhận ra đó là một sai lầm). Quá trình nhập không sử dụng đó đã kéo toàn bộ một tầng ứng dụng riêng biệt, trong khi IDE không được định cấu hình để tách chúng ra, thì quá trình xây dựng vẫn diễn ra. Một lần nhập duy nhất đó kéo theo rất nhiều lớp mà trình biên dịch đã cố gắng biên dịch mà không có các thư viện phụ thuộc có liên quan trong classpath, điều này gây ra rất nhiều vấn đề gây ra lỗi hết bộ nhớ. Phải mất một giờ để giải quyết vấn đề này do một lần nhập chưa sử dụng.


4
@Yishai, nếu bạn sử dụng Eclipse, hãy xem hành động Lưu, có thể chuẩn hóa mã nguồn mỗi khi bạn lưu.
Thorbjørn Ravn Andersen

2
@EJP, mặc dù chúng không ảnh hưởng đến bytecode kết quả, trình biên dịch cần giải quyết chúng để hiểu được bytecode mà nó cần tạo.
Yishai

3
@EJP, toàn bộ phụ lục nói về thời gian biên dịch ("máy chủ xây dựng bắt đầu biên dịch không thành công").
Yishai

1
Tôi vẫn không hiểu làm thế nào mà chỉ nhập khẩu lại có thể gây ra tất cả những điều này?
Thorbjørn Ravn Andersen,

1
@Yishai Xin lỗi nhưng tôi không tin. Bạn đã chẩn đoán sai điều này. Việc nhập sẽ không có tác dụng như vậy, trừ khi lớp thực sự được sử dụng. Tất cả những gì câu lệnh nhập làm là cho trình biên dịch biết gói đó đang ở trong gói nào. Trình biên dịch chỉ cố gắng biên dịch ngầm khi nó cần thông tin kiểu về lớp đó.
Marquis of Lorne

9

Theo quan điểm thuần túy, bất kỳ sự phụ thuộc nào đều là "hạn chế" đối với sản phẩm và do đó có thể gây ra các vấn đề về bảo trì sau này.

Ví dụ: giả sử rằng chương trình của bạn sử dụng lớp com.XYZObjectPool, và sau này bạn quyết định không sử dụng nó nhưng không bao giờ xóa nhập. Nếu ai đó bây giờ muốn khởi tạo org.WVYObjectPool và chỉ tham chiếu đến ObjectPool, họ sẽ không nhận được bất kỳ cảnh báo nào về điều đó cho đến khi ở đâu đó có sự cố truyền hoặc sự cố gọi.

Nhân tiện, đây không phải là một kịch bản phi thực tế. Mỗi khi bạn có Eclipse hỏi bạn muốn nhập phiên bản X cụ thể nào và bạn đã chọn một trong số nhiều gói, đó là một tình huống mà nếu bạn đã nhập ở đó, bạn có thể đã chọn sai mà không biết về nó.

Dù bằng cách nào, bạn có thể yêu cầu Eclipse dọn dẹp chúng cho bạn


3

Cảnh báo? Yêu cầu Eclipse tự động dọn dẹp chúng cho bạn. Đó là những gì IntelliJ làm. Nếu nó đủ thông minh để cảnh báo bạn, nó sẽ đủ thông minh để dọn dẹp chúng. Tôi khuyên bạn nên tìm kiếm một cài đặt Eclipse để yêu cầu nó ngừng cằn nhằn như vậy và làm điều gì đó.


4
Đó là Lưu hành động. Cá nhân tôi thích rằng Eclipse chỉ thay đổi mã của bạn khi bạn đã yêu cầu rõ ràng.
Thorbjørn Ravn Andersen

1
@ Thorbjørn: Đồng ý, đặc biệt nếu đó là lớp tôi đã ngừng sử dụng một chút nhưng tôi mong đợi sẽ sớm bổ sung trở lại.
Donal Fellows

2
@Donal, tốt, đó là những gì Ctrl-Space dành cho.
Thorbjørn Ravn Andersen

3

Điều này liên quan đến sự rõ ràng của chương trình hữu ích cho việc bảo trì.

Nếu bạn phải duy trì một chương trình, bạn sẽ thấy hữu ích như thế nào khi nhập một lớp duy nhất trên mỗi dòng.

Hãy nghĩ về tình huống sau:

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
     }
 }

Khi bạn đang sửa lỗi hoặc duy trì đoạn mã (hoặc chỉ đọc nó), rất hữu ích cho người đọc để biết gói mà các lớp được sử dụng thuộc về gói nào. Sử dụng nhập ký tự đại diện như được hiển thị ở trên không giúp ích cho mục đích đó.

Ngay cả với IDE, bạn không muốn di chuột hoặc chuyển đến khai báo và quay lại, sẽ dễ dàng hơn nếu bạn hiểu về mặt chức năng mà mã hiện tại phụ thuộc vào các gói và lớp nào.

Nếu điều này là cho một dự án cá nhân hoặc một cái gì đó nhỏ thì nó thực sự không quan trọng, nhưng đối với một cái gì đó lớn hơn mà các nhà phát triển khác phải sử dụng (và duy trì qua nhiều năm) thì điều này là PHẢI CÓ.

Hoàn toàn không có sự khác biệt về hiệu suất với bất kỳ.


3

FYI, Điều này làm tôi ngạc nhiên, vì tôi không nghĩ rằng tổ chức nhập khẩu thực sự loại bỏ các nhập khẩu không sử dụng, tôi nghĩ nó chỉ sắp xếp chúng.

Việc tự động xóa các phần nhập trong quá trình lưu khiến tôi hơi buồn khi ví dụ: trong quá trình phát triển hoặc thử nghiệm, bạn gặp sự cố và nhận xét một số mã, khi bạn lưu nó, các phần nhập được sử dụng bởi phần đã nhận xét của mã sẽ bị xóa. Đôi khi đây không phải là vấn đề vì bạn có thể hoàn tác ( Ctrl+ Z) các thay đổi, nhưng những lần khác thì không đơn giản như vậy vì bạn có thể đã thực hiện các thay đổi khác. Tôi cũng gặp sự cố khi tôi bỏ ghi chú mã (trước đó tôi đã nhận xét ra sau đó lưu, do đó xóa các lần nhập cho mã đó), nó tự động cố gắng đoán các lần nhập cần thiết và chọn sai (ví dụ: tôi nghĩ rằng tôi có một StringUtilslớp đang được sử dụng và nó đã chọn một lớp khác có cùng tên từ thư viện sai).

Tôi thích tổ chức nhập theo cách thủ công hơn là để nó như một hành động lưu.


2

Đối với nhật thực, tôi sử dụng điều này: cửa sổ -> tùy chọn -> java -> trình chỉnh sửa -> lưu hành động -> chọn hộp kiểm để tổ chức nhập (có rất nhiều thứ hữu ích khác ở đó, như định dạng, tạo trường cuối cùng, v.v. .). Vì vậy, khi tôi lưu tệp, nhật thực sẽ xóa các nhập unessacry cho tôi. Theo tôi, nếu bạn không cần thứ gì đó thì hãy loại bỏ nó (hoặc để nó bị xóa bởi nhật thực).


2

Bạn có thể nhận xét các câu lệnh nhập không sử dụng ra ngoài và các cảnh báo sẽ không làm phiền bạn nhưng bạn có thể xem những gì bạn có.


2
@DimaSan Thực ra thì có: câu hỏi nói rằng tôi không muốn xóa các phần nhập cho đến khi tôi khá chắc rằng mình đã thiết kế xong lớp.
The Vee

1

Không có bất kỳ tác động nào về hiệu suất, mặc dù để dễ đọc, bạn có thể làm cho nó sạch sẽ. Loại bỏ các nhập không sử dụng khá đơn giản trong cả Eclipse và IntelliJ IDEA.

Nhật thực

Windows / Linux -    Ctrl+ Shift+O

Mac -                        Cmd+ Shift+O

IntelliJ IDEA hoặc Android Studio

Windows / Linux -    Ctrl+ Alt+O

Mac -                        Cmd+ Alt+O


0

Tôi đã đọc ở đâu đó, cách đây vài năm, rằng mọi lớp được nhập sẽ được tải trong thời gian chạy với lớp nhập. Vì vậy, loại bỏ các gói không sử dụng, đặc biệt là toàn bộ, sẽ giảm chi phí bộ nhớ. Mặc dù tôi cho rằng các phiên bản java hiện đại đối phó với điều đó, vì vậy có lẽ đó không phải là lý do nữa.

Và nhân tiện, với eclipse, bạn có thể sử dụng Ctrl+ Shift+ Ođể sắp xếp quá trình nhập, nhưng bạn cũng có thể định cấu hình "trình dọn dẹp" xử lý những thứ như vậy (và nhiều thứ khác) mỗi khi bạn lưu tệp java.


hmm .. tôi sẽ ngạc nhiên nếu đó là hành vi .. tôi biết các lớp không được khởi tạo (tức là gọi trình khởi tạo tĩnh) cho đến khi sử dụng lần đầu hoặc cho đến khi chúng được yêu cầu cụ thể bởi trình tải tùy chỉnh. nhưng nếu bằng cách "tải" bạn chỉ có nghĩa là "đọc vào bộ nhớ nhưng không được xử lý" thì có thể, mặc dù tôi nghi ngờ điều đó.
Kip

thực ra, khi suy nghĩ sâu hơn, nó sẽ khá dễ dàng để kiểm tra. biên dịch mã với các mục nhập chưa sử dụng, sau đó sử dụng công cụ "dịch ngược" và xem liệu các mục nhập chưa sử dụng có còn ở đó hay không. nếu không thì hoặc chúng đang bị trình biên dịch loại bỏ, hoặc chúng chỉ ở đó để thuận tiện cho lập trình viên.
Kip

4
Bạn đã đọc nó ở đâu vậy? Nó hoàn toàn và hoàn toàn không chính xác, và luôn luôn như vậy. Mọi lớp được tham chiếu bởi mã sẽ được tải, không bao gồm nhập.
Marquis of Lorne,

0

Đối với tôi, một lần nhập lớp không sử dụng trong lớp bộ điều khiển đã tạo ra sự cố biên dịch trong bản dựng Jenkins sau khi tôi xóa lớp đã nhập trong quá trình dọn dẹp mã và cam kết xóa trong git mà không kiểm tra bản dựng trong cục bộ.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.