2010-06-14 22 views
7

Tôi đã nhìn vào code của một ai đó và thấy rằng ông nhiều lần tuyên bốOn System.out, làm rõ cần

PrintStream out = System.out; 

và sau đó gọi

out.println("blah"); 

Tôi thực sự nghĩ rằng đây là loại gọn gàng. Đây có phải là một thực tế phổ biến? Có phải anh ta chỉ là người ưa thích?

+6

Anh ta có thể dễ dàng thêm vào một khai báo 'java static tĩnh.out.out;' ở đầu tệp. – ILMTitan

+0

@ILMTitan là giải pháp thậm chí còn gọn gàng hơn, nhưng tất nhiên sẽ chỉ hoạt động với java 5 trở lên. – Alb

+2

@Alb Java 5 đã hoàn thành giai đoạn End Of Service Life. –

Trả lời

7

Đây là một cách tiếp cận hợp lý. Ông về cơ bản là tạo ra một bí danh cho System.out. Có một số lợi thế:

  • Ít đánh máy hơn.
  • Dễ dàng thay đổi mã sau để xuất sang một PrintStream khác.
  • Có thể cải thiện hiệu suất, mặc dù nó sẽ không đáng kể.
+0

điểm 1, không nhỏ hơn sysout sẽ chèn "System.out.println()". Điểm 2, có nhưng điều đó cũng có nghĩa là bạn có thể mắc lỗi khi giả định rằng "out" có nghĩa là System.out.println bởi vì đó là cách nó được thực hiện ở mọi nơi khác trong mã. Nó cũng rõ ràng hơn, như không sử dụng tên biến ngắn. Điểm 3 - không. Biên dịch thông minh hơn bạn. KHÔNG BAO GIỜ đưa ra quyết định dựa trên những gì bạn nghĩ rằng trình biên dịch sẽ thực hiện mà không dựa vào thử nghiệm - phỏng đoán của bạn hầu như luôn sai, trình biên dịch tối ưu hóa dựa trên việc bạn không bị lừa - bằng cách viết mã rõ ràng nhất có thể. –

+0

@Bill K: Trình biên dịch thông minh, nhưng ngữ nghĩa của truy cập trường so với truy cập biến cục bộ khác nhau, vì vậy nó không thể tối ưu hóa điều này nói chung. Ai nói rằng println() không thay đổi giá trị của System.out? (Các trường cuối cùng không phải là cuối cùng như bạn nghĩ - nhìn vào System.setout().) –

+0

@Adam Crume Tôi cho rằng tôi nên nói rằng trình biên dịch + thời gian chạy là thông minh hơn bạn nghĩ. Nó có thể nhìn vào thực tế là System.out không thay đổi và trong dòng mã để ghi vào nó. Trong thực tế, nó có thể nội tuyến toàn bộ khối mã để làm đầu ra thực tế nếu nó muốn - nó có lẽ không nhưng tôi sẽ không quá ngạc nhiên nếu nó đã làm. Nếu bạn đã được bí danh "ra", nó có thể ngăn chặn tối ưu hóa thời gian chạy như vậy. Về cơ bản, tất cả những gì tôi nói là nếu bạn EVER đưa ra quyết định lập trình dựa trên những lợi thế về mặt lý thuyết thay vì những lợi thế được kiểm tra, bạn thực sự cần suy nghĩ lại. –

0

Đó là lối tắt nếu bạn đang thực hiện rất nhiều println. Tôi đã xem nó ở những nơi trước đây, mặc dù tôi có xu hướng không làm điều đó vì tôi nghĩ rằng System.out.println rõ ràng hơn vì bạn không cần tìm ra nơi out Đã được chuyển nhượng. Tôi thiết lập một mẫu nhật thực để tôi có thể tự động hoàn thành println đến System.out.println và nó khá nhanh.

+0

Eclipse có sẵn một mẫu "sysout", vì vậy bạn thậm chí không cần phải tạo của riêng bạn :) – benjismith

+0

Đúng, nhưng tôi viết rất nhiều mã groovy và cách này tôi có thể sử dụng println trong cả hai ngôn ngữ. –

0

Không. Chưa bao giờ thấy điều đó trước đây.

Tôi đồng ý. Nó không quá tồi tàn ...

3

Để tránh gõ System.out.println đặc biệt khi thực hiện thử nghiệm nhỏ (không có một IDE) Tôi sử dụng import static java.lang.System.out thay

Nhưng điều đó có thể làm cho ý nghĩa nếu bạn muốn thay thế giá trị của System.out sau, có lẽ đến một wrapper để chuyển hướng vào một tệp

PrintStream out = new FilePrintStream("MyLogs.log"); // // System.out 

Và tắt tiếng đầu ra tiêu chuẩn cùng một lúc. Tôi lặp lại nó có thể có ý nghĩa đối với một số trường hợp, vì tôi sẽ sử dụng khung ghi nhật ký.

BTW, nó sẽ là tốt hơn để khai báo nó như thức và tĩnh cũng:

class YourClass { 
    private final static PrintStream out = System.out; 
} 
0

Nếu bạn nhìn vào Throwable.printStackTrace trong tài liệu bạn có thể gọi nó là không có đối số, và nó chỉ cần vượt qua System.out với phiên bản có PrintStream.

Khá phổ biến để tìm các tình huống mà một số đối tượng PrintStream khác nhau có thể được truyền đi xung quanh và nó làm cho mã in đơn giản hơn nhiều.

0

Đó là một mẹo dễ thương, nhưng giống như hầu hết các thủ thuật dễ thương, có thể tốt hơn là chỉ để làm điều đó đúng.

Một khi bạn đến điểm mà bạn chắc chắn muốn đăng nhập (chắc chắn đủ để thêm một cái gì đó như thế), tại sao không chỉ nhận được Log4J hoặc một số hệ thống ghi nhật ký khác thậm chí còn linh hoạt và mạnh mẽ hơn?

Bí danh là loại dễ thương và thú vị nếu bạn ở một mình, nhưng ngay cả khi bạn là một người đánh máy thực sự chậm và nó tiết kiệm cho bạn toàn bộ 5 giây mỗi lần bạn nhập (trên System.out hoặc "sysout +<ctrl-space>" trong nhật thực/netbeans), bạn sẽ mất thời gian đó gấp mười lần lần đầu tiên một người nào đó - có thể bạn - thấy "ngoài". và không biết ngay ý nghĩa của nó. Tôi có nghĩa là, trong một chương trình chúng ta hãy nói rằng bạn đã làm những gì một số poster khác đề xuất và chuyển hướng "ra" để đi đến một tập tin thay vì STDOUT nhưng Trong một số lớp học, có lẽ "ra" vẫn đi đến System.out. hoặc có thể bạn quên rằng bạn đã chuyển hướng nó đến một tệp. Sau đó bạn đến và nói "vâng, nó nói:

out.println("WE MADE IT"); 

nhưng tôi không thấy dòng đó trong STDOUT, cái quái gì?"

Sau đó, bạn dành 4 giờ theo dõi chỉ báo xấu thay vì sửa lỗi.

+0

Nếu bạn đang sử dụng Eclipse và nhìn thấy 'ra', bạn sẽ không chỉ nhấn F3 trên nó và xem chính xác nơi nó đã đi với thời gian không lãng phí? Tôi là tất cả để loại bỏ trùng lặp và loại bỏ các cuộc gọi System.out mỗi nơi nó được sử dụng là loại bỏ trùng lặp. Các lý do được nêu rõ bởi câu trả lời http://stackoverflow.com/questions/3041482/plain-old-system-out-question/3041495#3041495 – Alb

+0

Nếu bạn không nghĩ, đó là toàn bộ vấn đề. Rõ ràng nhịp đập ngắn gọn khi bạn đang làm việc với những người khác. Khi bạn ở một mình, mã của bạn có thể vui vẻ như bạn thích, nhưng tôi thực sự mệt mỏi khi làm việc với các thủ thuật dễ thương của người khác. Thái độ này đang nhận được một số tình yêu/ghét với các quy ước đặt tên biến Java. Ý tôi là, bạn sẽ tiết kiệm được nhiều không gian bằng cách sử dụng yalvn thay vì gõ vào AnotherLongVariableName, nhưng một số người bắt đầu nhận được tầm quan trọng của sự rõ ràng hơn (ít nhất là trong thế giới Java - tôi vẫn thấy rất nhiều biến "yalvn" c tên, như thể họ đã chiếm bộ nhớ hoặc một cái gì đó) –

+0

Chắc chắn tôi đánh giá cao một tên phương pháp phong nha, nhưng trong trường hợp này, tên phương pháp ban đầu chỉ là 'ra'. Trước hết tôi không nghĩ rằng bất cứ ai nên giả định điều này sẽ được System.out mà không kiểm tra nó, thứ hai tôi không nghĩ rằng việc thêm các gói cho nó ở mọi invocation là cách tốt nhất để đối phó với nó mặc dù. Việc trích xuất tất cả các lệnh gọi System.out thành, ví dụ, phương thức 'printToConsole' hoặc 'printToLogStream' tốt hơn là để chúng trực tuyến theo ý kiến ​​của tôi vì nó loại bỏ sự trùng lặp nhưng vẫn giữ được ý định rõ ràng. – Alb

0

Cho dù đây là một ý tưởng hay là có thể gây tranh cãi và có thể phụ thuộc vào hoàn cảnh.

Về phía cộng:

  • Nó làm cho mã ứng dụng cái nhìn gọn gàng.
  • Nó có thể đơn giản hóa việc thay đổi điểm đến cho đầu ra.

Về phía trừ:

  • Nó có khả năng làm tăng chéo khớp nối; ví dụ. nếu biến số out là biến mẫu hoặc phải được chuyển thành tham số.
  • Có thể gây rắc rối nếu ứng dụng của bạn cần gọi System.setOut().
  • Nếu mã System.out chỉ gỡ lỗi, điều này sẽ khiến bạn khó nhận thấy và xóa. Thật vậy, nó có thể vô hiệu hóa PMD (vv) kiểm tra chất lượng mã mà báo cáo loại điều này.

Cần lưu ý rằng có nhiều cách khác để thực hiện việc này; ví dụ. thay thế System.out.println(String) bằng phương pháp tiện ích printLine(String) đạt được hiệu ứng tương tự mà không cần ghép nối chéo.

0

kể từ System.out là biến số final, những gì anh ấy làm sẽ được xác định để tham chiếu trực tiếp System.out.

trừ khi ai đó gọi là System.setOut() đã gán lại System.out.

chờ đợi, cái gì?

1

Nó có thể là do nói chung nó không được khuyến khích để nghiên cứu và sử dụng các đối tượng là thành viên của các đối tượng khác. Nó được xem như ai đó với túi của bạn để lấy tiền của bạn ra khỏi ví của bạn thay vì yêu cầu bạn cho anh ta mượn một số tiền.

Có thể có một lợi thế nhỏ để điều này có thể thay đổi luồng đầu ra nếu cần thiết cho tệp, ổ cắm hoặc bất kỳ thứ gì.Vì vậy, ông sẽ có thể thay thế:

PrintStream out = System.out; 

với

PrintStream out = new PrintStream(new FileOutputStream(filename)); 

Tuy nhiên, nếu ông được lặp đi lặp lại tuyên bố nó hơn và hơn nữa anh đang thực sự mất lợi thế trên, bởi vì toàn bộ điểm sẽ có nó ở đâu đó tập trung và quyết định nơi để sản xuất các bản ghi ở một nơi.

Lưu ý rằng đây là cách rất thô lỗ và thực hành tiêu chuẩn thực tế là sử dụng ghi nhật ký. Java có gói java.util.logging riêng của nó ra khỏi hộp, log4j là một giải pháp thay thế rất mạnh (và rất phổ biến) và có những thứ khác.

Các vấn đề liên quan