Lập trình Java trung cấp
Tóm tắt: Ngôn ngữ Java™ cung cấp hầu hết những gì mà các lập trình viên
chuyên nghiệp mong đợi đối với một ngôn ngữ lập trình và thậm chí là đối với
một ngôn ngữ hướng-đối tượng. Thế nhưng, ngoài những điều căn bản, ngôn ngữ
Java còn cung cấp một số công cụ có ích để tạo ra các chương trình tinh vi hơn.
Hướng dẫn này sẽ giới thiệu cho bạn một số trong các đặc tính nâng cao hơn này
của ngôn ngữ Java thường được thấy trong các dự án phát triển công nghệ Java
điển hình.
Trước khi bạn bắt đầu
Về hướng dẫn này
Hướng dẫn này giới thiệu cho bạn về các khả năng của ngôn ngữ Java tinh tế hơn
những khả năng đã trình bày trong hướng dẫn "Giới thiệu về lập trình Java" (xem
Tài nguyênđể tìm liên kết đến hướng dẫn này và các tài liệu khác được tham
chiếu trong đó). Để học được nhiều nhất từ hướng dẫn này, bạn nên tìmhiểu xong
hướng dẫn nhập môn đó hoặc làm quen với các khái niệm được trình bày trong nó.
Ngôn ngữ Java cung cấp một bộ công cụ khổng lồ có thể giúp cho một lập trình
viên hoàn thành hầu hết mọi nhiệm vụ. Trong hướng dẫn này, chúng tôi sẽ trình
bày một số trong các công cụ cao cấp hơn thường được dùng trong các dự án phát
triển Java, bao gồm như sau:
Thừa kế và trừu tượng hóa.
Các giao diện.
Các lớp lồng trong.
Các biểu thức chính quy.
Các sưu tập.
Ngày tháng.
Vào/Ra (I/O)
ác luồng ký tự. Reader flavors read bytes from a byte stream and convert them to characters. The Writer chuyển đổi các ký tự thành các byte để đặt chúng vào các luồng byte. BufferedReader and BufferedWriter Là bộ đệm dữ liệu trong khi đọc hoặc viết một luồng khác, cho phép các hoạt động đọc và ghi có hiệu quả hơn. Bạn gói một luồng khác trong một luồng có bộ đệm. Các luồng là một chủ đề lớn và chúng ta không thể trình bày toàn bộ chúng ở đây. Thay vào đó, chúng ta sẽ tập trung vào các luồng được khuyến cáo dùng để đọc và viết các tệp tin. Trong hầu hết trường hợp, đây sẽ là các luồng ký tự, nhưng chúng tôi sẽ sử dụng cả các luồng ký tự và các luồng byte để minh họa các khả năng này. Đọc và viết các tệp tin Có một số cách để đọc ra từ và viết vào một File. Người ta có thể cho rằng cách tiếp cận đơn giản nhất diễn ra như sau: Tạo một FileOutputStream trên File để viết vào nó. Tạo một FileInputStream trên File để đọc từ nó. Gọi read() để đọc từ File và write() để viết vào File. Đóng các luồng, dọn dẹp sạch sẽ nếu cần thiết. Các mã có thể trông giống như sau: try { File source = new File("input.txt"); File sink = new File("output.txt"); FileInputStream in = new FileInputStream(source); FileOutputStream out = new FileOutputStream(sink); int c; while ((c = in.read()) != -1) out.write(c); in.close(); out.close(); } catch (Exception e) { e.printStackTrace(); } Ở đây chúng ta tạo ra hai đối tượng File: một FileInputStream để đọc từ tệp tin nguồn và một FileOutputStream để viết tới File kết quả. (Lưu ý: Ví dụ này đã được điều chỉnh từ ví dụ CopyBytes.java trong Java.sun.com; xem Tài nguyên). Chúng ta sau đó đọc vào từng byte của dữ liệu đầu vào và ghi nó vào kết quả đầu ra. Sau khi đã xong, chúng ta đóng các luồng. Có lẽ là khôn ngoan khi đặt một lời gọi close() vào trong khối cuỗi cùng (finally). Tuy nhiên, trình biên dịch của ngôn ngữ Java sẽ còn yêu cầu bạn phải nắm bắt nhiều trường hợp ngoại lệ khác có thể xảy ra, điều này có nghĩa là cần một mệnh đề catch khác nữa nằm trong khối finally của bạn. Có chắc chắn đáng làm không? Có thể. Vậy là bây giờ chúng ta có một cách tiếp cận cơ bản để đọc và viết. Nhưng sự lựa chọn khôn ngoan hơn, và về một vài khía cạnh, sự lựa chọn dễ dàng hơn, là sử dụng một số luồng khác mà chúng ta sẽ thảo luận trong phần tiếp theo. Các luồng có bộ đệm Có một số cách để đọc ra và ghi vào một File, nhưng cách tiếp cận điển hình và thuận tiện nhất diễn ra như sau: Tạo một FileWriter trên File. Gói FileWriter trong một BufferedWriter. Gọi write() trên BufferedWriter mỗi khi cần thiết để viết các nội dung của File, thường ở cuối mỗi dòng cần viết ký tự kết thúc dòng (đó là, \n). Gọi flush() trên BufferedWriter để làm rỗng nó. Đóng BufferedWriter, dọn dẹp sạch nếu cần thiết. Các mã có thể trông giống như sau: try { FileWriter writer = new FileWriter(aFile); BufferedWriter buffered = new BufferedWriter(writer); buffered.write("A line of text.\n"); buffered.flush(); } catch (IOException e1) { e1.printStackTrace(); } Ở đây, chúng ta tạo ra một FileWriter trên aFile, sau đó chúng ta gói nó trong một BufferedWriter. Thao tác viết có bộ đệm hiệu quả hơn là đơn giản viết mỗi lần một byte. Khi chúng ta đã thực hiện viết từng dòng (mà chúng ta tự kết thúc bằng \n), chúng ta gọi flush() trên BufferedWriter. Nếu chúng ta không làm như vậy, chúng ta sẽ không nhìn thấy bất kỳ dữ liệu nào trong tệp tin đích, bất chấp mọi công sức cố gắng viết tệp tin này. Khi chúng ta có dữ liệu trong tệp tin, chúng ta có thể đọc nó bằng các mã tương tự đơn giản: String line = null; StringBuffer lines = new StringBuffer(); try { FileReader reader = new FileReader(aFile); BufferedReader bufferedReader = new BufferedReader(reader); while ( (line = bufferedReader.readLine()) != null) { lines.append(line); lines.append("\n"); } } catch (IOException e1) { e1.printStackTrace(); } System.out.println(lines.toString()); Chúng ta tạo ra một FileReader, sau đó gói nó trong một BufferedReader. Điều đó cho phép chúng ta sử dụng phương thức thuận tiện readLine(). Chúng ta đọc từng dòng cho đến khi không có gì còn lại, viết thêm mỗi dòng vào cuối StringBuffer. của chúng ta. Khi đọc từ một tệp tin, một IOException có thể xảy ra, do đó chúng ta bao quanh tất cả logic đọc tệp tin của chúng ta bằng một khối try/catch. Tóm tắt Chúng tôi đã trình bày một phần quan trọng của ngôn ngữ Java trong hướng dẫn "Giới thiệu về lập trình Java" (xem Tài nguyên) và hướng dẫn này, nhưng ngôn ngữ Java là rất lớn nên chỉ một hướng dẫn nguyên khối (hoặc thậm chí một số hướng dẫn nhỏ hơn) không thể bao gồm tất cả mọi vấn đề. Dưới đây nhặt ra một số lĩnh vực mà chúng tôi còn chưa nêu ra: Chủ đề Mô tả ngắn gọn Threads Có một chương trình chỉ thực hiện một việc tại một thời điểm có thể là có ích, nhưng hầu hết các chương trình ngôn ngữ Java tinh vi có nhiều luồng (threads) thực thi chạy cùng một lúc. Ví dụ, các tác vụ in ấn hoặc tìm kiếm có thể chạy ở mặt sau. Lớp Thread và các lớp có liên quan trong java.lang có thể cung cấp cho bạn khả năng phân luồng mạnh mẽ và linh hoạt trong chương trình của bạn. developerWorks có các trang Web với nhiều tài nguyên tốt về phân luồng trong mã Java của bạn, nhưng một điểm bắt đầu thích hợp là các hướng dẫn "Giới thiệu về các luồng Java" và "Tương tranh trong JDK 5.0" và loạt các bài viết này của Brian Goetz. Reflection Một trong những khía cạnh mạnh của ngôn ngữ Java (và thường là một trong những điều ám ảnh nhất) là sự phản chiếu hay khả năng để xem thông tin về chính mã của bạn. Gói java.lang.reflect bao gồm các lớp như Class và Method cho phép tra xét cấu trúc mã của bạn. Ví dụ, bạn có thể tìm thấy một phương thức bắt đầu với get, sau đó gọi nó bằng cách gọi invoke() trên đối tượng Method -- rất mạnh. Phần 2 của loạt bài "Các động lực trong lập trình Java" của Dennis M. Sosnoski nói về việc sử dụng phản chiếu. NIO Kể từ JDK 1.4, ngôn ngữ Java đã kết hợp một số khả năng I/O tinh vi hơn, dựa trên một API hoàn toàn mới gọi là I/O mới hoặc viết tắt là NIO. Sự khác biệt chính là ở chỗ I/O của ngôn ngữ Java truyền thống là dựa trên các luồng (như chúng ta đã thảo luận ở trên), trong khi NIO dựa trên một khái niệm gọi là khối I/O, các kênh và các bộ đệm. Khối I/O này có xu hướng có hiệu quả hơn việc gửi từng byte đơn lẻ thông qua một luồng. Mặt hạn chế là NIO là khái niệm khó. "Khởi đầu với I/O mới (NIO)" của Greg Travis là một hướng dẫn tuyệt vời về chủ đề này. Sockets Các chương trình ngôn ngữ Java của bạn có thể giao tiếp với hầu như bất kỳ chương trình nào trên một thiết bị có khả năng IP. Tất cả những gì bạn cần làm là mở một kết nối ổ cắm (socket) với một địa chỉ IP và một cổng trên thiết bị đó. API các ổ cắm (Sockets API) của ngôn ngữ Java hỗ trợ việc này. Xem hướng dẫn "101 các ổ cắm của Java" của Roy Miller và Adam Williams để được giới thiệu về API các ổ cắm. Hướng dẫn "Sử dụng JSSE cho giao tiếp ổ cắm an toàn" của Greg Travis cho bạn thấy làm thế nào để thực hiện bảo mật giao tiếp ổ cắm của bạn. Swing Ngôn ngữ Java bao gồm các hỗ trợ rộng lớn cho việc phát triển GUI dưới dạng Swing. Bộ Swing của các API bao gồm các lớp cho các vật dụng và các phần tử khác để tạo ra các giao diện người dùng có đầy đủ đặc tính. Có một số tài nguyên quan trọng trên developerWorks liên quan đến Swing, nhưng một điểm thích hợp để bắt đầu là bài viết giới thiệu "Giao diện người dùng của Java 2" của Matt Chapman. Chuyên mục Magic với Merlin của John Zukowski tập trung vào những thay đổi và cập nhật Swing gần đây. John cũng chủ trì trang web Diễn đàn thảo luận lập trình Java phía khách, vì vậy bạn có thể nhận được sự hỗ trợ cho việc lập trình Swing ở đó. Hướng dẫn "Di chuyển ứng dụng Swing của bạn đến SWT" thảo luận cách làm thế nào để di chuyển từ Swing đến SWT của IBM, một giải pháp thay thế gọn nhẹ nhưng vẫn rất mạnh mẽ. JNI Khi chương trình Java của bạn cần phải giao tiếp với một chương trình khác, ví dụ viết bằng ngôn ngữ C, Java cho bạn một cách để làm điều đó, đó là: Giao diện bản địa Java (JNI). API này cho phép bạn chuyển đổi các lời gọi phương thức của Java thành các lời gọi đến các hàm C (để tương tác với các hệ điều hành và tương tự). Hướng dẫn "Lập trình Java với JNI" của developerWorks thảo luận về các cơ cấu của JNI với mã Java, C và C++. RMI API về viện dẫn phương thức từ xa của ngôn ngữ Java (RMI - Remote Method Invocation) cho phép một chương trình bằng ngôn ngữ Java, hoặc trong một tiến trình hoặc trên một máy tính, truy cập vào chương trình ngôn ngữ Java khác đang chạy trong một tiến trình khác và/hoặc trên máy tinh khác. Nói cách khác, RMI hỗ trợ các cuộc gọi phương thức phân tán giữa các chương trình đang chạy trong các máy ảo Java khác nhau. Hướng dẫn "Các đối tượng phân tán của Java: Sử dụng RMI và CORBA" của Brad Rubin cung cấp một sự mở đầu vững chắc về RMI và thảo luận về RMI và CORBA cùng với nhau. Bạn cũng nên xem bài viết này của Edward Harned để tìm hiểu lý do tại sao RMI không phải là một máy chủ ứng dụng làm sẵn. Security Ngôn ngữ Java bao gồm các API bảo mật tinh vi để hỗ trợ xác thực và cấp phép. Làm thế nào bạn có thể chắc chắn rằng những người nào đó sử dụng chương trình của bạn được phép thực hiện ? Làm thế nào bạn có thể bảo vệ các thông tin khỏi những con mắt tò mò? Các API bảo mật có thể trợ giúp. Trên developerWorks cung cấp nhiều nội dung có liên quan đến bảo mật Java. Dưới đây chỉ là một vài ví dụ: Trang web Diễn đàn thảo luận bảo mật Java được John Peck, một lập trinh viên và chuyên gia bảo mật Java kỳ cựu, chủ trì; "Bên trong cơ chế cấp phép Java" của Abhijit Belapurkar; và "Bảo mật Java, Phần 1: Những điều căn bản về mật mã hóa" và "Bảo mật Java , Phần 2: Xác thực và cấp phép" cả hai đều của Brad Rubin.
File đính kèm:
- Lập trình Java trung cấp.pdf