1. Trang chủ
  2. » Giáo Dục - Đào Tạo

Giáo trình Công nghệ Java ĐH Kinh Tế Kỹ Thuật Công Nghiệp

226 6 0

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Tiêu đề Giáo trình Công nghệ Java
Trường học ĐH Kinh Tế Kỹ Thuật Công Nghiệp
Chuyên ngành Công nghệ Java
Thể loại Giáo trình
Định dạng
Số trang 226
Dung lượng 3,39 MB

Cấu trúc

  • Chương 1. TỔNG QUAN VỀ LẬP TRÌNH JAVA (10)
    • 1.1. Lịch sử ra đời và phát triển của Java (10)
    • 1.2. Đặc trưng ngôn ngữ Java (10)
    • 1.3. Các ứng dụng của Java (12)
    • 1.4. Dịch và thực thi một chương trình viết bằng Java (13)
    • 1.5. Kiến trúc chương trình xây dựng trên Java (13)
      • 1.5.1. Kiến trúc chương trình Java (13)
      • 1.5.2. Chương trình Java đầu tiên (16)
  • Chương 2. CẤU TRÚC LẬP TRÌNH CƠ BẢN TRONG JAVA (20)
    • 2.1. Các kiểu dữ liệu (20)
    • 2.2. Biến (21)
    • 2.3. Toán tử (22)
    • 2.4. Strings và String Buider (23)
      • 2.4.1. Lớp String (23)
      • 2.4.2. StringBuffer và StringBuilder (27)
    • 2.5. Nhập/Xuất dữ liệu (27)
    • 2.6. Câu lệnh và các cấu trúc lệnh trong Java (31)
      • 2.6.1. Lệnh, khối lệnh trong Java (32)
      • 2.6.2. Câu lệnh if …else (32)
      • 2.6.3. Câu lệnh switch -case (33)
      • 2.6.4. Vòng lặp While (35)
      • 2.6.5. Vòng lặp do -while (35)
      • 2.6.6. Vòng lặp for (36)
      • 2.6.7. Lệnh break và continue (37)
    • 2.7. Số lớn trong java (38)
    • 2.8. Mảng (38)
      • 2.8.1. Vòng lặp “for each” (39)
      • 2.8.2. Khởi tạo mảng và mảng nặc danh (40)
      • 2.8.3. Copy mảng (41)
      • 2.8.4. Các tham số dòng lệnh (41)
      • 2.8.5. Sắp xếp mảng (42)
      • 2.8.6. Mảng nhiểu chiều (0)
  • Chương 3. ĐỐI TƯỢNG, LỚP, KẾ THỪA, GIAO DIỆN (49)
    • 3.1. Đối tượng, lớp, lớp trừu tượng (49)
      • 3.1.1. Khái niệm (49)
      • 3.1.2. Khai báo lớp (49)
      • 3.1.3. Thuộc tính của lớp (50)
      • 3.1.4. Phương thức của lớp (52)
      • 3.1.5. Chỉ định truy xuất lớp (55)
    • 3.2. Tạo đối tượng (55)
    • 3.3. Kế thừa và đa hình (57)
      • 3.3.1. Mô tả kế thừa (57)
      • 3.3.2. Kế thừa đơn (57)
      • 3.3.3. Kế thừa kép (61)
      • 3.3.4. Lớp cha, lớp con (63)
      • 3.3.5. Cách sử dụng từ khóa super (64)
      • 3.3.6. Cách nạp chồng phương thức (64)
      • 3.3.7. Đa hình (66)
    • 3.4. Lớp trừu tượng (68)
    • 3.5. Lớp Object (71)
      • 3.5.1. Phương thức equals (71)
      • 3.5.2. Phương thức toString ( ) (72)
    • 3.6. Giao diện (72)
      • 3.6.1. Mô tả giao diện (72)
      • 3.6.2. Mục đích sử dụng giao diện (73)
      • 3.6.3. So sánh giao diện và lớp trừu tượng (73)
    • 3.7. Lớp nội (74)
      • 3.7.1. Các kiểu lớp nội (75)
    • 3.8. Xử lý ngoại lệ (77)
      • 3.8.1. Giới thiệu (77)
      • 3.8.2. Mục đích của việc xử lý ngoại lệ (77)
      • 3.8.3. Lớp Exception (77)
      • 3.8.4. Xử lý ngoại lệ (77)
      • 3.8.5. Mô hình xử lý ngoại lệ (78)
      • 3.8.6. Các khối chứa nhiều Catch (79)
      • 3.8.7. Khối ‘finally’ (81)
      • 3.8.8. Các ngoại lệ được định nghĩa với lệnh ‘throw’ và ‘throws’ (83)
      • 3.8.9. Danh sách các ngoại lệ (84)
    • 3.9. Giao diện Collection (85)
      • 3.9.1. Giới thiệu (85)
      • 3.9.2. Các kiểu collection (85)
      • 3.9.3. Collection frame work (91)
    • 3.10. Thread (94)
      • 3.10.1. Thread là gì, Tạo Thread (94)
      • 3.10.2. Các trạng thái của Thread (94)
      • 3.10.3. Các phương thức của lớp Thread (95)
      • 3.10.4. Quản lý Thread (96)
      • 3.10.5. Luồng chạy ngầm (deamon) (96)
    • 3.11. Đa luồng và tương tranh (97)
      • 3.11.1. Định nghĩa đa luồng (97)
      • 3.11.2. Sử dụng phương thức isAlive() và join() (100)
      • 3.11.3. Điều kiện tương tranh và cách khắc phục (101)
      • 3.11.4. Cách sử dụng phương thức wait() và notify() (102)
      • 3.11.5. Định nghĩa deadlock và khắc phục (103)
  • CHƯƠNG 4. LẬP TRÌNH GIAO DIỆN VỚI JAVA SWING (111)
    • 4.1. Gi ớ i thi ệu Swing và mô hình MVC (111)
      • 4.1.1. L ợi ích củ a s ử d ụ ng Swing so v ớ i AWT (112)
      • 4.1.2. Mô tả container trong Swing (113)
    • 4.2. Qu ản lý Layout (113)
      • 4.2.1. BorderLayout (113)
      • 4.2.2. GridLayout (115)
      • 4.2.3. GirdBagLayout (116)
      • 4.2.4. GroupLayout (116)
    • 4.3. Text Input (116)
      • 4.3.1. TextFields (116)
      • 4.3.2. Label (117)
      • 4.3.3. Password Fields (118)
      • 4.3.4. TextAreas (118)
      • 4.3.5. Scroll Panes (119)
    • 4.4. Các thành phầ n l ự a ch ọ n (120)
      • 4.4.1. Checkboxes (120)
      • 4.4.2. Radio Button (120)
      • 4.4.3. ComboBoxes (121)
      • 4.4.4. Slider (123)
    • 4.5. Menu (124)
      • 4.5.1. Xây dự ng menu (124)
      • 4.5.2. Icons và Menu Items (124)
      • 4.5.3. Pop-Up Menu (125)
      • 4.5.4. Hi ể n th ị và ẩn các mụ c trong menu (125)
      • 4.5.5. Toolbars (125)
      • 4.5.6. Tooltips (127)
    • 4.6. Dialog Boxes (127)
      • 4.6.1. T ạ o Dialogs (127)
      • 4.6.2. Option Dialogs (128)
      • 4.6.3. Trao đổ i d ữ li ệ u (132)
      • 4.6.4. File Dialogs (132)
      • 4.6.5. Các lự a ch ọn màu (133)
  • Chương 5. LUỒNG VÀ TẬP TIN (139)
    • 5.1. Mở đầu (139)
    • 5.2. Luồng (139)
      • 5.2.1. Khái niệm luồng (139)
      • 5.2.2. Luồng byte (Byte Streams) (139)
      • 5.2.3. Luồng ký tự (Character Streams) (140)
      • 5.2.4. Những luồng được định nghĩa trước (The Predefined Streams) (141)
    • 5.3. Sử dụn g l uồng Byte (141)
      • 5.3.1. Đọc dữ liệu từ Console (142)
      • 5.3.2. Xuất dữ liệu ra Console (143)
      • 5.3.3. Đọc và ghi file dùng luồng Byte (144)
      • 5.3.4. Đọc và ghi dữ liệu nhị phân (147)
    • 5.4. File truy cập ngẫu nhiên (Random Access Files) (150)
    • 5.5. Sử dụng luồng ký tự (152)
      • 5.5.1. Nhập Console dùng luồng ký tự (153)
      • 5.5.2. Xuất Console dùng luồng ký tự (155)
      • 5.5.3. Đọc/ghi File dùng luồng ký tự (156)
    • 5.6. Lớp File (158)
  • Chương 6. ỨNG DỤNG GIAO TIẾP VỚI CƠ SỞ DỮ LIỆU (163)
    • 6.1. Giới thiệu (163)
    • 6.2. Kiến trúc JDBC, cách tạo ứng dụng JDBC (163)
    • 6.3. Các khái niệm cơ bản (164)
      • 6.3.1. JDBC Driver (164)
      • 6.3.2. JDBC URL (166)
    • 6.4. Kết nối cơ sở dữ liệu với JDBC (166)
      • 6.4.1. Đăng ký trình điều khiển (166)
      • 6.4.2. Thực hiện kết nối (167)
      • 6.4.3. Các ví dụ (168)
    • 6.5. Cách tạo truy vấn và các kiểu truy vấn (172)
    • 6.6. Mô tả Rowset, JDBCRowset và CatchedRowset (178)
  • CHƯƠNG 7. LẬP TRÌNH ỨNG DỤNG MẠNG VỚI SOCKET (183)
    • 7.1. Giới thiệu chung (183)
    • 7.2. Lập trình thao tác với địa chỉ máy trạm (183)
      • 7.2.1. Lập trình thao tác với địa chỉ IP, lớp URL Connection (183)
      • 7.2.2. Ví dụ sử dụng các phương thức lớp InetAddress (189)
    • 7.3. Lập trình ứng dụng mạng với TCP socket (190)
      • 7.3.1. Lớp Socket và lớp Server Socket (190)
      • 7.3.2. Kỹ thuật lập trình truyền thông với giao thức TCP (194)
      • 7.3.3. Một số ví dụ (197)
    • 7.4. Lập trình ứng dụng mạng với UDP Socket (200)
      • 7.4.1. Một số lớp Java hỗ trợ lập trình với UDP Socket (200)
      • 7.4.2. Kỹ thuật lập trình truyền thông với giao thức U DP (0)
    • 7.5. L ấ y d ữ li ệ u web (0)
      • 7.5.1. URL và URI (0)
      • 7.5.2. S ử d ụng URLConnection để truy xu ấ t d ữ li ệ u (0)
    • 7.6. G ử i Email (0)
      • 7.6.2. Khái niệ m Session (0)
      • 7.6.3. Cách tạ o message (0)
      • 7.6.4. Các bước để t ạo và gử i message (0)
      • 7.6.5. Các bướ c c ầ n thi ết để đọ c m ộ t message (0)

Nội dung

TỔNG QUAN VỀ LẬP TRÌNH JAVA

Lịch sử ra đời và phát triển của Java

Năm 1991, một nhóm kỹ sư từ Sun Microsystems đã quyết định phát triển một ngôn ngữ lập trình nhằm điều khiển các thiết bị điện tử như tivi và máy giặt Ban đầu, họ dự định sử dụng C và C++, nhưng nhận thấy rằng trình biên dịch C/C++ phụ thuộc vào từng loại CPU Vì vậy, nhóm kỹ sư đã bắt tay vào việc xây dựng một ngôn ngữ mới, nhanh chóng, gọn gàng và hiệu quả, độc lập với thiết bị, và ngôn ngữ "Oak" đã ra đời.

Năm 1995, ngôn ngữ Oak, tương tự như C++, đã được cải tiến bằng cách loại bỏ một số tính năng nguy hiểm và có khả năng chạy trên nhiều nền tảng phần cứng khác nhau Đồng thời, sự phát triển của World Wide Web đã khiến Sun nhận ra tiềm năng to lớn của ngôn ngữ này, dẫn đến việc đầu tư mạnh mẽ vào việc phát triển và cải tiến nó.

Ngôn ngữ lập trình Java được Sun Microsystems giới thiệu vào tháng 6 năm

Java, ra mắt vào năm 1995, đã nhanh chóng trở thành ngôn ngữ lập trình ưa chuộng của các lập trình viên chuyên nghiệp Ngôn ngữ này được phát triển dựa trên nền tảng của C và C++, đồng thời sử dụng cú pháp tương tự, giúp lập trình viên dễ dàng làm quen và ứng dụng.

C++ có đặc trưng hướng đối tượng, trong khi Java là ngôn ngữ kết hợp giữa biên dịch và thông dịch Mã nguồn Java được biên dịch thành bytecode, sau đó thực thi trên các máy khác nhau thông qua trình thông dịch Mục tiêu của Java là cho phép lập trình viên viết một lần nhưng có thể chạy trên nhiều nền tảng phần cứng khác nhau.

Ngày nay, Java được sử dụng phổ biến không chỉ cho việc phát triển ứng dụng trên máy tính để bàn và web, mà còn để tạo ra các trình điều khiển cho thiết bị di động và PDA.

Đặc trưng ngôn ngữ Java

Ngôn ngữ lập trình Java đơn giản hóa các đặc trưng phức tạp của C và C++, loại bỏ thao tác con trỏ và định nghĩa chồng toán tử, không cho phép đa kế thừa mà thay vào đó sử dụng giao diện, không sử dụng lệnh "goto" và file header (.h), đồng thời loại bỏ cấu trúc "struct" và "union".

Hướng đối tượng trong Java tương tự như C++, nhưng Java là một ngôn ngữ lập trình hoàn toàn hướng đối tượng Mọi khía cạnh trong Java đều liên quan đến các đối tượng đã được định nghĩa trước, bao gồm cả hàm chính của chương trình.

Trong Java, hàm main phải được đặt bên trong một lớp, và ngôn ngữ này không hỗ trợ tính đa kế thừa như C++ Thay vào đó, Java sử dụng khái niệm interface để hỗ trợ tính đa kế thừa.

Tính độc lập với phần cứng và hệ điều hành

Tính độc lập với phần cứng trong Java có nghĩa là một chương trình có thể chạy đúng trên tất cả các họ máy nếu nó hoạt động tốt trên một họ máy cụ thể Ngược lại, nếu một chương trình chỉ chạy đúng trên một số họ máy nhất định, thì nó được coi là phụ thuộc vào phần cứng.

Tính độc lập với hệ điều hành trong Java có nghĩa là một chương trình Java có thể chạy trên tất cả các hệ điều hành mà không gặp phải vấn đề tương thích Ngược lại, những chương trình chỉ có thể chạy trên một số hệ điều hành nhất định được gọi là phụ thuộc hệ điều hành.

Các chương trình Java có khả năng chạy trên hầu hết các hệ điều hành mà không cần thay đổi, nhờ vào khẩu hiệu 'viết một lần, chạy mọi nơi' Điều này là một ưu điểm nổi bật so với các ngôn ngữ lập trình khác.

Java là một ngôn ngữ lập trình yêu cầu chặt chẽ về kiểu dữ liệu, giúp giảm thiểu lỗi nhờ hạn chế việc ép kiểu tự động như trong C và C++ Ngôn ngữ này thực hiện kiểm tra cả trong quá trình biên dịch và thời gian thông dịch, từ đó loại bỏ nhiều loại lỗi lập trình phổ biến Java không sử dụng con trỏ và các phép toán liên quan, đồng thời kiểm tra tất cả các truy cập đến mảng và chuỗi trong quá trình thực thi để đảm bảo không có truy cập nào vượt quá giới hạn kích thước.

Trong lập trình truyền thống, lập trình viên phải tự cấp phát và giải phóng bộ nhớ, nhưng với Java, quá trình này được tự động hóa nhờ vào dịch vụ thu gom rác (garbage collection) Điều này giúp lập trình viên không còn phải lo lắng về việc quản lý bộ nhớ Bên cạnh đó, cơ chế bẫy lỗi của Java cũng đơn giản hóa việc xử lý và hồi phục sau lỗi, mang lại sự tiện lợi cho người lập trình.

Java cung cấp một môi trường quản lý an toàn cho việc thực thi chương trình thông qua nhiều cấp độ kiểm soát Ở cấp độ đầu tiên, ngôn ngữ lập trình, dữ liệu và phương thức được bảo vệ bên trong lớp và chỉ có thể truy cập thông qua các giao diện mà lớp cung cấp Cấp độ thứ hai là trình biên dịch, nơi mà an toàn của mã được kiểm tra trước khi quá trình biên dịch diễn ra.

Mức thứ ba được đảm bảo bởi trình thông dịch: Chúng kiểm tra xem bytecode có đảm bảo các qui tắc an toàn trước khi thực thi

Mức thứ tư, hay còn gọi là mức class, đóng vai trò quan trọng trong việc kiểm soát quá trình nạp các lớp vào bộ nhớ Điều này giúp giám sát và phát hiện các vi phạm giới hạn truy xuất trước khi các lớp này được nạp vào hệ thống.

Java được phát triển để hỗ trợ các ứng dụng mạng thông qua các lớp mạng trong gói Java.net Nó tích hợp các công nghệ lập trình như RMI, CORBA và JavaBean, cho phép tái sử dụng các lớp đã được xây dựng và gọi các phương thức hoặc đối tượng từ xa.

Tính năng này cho phép lập trình viên viết chương trình với nhiều đoạn mã lệnh chạy song song, mang lại khả năng chạy đa luồng dễ dàng trong Java Việc đồng bộ hóa tài nguyên dùng chung trong Java cũng trở nên đơn giản, điều này khác biệt so với một số ngôn ngữ lập trình khác như C/C++ hay Pascal.

Java được phát triển như một ngôn ngữ động, phù hợp với các môi trường mở Các chương trình Java cung cấp thông tin cho các đối tượng trong thời gian thực thi, cho phép khả năng liên kết động giữa các mã.

Các ứng dụng của Java

Ứng dụng thực thi qua dòng lệnh (Console) là loại ứng dụng nhập xuất ở chế độ văn bản, tương tự như màn hình Console của hệ điều hành MS-DOS Các ứng dụng Console thường được sử dụng để minh họa cú pháp ngôn ngữ, thuật toán và các chương trình không cần giao diện người dùng đồ họa.

Applet là chương trình Java được thiết kế để hoạt động trên Internet thông qua các trình duyệt hỗ trợ Java như Internet Explorer và Netscape Nó được nhúng trực tiếp vào trang web, và khi trang web được hiển thị trong trình duyệt, Applet sẽ được tải xuống và thực thi ngay trong trình duyệt.

Việc phát triển ứng dụng có giao diện đồ họa trực quan đã được Java hỗ trợ thông qua thư viện AWT và JFC Trong đó, JFC (Swing) nổi bật với tính năng phong phú và hỗ trợ mạnh mẽ, cho phép lập trình viên dễ dàng tạo ra giao diện trực quan cho bất kỳ ứng dụng nào, bao gồm cả ứng dụng web.

Java cung cấp hỗ trợ mạnh mẽ cho việc phát triển ứng dụng Web thông qua công nghệ J2EE (Java 2 Enterprise Edition), cho phép tạo ra các ứng dụng Web hiệu quả tương đương với công nghệ NET của Microsoft Công nghệ web hiện tại của Java bao gồm Servlet và JSP, cùng với sự hỗ trợ từ lập trình Socket, Java Bean, RMI, CORBA và EJB, giúp phát triển các ứng dụng lập trình mạng linh hoạt và mạnh mẽ.

Java cung cấp hỗ trợ mạnh mẽ cho lập trình ứng dụng mạng thông qua các lớp thư viện socket, giúp đơn giản hóa kết nối và chuyển dữ liệu Người lập trình có thể dễ dàng làm việc với nhiều giao thức như TCP/IP, UDP, HTTP, FTP và Telnet.

Các ứng dụng điển hình bao gồm chương trình chat, chuyển dữ liệu, truyền tin thông báo tin tức, trao đổi trực tuyến và gửi nhận thư điện tử Ngoài ra, ứng dụng cơ sở dữ liệu cũng đóng vai trò quan trọng trong việc quản lý và lưu trữ thông tin hiệu quả.

CSDL đóng vai trò quan trọng trong hầu hết các ứng dụng, nhưng không phải ngôn ngữ lập trình nào cũng hỗ trợ truy xuất CSDL đầy đủ Chẳng hạn, VB cung cấp nhiều cơ chế truy xuất CSDL tiện lợi như ODBC, ADO, ADO.NET và OLEDB, trong khi C/C++ lại thiếu những công cụ này.

Java hỗ trợ truy xuất cơ sở dữ liệu mở thông qua công nghệ JDBC (Java Database Connectivity), cho phép kết nối với nhiều loại cơ sở dữ liệu như Oracle, DB2, MySQL và SQL Server JDBC cung cấp khả năng truy cập dữ liệu bằng mô hình đa luồng, rất phù hợp cho các ứng dụng phân tán.

Dịch và thực thi một chương trình viết bằng Java

Việc xây dựng, dịch và thực thi một chương trình viết bằng Java có thể tóm tắt qua các bước sau:

 Viết mã nguồn: Dùng một chương trình soạn thảo nào đó (NotePad hay Jcreator chẳng hạn) để viết mã nguồn và lưu lại với tên có đuôi “ Java”

 Biên dịch ra mã máy ảo: Dùng trình biên dịch Javac để biên dịch mã nguồn

“.Java” thành mã của máy ảo (Java bytecode) có đuôi “.class” và lưu lên đĩa.

 Thông dịch và thực thi: Ứng dụng được load vào bộ nhớ, thông dịch và thực thi dùng trình thông dịch Java thông qua lệnh “Java”.

Để thực thi chương trình Java, bước đầu tiên là đưa mã Java bytecode vào bộ nhớ, hay còn gọi là bước "loading" Trong quá trình này, "Loader" sẽ lấy các tệp tin có đuôi ".class" chứa mã Java bytecode và nạp chúng vào bộ nhớ trước khi thực hiện chương trình.

Trước khi trình thông dịch chuyển đổi mã Java bytecode thành mã máy để thực thi, mã bytecode cần được kiểm tra tính hợp lệ Cuối cùng, dưới sự điều khiển của CPU và trình thông dịch, mã bytecode sẽ được chuyển đổi sang mã máy và thực hiện.

Kiến trúc chương trình xây dựng trên Java

1.5.1 Kiến trúc chương trình Java

Tập tin mã nguồn Java cơ bản có cấu trúc gồm ba phần chính: đầu tiên là khai báo tên gói với cú pháp `package packageName;`, tiếp theo là khai báo thư viện cần sử dụng thông qua `import java.awt.*;`, và cuối cùng là khai báo tên lớp với cú pháp `class className`.

/* Đây là dòng chú thích, nếu cần */ int var; // Khai báo biến public void methodName() // Khai báo tên phương thức

/* Phần thân của phương thức */

// Các lệnh thực hiện trong thân phương thức

Một tệp mã nguồn Java có thể có ba phần chính:

 Phần khai báo tên gói (khối) bằng từ khoá package

 Phần khai báo thư viện tham khảo bằng từ khoá import

 Phần khai báo nội dung lớp bằng từ khoá class.

Gói (package) là phương pháp hiệu quả để tổ chức và đóng gói các lớp trong chương trình thành một khối thống nhất Nó giúp lưu trữ các lớp tương tự hoặc thuộc cùng một module, tạo sự gọn gàng và dễ quản lý trong quá trình phát triển phần mềm.

Cú pháp khai báo tên gói trong chương trình sử dụng từ khóa "package" theo định dạng: package ; Việc đặt tên gói tương tự như cách đặt tên thư mục trên ổ đĩa, bắt đầu từ tên có phạm vi lớn đến tên có phạm vi nhỏ, và cuối cùng là tên các gói trực tiếp chứa các lớp Thứ tự đặt tên gói thường được thực hiện từ phạm vi lớn đến nhỏ.

 Tên các chức năng trong modul Ưu điểm của package:

Cho phép nhóm các lớp lại với nhau thành các đơn vị nhỏ hơn giúp việc thao tác trên các đơn vị khối trở nên gọn gàng và hiệu quả hơn so với việc thao tác trên một tập hợp lớn các lớp.

Để tránh xung đột trong việc đặt tên lớp khi số lượng lớp trong chương trình quá lớn, chúng ta nên tổ chức các lớp vào các package khác nhau Điều này giúp duy trì sự rõ ràng và dễ quản lý cho mã nguồn.

 Cho phép bảo vệ các lớp Khi chương trình lớn, việc chia nhỏ chương trình thành các package sẽ thuận lợi hơn cho việc quản lí và phát triển

 Tên gói còn được dùng để định danh lớp trong ứng dụng

Các tệp tin của các lớp trong cùng một gói ứng dụng cần được lưu trữ trong thư mục chung, với tên thư mục trùng với tên khối, theo cấu trúc khối của dự án.

Tên gói nên được viết bằng chữ thường để tránh nhầm lẫn với tên các tệp tin, vì tên gói sẽ là tên thư mục tương ứng trong ổ đĩa.

Để sử dụng các thư viện đã được định nghĩa sẵn trong chương trình, bạn cần khai báo chúng bằng cú pháp import Cú pháp khai báo thư viện được thực hiện như sau: import ;

Java chuẩn cung cấp một số thư viện như sau:

Gói java.lang cung cấp các hàm quan trọng để thao tác với các kiểu dữ liệu cơ bản, xử lý lỗi và ngoại lệ, cũng như quản lý các hoạt động nhập xuất trên các thiết bị chuẩn như bàn phím và màn hình.

 java.applet: cung cấp các hàm cho xây dựng các applet

 java.awt: cung cấp các hàm cho xây dựng các ứng dụng đồ hoạ với các thành phần giao diện đa phương tiện multimedia.

 java.io: cung cấp các hàm xử lí vào/ra trên các thiêt bị chuẩn,các thiết bị ngoại vi

 java.util: cung cấp các hàm tiện ích trong xử lí liên quan đến các kiểu dữ liệu có cấu trúc như Date, Stack, Vector

 Nếu muốn khai báo tham khảo nhiều thư viện, phải khai báo tham khảo mỗi thư viện với một từ khoá import

Khi tham khảo một số lớp trong thư viện, bạn nên chỉ rõ các lớp cụ thể thay vì sử dụng ký hiệu “*” để tham khảo toàn bộ gói Việc này giúp giảm kích thước tệp tin class sau khi biên dịch, tối ưu hóa hiệu suất và quản lý tài nguyên hiệu quả hơn.

 Nếu không tham khảo thư viện nào, không cần thiết phải khai báo các tham khảo với từ khoá import

Phần thứ ba là phần khai báo lớp và nội dung của lớp, phần này luôn bắt buộc phải có đối với một tệp mã nguồn Java:

 Khai báo tên lớp với từ khoá class

 Khái báo các thuộc tính của lớp.

 Khai báo các phương thức của lớp

1.5.2 Chương trình Java đầu tiên

1.5.2.1 Công cụ soạn thảo mã nguồn Java Để viết mã nguồn Java chúng ta có thể sử dụng trình soạn thảo NotePad hoặc một số môi trường phát triển hỗ trợ ngôn ngữ Java như: Jbuilder của hãng Borland, JDeveloper của hãng Oracle, Visual J++ của Microsoft…

Trong khuôn khổ giáo trình này để hướng dẫn sinh viên thực hànhchúng tôi dùng công cụ NetBeans IDE 7.0 được phát triển bởi Sun Microsystems.

NetBean IDE là một môi trường phát triển mạnh mẽ, cho phép lập trình viên viết, biên dịch, gỡ lỗi và triển khai chương trình, chủ yếu bằng ngôn ngữ Java nhưng cũng hỗ trợ nhiều ngôn ngữ khác Với giao diện thân thiện và hiệu quả, NetBean IDE được xem là một trong những công cụ phổ biến nhất, hoàn toàn miễn phí và không giới hạn sử dụng Nó dễ dàng cài đặt và hoạt động trên nhiều hệ điều hành như Windows, Linux, Mac OS X và Solaris Bạn có thể tải NetBean IDE tại trang web netbeans.org/downloads/.

Ví dụ Để tạo và thực thi chương trình có tên HelloWorldApp như sau:

Bước 1 Tạo Project: Chọn File/NewProject:

Tại mục Categories ta chọn Java

Tại mục Projects ta chọn Java Application rồi chọn Next.

Nhập Project Name và chọn Finish.

Hình 1 2 Vị trí lưu project

Bước 2 Soạn thảo mã nguồn tại cửa sổ bên dưới:

Hình 1.3 Màn hình soạn thảo

Chương trình sau cho phép hiển thị thông điệp: "Hello World Application!" package helloworldapp;

* @param args the command line arguments

18 public static void main(String[] args) {

// TODO code application logic here

System.out.println("Hello World Applications!");

Để thực thi chương trình, bạn có thể vào Run/Run Main Project, nhấn nút Run Main Project trên thanh công cụ, hoặc sử dụng phím tắt F6 Kết quả sẽ được hiển thị trên màn hình.

1.5.2.3 Phân tích chương trình đầu tiên.

Tập tin HelloWorldApp.Java sẽ nằm trong gói helloworldapp

Ký hiệu “/*… */ ” dùng để chú thích nhiều dòng lệnh Trình biên dịch sẽ bỏ qua các dòng chú thích này Java hỗ trợ hai loại chú thích:

 Loại chú thích trên một dòng, dùng “//” Trình biên dịch sẽ bỏ qua nội dung bắt đầu từ kí hiệu “//” cho đến hết dòng lệnh chứa nó

 Loại chú thích trên nhiều dòng có thể bắt đầu với “/*” vàkết thúc với “*/” Trình biên dịch sẽ bỏ qua nội dung nằm giữa hai kí hiệu này.

Dòng kế tiếp khai báo lớp có tên HelloWorldApp: Bắt đầu với từ khoá public, kế đến là từ khóa class, cuối cùng là tên lớp: public class HelloWorldApp {…}

Một định nghĩa lớp trong Java được bao quanh bởi hai ngoặc móc “{” và “}”, đánh dấu khối lệnh Phương thức chính, được định nghĩa là public static void main(String args[ ]), là điểm bắt đầu cho việc thực thi chương trình, và mọi ứng dụng Java đều cần có phương thức main này.

 Từ khoá public là một chỉ định truy xuất Nó cho biết thành viên của lớp có thể được truy xuất từ bất cứ đâutrong chương trình

Từ khoá static cho phép phương thức main được gọi mà không cần tạo ra một thể hiện của lớp, điều này có nghĩa là nó không phụ thuộc vào các thể hiện của lớp đã được tạo ra.

 Từ khoá void thông báo cho máy tính biết rằng phương thức sẽ không trả lại bất cứgiá trị nào khi thực thi chương trình

CẤU TRÚC LẬP TRÌNH CƠ BẢN TRONG JAVA

Các kiểu dữ liệu

Kiểu dữ liệu cơ bản

Kiểu dữ liệu Kích thước

Phạm vi biểu diễn Giá trị mặc định byte 8 bits -128 ÷127 0 short 16 bits - 32768 ÷ 32767 0 int 32 bits -2 31 ÷ 2 31 -1 0 long 64 bits -2 63 ÷ 2 63 -1 0l

Kiểu dữ liệu Kích thước

Phạm vi biểu diễn Giá trị float 32 bits -3.4e38÷3.4e38 0.0f double 64 bits -1.7976 E+308÷+

Nhận giá trị true hoặc false Giá trị mặc định là false

Kiểu dữ liệu Kích thước

Phạm vi biểu diễn Giá trị char 16 bits \u0000÷\uffff 0

Kiểu dữ liệu đối tượng :

Trong Java, có 3 kiểu dữ liệu đối tượng:

 array: Một mảng của các dữ liệu cùng kiểu

 class: Dữ liệu kiểu lớp đối tượng do người dùng định nghĩa

Dữ liệu kiểu lớp giao diện do người dùng định nghĩa chứa các phương thức của giao diện, cho phép tương tác linh hoạt Ép kiểu là quá trình chuyển đổi giữa các kiểu dữ liệu cơ sở, giúp tối ưu hóa việc sử dụng và xử lý dữ liệu trong lập trình.

Hình 2 1 Chuyển đổi giữa các kiểu dữ liệu cơ sở

Trong Java có hai loại ép kiểu dữ liệu:

Mở rộng (widening) là quá trình chuyển đổi kiểu dữ liệu từ kích thước nhỏ hơn sang kích thước lớn hơn mà không làm mất thông tin, ví dụ như chuyển từ kiểu int sang long Quá trình này thường được thực hiện ngầm định bởi trình biên dịch.

Thu hẹp (narrowwing) là quá trình chuyển đổi kiểu dữ liệu từ kích thước lớn hơn sang kích thước nhỏ hơn, nhưng có thể dẫn đến mất thông tin Việc chuyển đổi này không thể thực hiện tự động bởi trình biên dịch; người dùng cần thực hiện chuyển đổi một cách tường minh.

Qui tắc ép kiểu có dạng: ()

Trong đó: : kiểu dữ liệu cần ép sang

: là biểu thức cần ép kiểu cho giá trị trả về của biểu thức

Ví dụ 2.1: float fNum = 2.2; int iCount = (int) fNum

Biến

 Biến là vùng nhớ dùng để lưu trữ các giá trị của chương trình

 Tên biến phải bắt đầu bằng một chữ cái, một dấu gạch dưới hay dấu dollar

 Tên biến có phân biệt chữ hoa chữ thường

 Trong Java, biến có thể được khai báo ở bất kỳđâu trong chương trình

Cú pháp khai báo biến: dataType varName; hoặc dataType varName = value;

Trong đó, dataType là kiểu dữ liệu của biến, varName là tên biến, value là giá trị khởi tạo ban đầu cho biến varName

Phạm vi hoạt động của biến

Biến có phạm vi hoạt động trong toàn bộ khối lệnh mà nó được khai báo, với khối lệnh được xác định bằng dấu “{” và “}” Các kiểu dữ liệu trong khối lệnh bao gồm byte, short, int, long, float và double.

Nếu một biến được khai báo trong một phương thức mà không nằm trong bất kỳ khối lệnh nào, thì phạm vi hoạt động của biến đó chỉ giới hạn trong phương thức đó Biến này có thể được sử dụng trong tất cả các khối lệnh của phương thức tương ứng.

Nếu một biến được khai báo trong một lớp mà không nằm trong bất kỳ phương thức nào, biến đó sẽ có phạm vi hoạt động toàn bộ lớp và có thể được sử dụng trong tất cả các phương thức của lớp đó.

Toán tử

Toán tử số học yêu cầu các toán hạng phải là số hoặc ký tự, không chấp nhận các toán hạng kiểu boolean Dưới đây là bảng liệt kê một số kiểu toán tử số học.

+ Trả về giá trị tổng hai toán hạng

- Trả về kết quả của phép trừ.

* Nhân Trả về giá trị là tích hai toán hạng.

/ Chia.Trả về giá trị là thương của phép chia

% Phép lấy modul Giá trị trả về là phần dư của phép chia

++ Tăng giá trị của biến lên 1 Ví dụ a++ tương đương với a = a + 1 Giảm giá trị của biến 1 đơn vị Ví dụ a tương đương với a = a - 1

-= Giảm giá trị của biến 1 đơn vị Ví dụ a tương đương với a = a - 1

*= Ví dụ c *= a tương đương với c = c*a

/= Ví dụ c /= a tương đương với c = c/a

%= Ví dụ c %= a tương đương với c = c%a

&& Và (AND) Trả về giá trị “Đúng” (True) chỉ khi cả hai toán tử có giá trị “True”

|| Hoặc (OR) Trả về giá trị “True” nếu ít nhất một giá trị là True

! NOT Chuyển giá trị từ True sang False và ngược lại.

Các toán tử điều kiện:

Toán tử điều kiện là một loại toán tử đặc biệt vì nó bao gồm ba thành phần cấu thành biểu thức điều kiện

Cú pháp: ? : ;

 biểu thức 1: Biểu thức logic Trả trả về giá trị True hoặc False

 biểu thức 2: Là giá trị trả về nếu xác định là True

 biểu thức 3: Là giá trị trả về nếu xác định là False

Toán tử gán (=) trong lập trình được sử dụng để gán giá trị cho biến, cho phép gán nhiều giá trị cho nhiều biến cùng một lúc Ví dụ, đoạn lệnh "int x = 20; int p, q, r, s; p = q = r = s = x;" gán giá trị 20 cho biến x và đồng thời gán giá trị này cho các biến p, q, r, và s trong cùng một dòng lệnh.

Dòng lệnh cuối cùng được thực hiện theo thứ tự từ phải qua trái Đầu tiên, giá trị của biến x được gán cho biến s, tiếp theo giá trị của s được gán cho biến r, và quy trình này tiếp tục như vậy.

Strings và String Buider

Class String trong Java là một thành phần quan trọng, được thiết kế là không thể thay đổi (immutable) và là final, nghĩa là không cho phép bất kỳ class nào thừa kế nó Mọi thay đổi trên một đối tượng String sẽ tạo ra một đối tượng String mới.

Trong Java, String là một lớp đặc biệt được sử dụng phổ biến trong các chương trình, yêu cầu hiệu suất cao và tính linh hoạt Vì vậy, String có cả tính chất đối tượng và tính chất nguyên thủy.

Có thể tạo một string literal (chuỗi chữ), string literal được lưu trữ trong ngăn xếp (stack), đòi hỏi không gian lưu trữ ít

Có thể sử dụng toán tử + để nối 2 string, toán tử này vốn quen thuộc và sử dụng cho các kiểu dữ liệu nguyên thủy int, float, double

Các string literal được lưu trữ trong một bể chung, cho phép hai string literal có nội dung giống nhau chia sẻ cùng một vùng bộ nhớ trên stack Điều này giúp tiết kiệm bộ nhớ hiệu quả.

Vì String là một class, vì vậy nó có thể được tạo ra thông qua toán tử new.

String object = new String("Hello World");

Các đối tượng String được lưu trữ trên Heap, điều này đòi hỏi quản lý bộ nhớ phức tạp và chiếm nhiều không gian lưu trữ Đáng chú ý, hai đối tượng String có nội dung giống nhau sẽ được lưu trữ ở hai vùng bộ nhớ khác nhau trên Heap.

Các phương thức của String

Phương thức charAt(int index) trả về ký tự tại vị trí chỉ số được chỉ định trong chuỗi, trong khi phương thức compareTo(Object o) so sánh một chuỗi với một đối tượng khác.

Int compareTo (String anotherString) So sánh hai chuỗi theo từ điển

(Phân biệt chữ hoa chữ thường) int compareToIgnoreCase (String str) So sánh hai chuỗi theo từ điển

(Không phân biệt chữ hoa chữ thường)

String concat (String str) Nối chuỗi boolean contentEquals (StringBuffer sb)

Hàm trả về true nếu chuỗi đại diện cho cùng một chuỗi ký tự như được quy định bởi StringBuffer Phương thức static String copyValueOf(char[] data) trả về một chuỗi tương ứng với chuỗi ký tự trong mảng đã chỉ định Ngoài ra, phương thức static String copyValueOf(char[] data, int offset, int count) cũng cho phép trả về chuỗi từ một phần của mảng ký tự.

Hàm trả về một chuỗi đại diện cho chuỗi ký tự trong mảng quy định Phương thức `endsWith(String suffix)` kiểm tra xem chuỗi có kết thúc bằng hậu tố đã chỉ định hay không Ngoài ra, phương thức `equals(Object anObject)` dùng để so sánh chuỗi với một đối tượng khác.

So sánh với một String khác, không phân biệt chữ hoa chữ thường. byte[] getBytes ( )

Mã hóa chuỗi thành một mảng byte bằng cách sử dụng bảng mã mặc định của nền tảng và lưu trữ kết quả vào một mảng byte mới.

Encode the string into a sequence of bytes using a predefined character encoding table, and store the results in a new byte array Utilize the method `void getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin)` to achieve this transformation effectively.

Sao chép các ký tự từ chuỗi nguồn vào mảng ký tự đích Phương thức `int indexOf(int ch)` trả về chỉ số đầu tiên xuất hiện của ký tự cụ thể trong chuỗi Phương thức `int indexOf(int ch, int fromIndex)` cho phép tìm kiếm ký tự bắt đầu từ chỉ số đã chỉ định.

Hàm `indexOf` trong chuỗi trả về chỉ số xuất hiện đầu tiên của ký tự hoặc chuỗi được chỉ định, bắt đầu tìm kiếm từ chỉ số cụ thể đến cuối chuỗi Cú pháp sử dụng là `int indexOf(String str)` để tìm chỉ số đầu tiên của chuỗi quy định, hoặc `int indexOf(String str, int fromIndex)` để chỉ định vị trí bắt đầu tìm kiếm.

Phương thức `int indexOf(int ch)` trả về chỉ số của sự xuất hiện đầu tiên của ký tự trong chuỗi, bắt đầu từ chỉ số xác định Trong khi đó, phương thức `int lastIndexOf(int ch)` cung cấp chỉ số của sự xuất hiện cuối cùng của ký tự cụ thể trong chuỗi Ngoài ra, phương thức `int lastIndexOf(int ch, int fromIndex)` cho phép tìm kiếm chỉ số của sự xuất hiện cuối cùng của ký tự, bắt đầu từ vị trí chỉ định trong chuỗi.

Hàm `lastIndexOf(String str)` trả về chỉ số của sự xuất hiện cuối cùng của ký tự được chỉ định trong chuỗi, bắt đầu tìm kiếm từ một chỉ số xác định Hàm `length()` cung cấp độ dài của chuỗi Hàm `matches(String regex)` kiểm tra xem chuỗi có khớp với biểu thức chính quy được chỉ định hay không Cuối cùng, hàm `regionMatches(int offset, String other, int ooffset, int len)` kiểm tra xem một phần của chuỗi có giống với một chuỗi khác hay không.

String replace (char oldChar, char newChar)

Trả về một chuỗi mới từ thay thế tất cả các lần xuất hiện của ký tự oldChar trong chuỗi này với ký tự newChar.

String replaceAll (String regex, String replacement)

Thay thế tất cả các chuỗi con của chuỗi này khớp với biểu thức chính quy bởi String mới replacement

String replaceFirst (String regex, String replacement)

Thay thế chuỗi con đầu tiên của chuỗi này khớp với biểu thức chính quy bởi một String mới replacement

Tách chuỗi thành các chuỗi con tại những vị trí khớp với biểu thức chính quy đã cho Hàm boolean startsWith (String prefix) được sử dụng để kiểm tra xem chuỗi có bắt đầu bằng tiền tố quy định hay không.

CharSequence subSequence (int beginIndex, int endIndex)

Trả về một chuỗi ký tự mới là một dãy con của dãy này.

String substring (int beginIndex, int endIndex)

Trả về một chuỗi ký tự mới, đại diện cho một dãy con từ chỉ số bắt đầu đến chỉ số cuối Phương thức char[] toCharArray() cho phép chuyển đổi chuỗi này thành mảng ký tự.

Chuyển tất cả các ký tự của chuỗi này sang chữ thường, sử dụng miền địa phương mặc định (default locale)

Chuyển tất cả các ký tự của chuỗi này sang chữ thường, sử dụng miền địa phương (locale) cho trước.

String toString ( ) Trả về String này.

String toUpperCase ( ) Chuyển tất cả các ký tự của chuỗi này sang chữ hoa, sử dụng miền địa phương mặc định (default locale)

String toUpperCase (Locale locale) Chuyển tất cả các ký tự của chuỗi này sang chữ hoa, sử dụng miền địa phương (locale) cho trước.

String trim ( ) Trả về một String mới, sau khi loại bỏ các ký tự trắng bên trái và bên phải.

Nhập/Xuất dữ liệu

Trong Java có 3 cách nhập liệu từ bàn phím: a Sử dụng lớp BufferReader

BufferReader là một lớp dùng để đọc dữ liệu từ bàn phím hay từ file.

Có thể dùng lớp này để đọc một chuỗi một mảng hoặc một kí tự.

Ví dụ 2.2: import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; public class GetInputFromKeyboard

{ public static void main(String[] args)

// Tạo một đối tượng BufferedReader

BufferedReader dataIn = new BufferedReader(new InputStreamReader( System.in) );

System.out.println("Please Enter Your Name:"); try

System.out.println("Hello " + name +"!");

Tham số đầu vào của BufferReader có thể là InputStreamReader hoặc FileReader (Dùng để đọc file).

Một số phương thức của lớp BufferReader:

- read() : đọc một kí tự.

- readLine() : đọc một dòng text. b Sử dụng JOptionPane

JOptionPane là một lớp thừa kế từ lớp JComponent Khi biên dịch chương trìnhsẽ hiện lên một dialog box cho phép nhập dữ liệu.

Ví dụ 2.3: import javax.swing.JOptionPane; public class InputFromKeyboardJOptionPane

{ public static void main(String[] args)

String name = ""; name=JOptionPane.showInputDialog("Please enter your name");

System.out.println("Name is:"+msg);

Một số phương thức của JOptionPane:

- showConfirmDialog() : Hiển thị một câu hỏi lựa chọn giống như yes no cancel

- showInputDialog() : Hiển thị box nhập

- showMessageDialog() : Báo cho người dùng một sự kiện vừa xảy ra. c) Sử dụng lớp Scanner

- Lớp Scanner trong Java cho phép nhập dữ liệu từ bàn phím.

- Lớp Scanner có thể đọc được nhiều kiểu dữ liệu khác nhau chẳng hạn Int, Long, Double, String, Float

Một số phương thức thường được sử dụng trong lớp Scanner:

Các phương thức trong Java cho phép lấy dữ liệu từ đầu vào như sau: `next()` trả về chuỗi trước khoảng trắng; `nextLine()` trả về toàn bộ nội dung của một hàng; `nextByte()` trả về kiểu dữ liệu byte; `nextShort()` trả về kiểu dữ liệu short; `nextInt()` trả về kiểu dữ liệu int; `nextLong()` trả về kiểu dữ liệu long; `nextFloat()` trả về kiểu dữ liệu float; và `nextDouble()` trả về kiểu dữ liệu double.

Sự khác nhau khi sử dụng next() và nextLine() lớp Scanner trong Java:

–Phương thức next() sẽ trả về kết quả cách nhau bởi khoảng trắng.

Ví dụ 2.4: import java.util.Scanner; public class Main { public static void main(String[] args) {

String str = "Chào mừng bạn đến với \ nKênh Lập Trình";

Scanner scanner = new Scanner(str); while(scanner.hasNext()){

System.out.println(scanner.next());

Phương thức nextLine() sẽ trả về kết quả nội dung của một hàng, ví dụ:

31 import java.util.Scanner; public class Main { public static void main(String[] args) {

String str = "Chào mừng bạn đến với \ nKênh Lập Trình";

Scanner scanner = new Scanner(str); while(scanner.hasNext()){

System.out.println(scanner.nextLine());

To calculate the sum of two numbers entered from the keyboard, utilize the Scanner class in Java The following code snippet demonstrates how to implement this functionality: ```javapackage exam; import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); System.out.print("Enter the first number: "); int firstNumber = scanner.nextInt(); System.out.print("Enter the second number: "); int secondNumber = scanner.nextInt(); int sum = firstNumber + secondNumber; System.out.println("The sum is: " + sum); scanner.close(); } }```This code effectively prompts the user for two integers, calculates their sum, and displays the result.

Scanner scanner = new Scanner(System.in);

System.out.print("Vui lòng nhập số hạng thứ nhất: "); int sothu1 = scanner.nextInt();

System.out.print("Vui lòng nhập số hạng thứ hai: "); int sothu2 = scanner.nextInt();

System.out.println("Tính tổng: " + (sothu1 + sothu2)); scanner.close();

Câu lệnh và các cấu trúc lệnh trong Java

Java cung cấp hai loại cấu trúc điều khiển: Điều khiển rẽ nhánh

2.6.1 Lệnh, khối lệnh trong Java

Giốngngôn ngữ C, các câu lệnh trong Java kết thúc bằngdấu chấm phẩy (;)

Một khối lệnh là phần chương trình bao gồm hai lệnh trở lên, được mở đầu bằng dấu ngoặc nhọn ({) và kết thúc bằng dấu ngoặc nhọn (}) Bên trong khối lệnh, có thể chứa nhiều lệnh hoặc các khối lệnh khác.

} // kết thúc khối lệnh 2 lệnh 1.1 lệnh 1.2

// Các lệnh thuộc khối lệnh 3

Java đưa ra hai cấu trúc lệnh if…else như sau:

là Biểu thức boolean như toán tử so sánh.

, là câu lệnh đơn hoặc khối lệnh trong Java;

Ví dụ 2.5: Chương trình kiểm tra xem ngày hiện tại có phải chủ nhật hay không: import java.util.Date; public class TestIf { public static void main( String args[ ] ){

Date today = new Date(); if( today.getDay() == 0 )

System.out.println(“Hom nay la chu nhat\n”); else

System.out.println(“Hom nay khong la chu nhat\n" );

Khối lệnh switch-case có thể được sử dụng thay thế câu lệnh if-else trong trường hợp một biểu thức cho ra nhiều kết quả

{ case ‘value1’: action 1 statement; break; case ‘value2’: action 2 statement; break; case ‘valueN’: actionN statement; break; default: default_action statement;

Biểu thức trong Java là một thành phần chứa giá trị xác định và phải có kiểu dữ liệu là char, byte, short hoặc int Nếu biểu thức có kiểu khác với các kiểu đã nêu, Java sẽ thông báo lỗi.

- value1, value 2,…., valueN: Các giá trị hằng số cùng kiểu dữ liệu với giá trị trên biến expression

- action1, action2…, actionN: Khối lệnh được thực thi khi trường hợp tương ứng có giá trị True

- break: Câu lệnh được sử dụng để bỏ qua tất cả các câu lệnh sau đó và giành quyền điều khiểncho cấu trúc bên ngoài switch

- default: Từ khóa tuỳ chọn được sử dụng để chỉ rõ các câu lệnh nào được thực hiện chỉ khi tất cả các trường hợp nhận giá trị False

- default - action: Khối lệnh được thực hiện chỉ khi tất cả các trường hợp nhận giá trị False

Ví dụ 2.6: Xác định giá trị trong một biến nguyên và hiển thị ngày trong tuần được thể hiện dưới dạng chuỗi class SwitchDemo

{ public static void main(String agrs[]) { int day = 2; switch(day)

The provided code snippet demonstrates a switch-case statement that prints the name of the day based on the integer value associated with each day of the week For instance, if the value is 0, it outputs "Sunday"; if it's 1, it outputs "Monday"; and so on, up to 6, which corresponds to "Saturday." Each case ends with a break statement to prevent fall-through, ensuring that only the matching case executes.

35 break; default: System.out.println(“Invalid day of week”);

Nếu giá trị của biến day = 4, chương trình sẽ hiển thị “Thursday”

Vòng lặp while thực thi khối lệnh khi điều kiện thực thi condition vẫn là True và dừng lại khi điều kiện thực thi condition nhận giá trị False

Ví dụ 2.7: Tính tổng các số lẻ từ 1 đến 20 int tong = 0, i = 1; while (i< )

System.out.println(“Tong bang ”+ tong); Ở ví dụ trên, vòng lặp được thực thi cho đến khi điều kiện i< là False

Kết quả in ra: Tong bang 100

Cú pháp: do{ action statements;

Vòng lặp do-while thực hiện khối lệnh khi điều kiện là True, tương tự như vòng lặp while, nhưng khác ở chỗ do-while sẽ thực hiện lệnh ít nhất một lần, ngay cả khi điều kiện là False.

Ví dụ 2.8: Tính tổng các số lẻ từ 1 đến 20 int tong = 0, i=1;

System.out.println(“Tong bang ”+ tong); Ở ví dụ trên, vòng lặp được thực thi cho đến khi điều kiện i< là False

Cú pháp: for(initialization statements; condition; increment statements)

Ví dụ 2.9: Tính tổng các số lẻ từ 1 đến 20 public class TestFor

{ public static void main(String[] args)

{ int tong = 0; for(int i=1; i< ; i+=2) tong+=i;

System.out.println(“Tong bang ” + tong);

Vòng lặp được thực thi cho đến khi điều kiện i< là False

2.6.7 Lệnh break và cont inue

Trong cấu trúc lặp, luồng thực hiện có thể được điều khiển thông qua các lệnh break và continue Lệnh break sẽ dừng ngay quá trình lặp mà không thực hiện phần còn lại của thân vòng lặp, trong khi lệnh continue sẽ bỏ qua phần còn lại và chuyển điều khiển về đầu vòng lặp để thực hiện lần lặp tiếp theo.

Ví dụ 2.10: public class BreakAndContinue { public static void main(String[] args) { for(int i = 0; i < 100; i++) { if(i == 74) break;// Out of for loop if(i % 9! = 0) continue;// Next iteration

} int i = 0; // An "infinite loop": while(true) { i++; int j = i * 27; if(j == 945) break;// Out of loop if(i % 10! = 0) continue;// Top of loop

Số lớn trong java

Lớp BigInteger sử dụng để xử lýcác số nguyên rất lớn nằm ngoài giới hạn của tất cả các kiểu dữ liệu nguyên thủy có sẵn.

Sử dụng phương thức tĩnh valueOf để chuyển một số bình thường thành số nguyên lớn BigInteger A = BigInterger(valueOf(100));

Hàm tạo này được sử dụng để dịch một mảng byte chứa biểu diễn nhị phân bổ sung của hai BigInteger thành một BigInteger.

BigInteger (int numBits, rnd ngẫu nhiên)

Hàm tạo này được sử dụng để tạo ngẫu nhiên một BigInteger nằm trong phạm vi từ 0 đến (2 numBits - 1)

Hàm tạo này được sử dụng để chuyển biểu diễn Chuỗi thập phân của BigInteger thành BigInteger.

BigInteger (Chuỗi val, int radix)

Hàm tạo này được sử dụng để chuyển biểu diễn Chuỗi của BigInteger trong cơ số được chỉ định thành BigInteger.

Một số phương thức thường dùng:

BigInteger add (BigInteger val)- Phương thức này trả về một BigInteger có giá trị là (this + val)

Int compareTo(BigInteger val)- so sánhBigInteger với BigInteger xác định. float floatValue() Chuyển BigInteger thành kiểu float.

BigInteger max(BigInteger val) Trả về giá trị lớn nhất của BigInteger và val.BigInteger min(BigInteger val) Trả về giá trị nhỏ nhất của BigInteger và val

Mảng

Mảng là tập hợp nhiều phần tử có cùng tên, cùng kiểu dữ liệu và mỗi phần tử trong mảng được truy xuất thông qua chỉ số trong mảng.

Khai báo []; hoặc [] ;

Ví dụ 2.11: int arrInt[]; // đây là mảng các số nguyên hoặc int[ ] arrInt;

Để cấp phát bộ nhớ cho mảng trong Java, chúng ta sử dụng từ khóa "new", vì mọi thứ trong Java đều được thực hiện thông qua các đối tượng Ví dụ, để cấp phát vùng nhớ cho mảng số nguyên với tối đa 100 phần tử, ta thực hiện như sau:

Truy nhập các phần tử trong mảng

Trong Java, chỉ số của mảng bắt đầu từ 0, nghĩa là phần tử đầu tiên có chỉ số là 0 và phần tử thứ n có chỉ số là n-1 Để truy xuất các phần tử của mảng, bạn sử dụng chỉ số của chúng nằm trong cặp dấu ngoặc vuông [].

Ví dụ 2.12: int arrInt[] = {1, 2, 3}; int x = arrInt[0]; // x sẽ có giá trị là 1 int y = arrInt[1]; // y sẽ có giá trị là 2 int z = arrInt[2]; // z sẽ có giá trị là 3

Trong nhiều ngôn ngữ lập trình như C, chuỗi được coi là một mảng các ký tự Tuy nhiên, trong Java, chuỗi được xử lý khác biệt nhờ vào lớp String, cho phép người dùng thực hiện các thao tác linh hoạt trên đối tượng dữ liệu chuỗi.

Vòng lặp foreach được sử dụng chủ yếu với mảng và ArrayList

Cú pháp: for(Khai_bao : Bieu_thuc)

Ví dụ 2.13: public class Test { public static void main(String args[]){ int [] numbers = {10, 20, 30, 40, 50}; for(int x : numbers ){

String [] names ={"James", "Larry", "Tom", "Lacy"}; for( String name : names ) {

2.8.2 Khởi tạo mảng và mảng nặc danh

Chúng tacó thể khởi tạo giá trị ban đầu cho các phần tử của mảng khikhai báo

Ví dụ về mảng trong lập trình bao gồm: mảng số nguyên với 4 phần tử int arrInt[] = {1, 2, 3, 4}; mảng ký tự với 3 phần tử char arrChar[] = {'a', 'b', 'c'}; và mảng chuỗi với 3 phần tử kiểu String String arrStrng[] = {"ABC", "DEF", "GHI"}.

Cũng có thể khởi tạo một mảng nặc danh new int[] { 17, 19, 23, 29, 31, 37 };

Sử dụng cú pháp khai báo mảng nặc danh này ta có thể khởi tạo một mảng mà không cần khai báo thêm biến mới. smallPrimes = new int[] { 17, 19, 23, 29, 31, 37 };

Là rút gọn của khai báo: int[] anonymous = { 17, 19, 23, 29, 31, 37 }; smallPrimes = anonymous

Ví dụ 2.15: Nhập và xuất giá trị các phần tử của một mảng các số nguyên class ArrayDemo

{ public static void main(String args[])

{ int arrInt[] = new int[10]; int i; for(i = 0; i < 10; i = i+1) arrInt[i] = i; for(i = 0; i < 10; i = i+1)

System.out.println("This is arrInt[" + i + "]: " + arrInt[i]);

Có thể sao chép một mảng vào một mảng khác, nhưng cả hai mảng phải tham chiếu đến cùng một đối tượng Ví dụ, khi gán `int[] luckyNumbers = smallPrimes;`, nếu bạn thay đổi giá trị tại chỉ số 5 của `luckyNumbers` thành 12, thì giá trị tại chỉ số 5 của `smallPrimes` cũng sẽ trở thành 12.

2.8.4 Các tham số dòng lệnh

Trong hàm main của Java, tham số `String[] args` cho phép hàm nhận giá trị đầu vào dưới dạng một mảng các xâu ký tự, những tham số này được truyền qua dòng lệnh.

Ví dụ 2.16: public class Message

{ public static void main(String[] args)

System.out.print("Hello,"); else if (args[0].equals("-g"))

// print the other command-line arguments for (int i = 1; i < args.length; i++)

Biên dịch chương trình và chạy java Message -g cruel world

Mảng args có nội dung sau args[0]: "-g" args[1]: "cruel"

Chương trình cho kết quả

2.8.5 Sắp xếp mảng Để sắp xếp một mảng số tadùng phương thức sort trong class Array int[ ] a= new int [10000];

Array.sort(a);/ / sẽ sắp xếp mảng a

Cú pháp khai báo mảng hai chiều:

[Kiểu_dữ_liệu] Tên_mảng[][]; Hoặc [Kiểu_dữ_liệu][][] Tên_mảng;

Cấp phát bộ nhớ cho mảng

Trong Java có 2 cách cấp phát bộ nhớ như sau:

[Kiểu_dữ_liệu] Tên_mảng[][] = new [Kiểu_dữ_liệu] [Số_dòng][Số_cột];

Ví dụ 2.18: Khai báo và cấp phát bộ nhớ cho mảng number có 2 dòng, 3 cột: int number[][] = new int[2][3];

[Kiểu_dữ_liệu][][] Tên_mảng = new[Kiểu_dữ_liệu] [Số_dòng][Số_cột];

Truy xuất các phần tử trong mảng hai chiều

Mỗi phần tử trong mảng 2 chiều được truy xuất thông qua tên mảng cùng với chỉ số dòng và chỉ số cột Nếu mảng 2 chiều có m dòng và n cột, chỉ số dòng sẽ từ 0 đến m - 1 và chỉ số cột từ 0 đến n - 1.

Cú pháp: Tên_mảng[Chỉ_số_dòng][Chỉ_số_cột];

Ví dụ 2.19: Nhập xuất mảng hai chiều public static void main(String[] args)

// khai báo số dòng và số cột cho mảng int soDong, soCot;

Scanner scanner = new Scanner(System.in);

System.out.prin tln("Nhập vào số dòng của mảng: "); soDong = scanner.nextInt();

System.out.pri ntln("Nhập vào số cột của mảng: "); soCot = scanner.nextInt();

// khai báo và cấp phát bộ nhớ cho mảng

43 int[][] A = new int[soDong][soCot]; for (int i = 0; i < soDong; i++) { for (int j = 0; j < soCot; j++) {

System.out.print("Nhập phần tử thứ [" + i + ", " + j + "]: "); A[i][j] = scanner.nextInt();

System.out.println("Mảng vừa nhập: "); for (int i = 0; i < soDong; i++) { for (int j = 0; j < soCot; j++) {

Câu 1 Những từ sau có phải là định danh hay không? a/ aZ4, b/ ân2, c/_class, d/ My$100

Câu 2 Dãy //* // */ có phải là chú thích hay không ? tại sao ?

Những lệnh nào trong số các lệnh sau là hợp lệ a Char a =’\u0061’; b Char ‘\u0061’=’a’; c Long phone35469L; d Fload pi=3.14159; e Double p14.159e-2;

In Java, the correct declarations for the main() method include: a) static void main(String arg[]) { /* */ }, and e) final static public void main(String[] arg) { /* */ } However, options b) public static int main(String arg[]) { /* */ }, c) public stactic void main(String arg[]) { /* */ }, and d) public stactic void main(String[] arg) { /* */ } are incorrect due to either return type errors or typos in the keyword "static."

Câu 4 Tìm câu trả lời đúng cho các câu hỏi sau: a) Trong cấu trúc if-else đơn (1 if và 1 else), ít nhất một khối lệnh (của if hoặc của else) sẽ được thực hiện Đúng hay sai? b) Trong cấu trúc switch-case, nếu không có “default”, thì có ít nhất một khối lệnh được thực hiện Đúng hay sai? c) Trong cấu trúc switch-case, khi có “default”, thì ít nhất một khối lệnh sẽ được thực hiện Đúng hay sai? d) Trong cấu trúc lệnh while, khối lệnh sẽ được thực hiện ít nhất một lần ngay cả khi điều kiện là False Đúng hay sai? e) Trong cấu trúc do-while, khối lệnh sẽ được thực hiện ít nhất một lần ngay cả khi điều kiện là False Đúng hay sai? f) Trong cấu trúc for, khối lệnh sẽ được thực hiện ít nhất một lần ngay cả khi điều kiện là False Đúng hay sai?

Câu 5 Chương trình sau có lỗi hay không, nếu có lỗi thì sửa cho đúng.

Public VOID main(String arg){ double fahreb.5; double celsius(fahre);

System.uot.println(fahre +’F=’+celsius+’c’);

Đoạn chương trình trên thực hiện vòng lặp 10 lần, bắt đầu từ giá trị i = 0 đến i = 9 Kết quả in ra sẽ là tổng của các số từ 0 đến 9, tức là 45.

Đoạn chương trình trên thực hiện vòng lặp 6 lần Biến `i` bắt đầu từ 5 và tăng lên 1 sau mỗi lần lặp cho đến khi `i` trở thành 11 Kết quả in ra của biến `sum` là tổng của các giá trị từ 5 đến 10, tức là 5 + 6 + 7 + 8 + 9 + 10 = 45.

Câu 8 Cho biết kết quả thực hiện chương trình sau : public class MyClas{ public static coid main (String [] arg){

String a,b,c; c=new String(“chuột”); b=new String(“Mèo”); b=a; a=”Chó”; c=b;

Câu 9 Điều gì sẽ xảy ra khi chạy và dịchchương trình sau : public class Prog1{ public static void main (String [] arg ) { int k=1; int i=++k + k++ + +k;

Khi chạy chương trình trên, giá trị của biến k sẽ được gán là 9, và mảng a sẽ có giá trị a[0] là 9 và a[1] vẫn giữ nguyên giá trị 6 Kết quả in ra sẽ là "i 9 6".

Câu 11 Cho biết kết quả thực hiện chương trình sau : public class Prog3{ public static void main (String [] arg){ int k =0 , i=0; boolean r,t=true; r=(t & 0< (i +=1)) ; r = (t && 0 < (i+=2)); r= (t | 0 < (k+=1)); r = (t || 0 < (k+=2));

Câu 12 Kết quả dich và chạy chương trình sau là gì ? public class Prog4{ public static void main (String [] arg){ int a=0,b=0; int [] bArr new int [1]; bArr[0] = b; inC1(a) ; inC2(bArr);

System.out.println(“a= ” + a + “b =” + b +”bArr = “+ bArr[0]”);

} public static void inC1(int x){x++;}; public static void inC2(int [] x) {x[0]++;};

Bài 1 Viết chương trình tìm ước số chung lớn nhất, bội số chung nhỏ nhất của hai số tự nhiên a và b.

Bài 2.Viết chương trình chuyển đổi một số tự nhiên ở hệ cơ số 10 thành số ở hệ cơ số b bất kì (1< b≤ 36).

Bài 3 Hãy viết chương trình tính tổng các chữ số của một số nguyên bất kỳ Ví dụ: Số

8545604 có tổng các chữ số là: 8+5+4+5+6+0+4= 32.

Bài 4.Viết chương trình phân tích một số nguyên thành các thừa số nguyên tố

Ví dụ: Số 28 được phân tích thành 2 x 2 x 7

Bài 5.Viết chương trìnhliệt kê tất cả các số nguyên tố nhỏ hơn n cho trước.

Bài 6 Viết chương trình liệt kê n số nguyên tố đầu tiên.

Bài 7.Dãy số Fibonacci được định nghĩa như sau: F0 =1, F1 = 1; Fn = Fn-1 + Fn-2 với n>=2 Hãy viết chương trình tìm số Fibonacci thứ n.

Bài 8 Nhập số n và dãy các số thực a 0 , a1 , , an-1 Không đổi chỗ các phần tử và không dùng thêm mảng số thực nào khác (có thể dùng mảng số nguyên nếu cần) hãy cho hiện trên màn hình dãy trên theo thứ tự tăng dần.

Bài 9 Viết chương trình nhập vào vào ma trận A có n dòng, m cột, các phần tử là những số nguyên lớn hơn 0 và nhỏ hơn 100 được nhập vào từ bàn phím Thực hiện các chức năng sau: a)Tìm phần tử lớn nhất của ma trận cùng chỉ số của số đó. b)Tìm và in ra các phần tử là số nguyên tố của ma trận (các phầntử không nguyên tố thì thay bằng số 0). c)Sắp xếp tất cả các cột của ma trận theo thứ tự tăng dần và in kết quả ra màn hình.

Viết chương trình java cho phép tạo và thực thi theo menu sau:

1 Nhập vào một số nguyên dương n.

2 Tính tổng các số từ 1 đến n

3 Kiểm tra n có là số nguyên tố

4 Kiểm tra n có là số hoàn hảo.

5 In ra các số nguyên tố từ 1 đến n

6 In ra các số hoàn hảo từ 1 đến n.

7 Hiển thị số n thành tích các thừa số nguyên tố.

Bài 11 Viết chương trình nhập vào vào mảng A có n phần tử, các phần tử là những số nguyên lớn hơn 0 và nhỏ hơn 100 được nhập vào từ bàn phím Thực hiện các chức năng sau: a) Tìm phần tử lớn nhất và lớn thứ 2 trong mảng cùng chỉ số của các số đó. b) Sắp xếp mảng theo thứ tự giảm dần c) Nhập một số nguyên x và chèn x vào mảngA sao cho vẫn đảm bảo tính sắp xếp giảm dần và số phần tử của mảng vẫn không đổi.

Bài 12 Nhập một dãy n số nguyên, tìm khoảng cách ngắn nhất giữa hai số liền kề nhau.

Ví dụ: input 4 8 6 1 2 9 4, out put: Khoảng cách ngắn nhất là 1, giữa hai số 1 và 2.

ĐỐI TƯỢNG, LỚP, KẾ THỪA, GIAO DIỆN

Đối tượng, lớp, lớp trừu tượng

Lớp là một khuôn mẫu cho đối tượng, bao gồm các thuộc tính và phương thức để tác động lên các thuộc tính đó.

Lớp SinhVien bao gồm các thuộc tính như MãSV, điểm và hạnh kiểm, cùng với các phương thức học tập, thực hành và giải trí Mỗi đối tượng trong lớp này là một thể hiện (class instance) cụ thể, với dữ liệu và hành vi được định nghĩa rõ ràng.

Mỗi sinh viên cụ thể là mộtthể hiện (hay đối tượng) của lớp SinhVien

3.1.2 Khai báo lớp class

Trong đó: class: là từ khóa của Java

ClassName là tên của lớp, trong khi field_1 và field_2 đại diện cho các thuộc tính, tức là các biến hoặc thành phần dữ liệu của lớp Constructor là phương thức dùng để xây dựng và khởi tạo đối tượng của lớp Các phương thức method_1 và method_2 thực hiện các thao tác xử lý và tác động lên các thuộc tính của lớp.

Ví dụ 3.2: Khai báo một lớp rỗng không chứa thuộc tính, phương thức.

// không chứa thuộc tính, phương thức

In this example, we define a class named `Pencil` that includes properties such as color, length, and diameter, along with a static variable `nextID` for unique identification The class features a method called `setColor` that allows users to change the pencil's color by passing a new color string as an argument.

3.1.3 Thuộc tính của lớp class

// khai báo những thuộc tính của lớp

field1;

- Kiểu dữ liệu có thể là kiểu dữ liệu cơ sở hoặc kiểu dữ liệu đối tượng tham chiếu: boolean, char, byte, short, int, long, float, double

Chỉ định truy xuất thuộc tính lớp + các bổ nghĩa loại thuộc tính nếu có (Các bổ nghĩa loại thuộc tính có thể là static hoặc final hoặc cả 2)

- Sau tên trường có thể có kèm theo giá trị khởi tạo

Chỉ định truy xuất thuộc tính lớp:

- private: Có thể truy cập thuộc tính này chỉ bên trong lớp khai báo

- package (~ không có chỉ định truy xuất): Có thể truy cập từ các lớp trong cùng gói (package) và trong bản thân lớp khai báo

- protected: Có thể truy cập từ các lớp trong cùng gói,các lớp thừa kế và bản thân lớp khai báo

- public: Có thể được truy cập từ bất kỳ một lớp nào

Ví dụ 3.4: public class Pencil { public String color = “red”; public int length; public float diameter; private float price; public static long nextID = 0; public void setPrice (float newPrice) { price = newPrice;

} public class CreatePencil { public static void main (String args[]){ Pencil p1 = new Pencil(); p1.price = 0.5f; // price has private access in Pencil

Các bổ nghĩa loại thuộc tính

 Chỉ một bản duy nhất của thuộc tính static được tồn tại, chia sẻ giữa các đối tượng của cùng lớp chứa thuộc tính này

 Có thể được truy cập trực tiếp trong bản thân lớp khai báo (truy cập trong hàm main)

Khi truy cập thuộc tính từ bên ngoài lớp khai báo, cần phải sử dụng tên lớp trước thuộc tính, ví dụ: System.out.println(Pencil.nextID), hoặc thông qua một đối tượng thuộc lớp đó.

 Từ bên ngoài lớp, các thuộc tính non-static phải được truy cập thông qua tham chiếu đối tượng

Ví dụ 3.5: public class CreatePencil { public static void main (String args[]){ Pencil p1 = new Pencil();

Pencil p2 = new Pencil(); Pencil.nextID++;

 Khi đã được khởi tạo, giá trị không thể thay đổi

 Thường được sử dụng cho các hằng số

 Thuộc tính static + final phải được khởi tạo ngay khi khai báo

 Thuộc tính non-static + final phải được khởi tạo ngay khi một đối tượng của lớp được tạo ra

Khởi tạo giá trị thuộc tính

Không bắt buộc phải sử dụng hằng số, chúng ta có thể khởi tạo giá trị cho mọi biến nếu có quyền Nếu không thực hiện khởi tạo, giá trị khởi tạo mặc định sẽ phụ thuộc vào loại thuộc tính của biến đó.

()

: Để xác định quyền truy xuất của các đối tượng khác đối với các phương thức của lớp người ta thường dùng các tiền tố sau:

- Các chỉ định truy xuất của phương thức (cùng ý nghĩa với thuộc tính): public, protected, private

- Các bổ nghĩa loại phươngthức: static, final, abstract, synchronized, native, volatile

: có thể là kiểu void, kiểu cơ sở hay một lớp.

: đặt theo qui ước giống tên biến.

: có thể rỗng

Các loại bổ nghĩa của phương thức

- static: Phương thức dùng chung cho tất cả các thể hiện của lớp, chỉ có thể truy cập đến các thuộc tính hoặc phương thức static trong cùng lớp

- final: Phương thức có thuộc tính này không được ghi đè (overridden) trong các lớp thừa kế

- abstract: Phương thức không cần cài đặt, sẽ được cài đặt trong các lớp thừa kế

Ví dụ 3.6: abstract void sampleMethod( );

- Sử dụng toán tử (.): reference.method(arguments)

 Bên ngoài class, tham chiếu reference có thể là tên class hoặc tham chiếu đối tượng của class

 Bên trong class, không cần tham chiếu reference

- Với phương thức non-static: “reference” phải là tham chiếu đối tượng

Giá trị của các đối số truyền vào trong lời gọi phương thức

Khi đối số không phải là một tham chiếu đối tượng, nó truyền vào một bản copy giá trị của đối số

Ví dụ 3.7: public void method1 (int a) { a = 6;

} public void method2 ( ) { int b = 3; method1(b); // now b = ? b = 3

Khi đối số là một tham chiếu đối tượng, nó truyền vào một bản copy của tham chiếu tới đối tượng đó

54 class PassRef{ public static void main(String[] args) {

Pencil plainPencil = new Pencil(); plainPencil.color = “PLAIN”;

System.out.println("original color:" + plainPencil.color); paintRed(plainPencil); // truyen vao tham chieu doi tuong

System.out.println("new color: " + plainPencil.color);

} public static void paintRed(Pencil p) { p.color = "RED"; // doi mau thanh do p = null; // sau do tro toi null

Nạp chồng phương thức (method overloading): Một class có thể có nhiều cách thức có cùng tên nhưng khác nhau về danh sách đối số public class Pencil {

public void setPrice (float newPrice) { price = newPrice;

} public void setPrice (Pencil p) { price = p.getPrice();

Trình dịch xác định sự khác biệt giữa hai danh sách đối số bằng cách so sánh số lượng và kiểu dữ liệu của các đối số, đồng thời chú ý đến thứ tự của chúng.

3.1.5 Chỉ định truy xuất lớp

Một lớp cũng có thể có các chỉ định truy xuất đi trước tên lớp:

 Có thể truy xuất từ bất kỳ đâu

 Không có từ khóa này, lớp chỉ có thể truy cậptrong phạm vi cùng gói

 Lớp này được thiết kế nhằm tạo ra một lớp có các đặc tính tổng quát, nó định nghĩa cácthuộc tính chungcho các lớp con của nó

 Không thể tạo đối tượng (thể hiện) cho những lớp abstract

 Lớp không thể được thừa kế

Tạo đối tượng

In this example, we define a class named Student, which includes private attributes such as idNum, name initialized to "empty," and address Additionally, a static variable nextID is declared to manage the unique identification of each Student object created.

Trong Java, một đối tượng được tạo ra bằng cách sử dụng phương thức new

Tạo đối tượng mới: Student std = new Student ();

Khởi tạo một thể hiện của lớp là một phương thức đặc biệt, cho phép gọi tự động khi tạo đối tượng Phương thức này có thể được sử dụng để gán những giá trị mặc định cho các thuộc tính của đối tượng.

- Không có giá trị trả về, có thể có hoặc không có tham số

- Phải có cùng tên với lớp và được gọi đến khi dùng từ khóa new

Trong trường hợp một lớp không được định nghĩa constructor, Java sẽ tự động cung cấp một constructor mặc định Những thuộc tính của lớp sẽ được khởi tạo với các giá trị mặc định, cụ thể là kiểu số sẽ được gán giá trị 0, kiểu logic sẽ là false, và các đối tượng sẽ có giá trị null.

Chú ý: Thông thường để an toàn, dễ kiểm soát và làm chủ mã nguồn mỗi lớp nên khai báo một constructor

Ví dụ 3.10: class Student { private long idNum;

56 private String name= “empty”; private String address;

// bien static chia se giua cac doi tuong cua lop Student private static long nextID = 0;

// gan gia tri nextID cho idNum, sau do tang nextID len 1 idNum = nextID++;

Student(String studentName, String addr) { this( ); name = studentName; address = addr;

Xem xét trước đó chưa có bất kỳ đối tượng Student nào được tạo ra Xem xét hai trường hợp sau:

Khi đó constructor không có tham số Student() được gọi khởi tạo các giá trị cho đối tượng Student: idNum = 0, name = “empty”, address = null, nextID = 1

Student std = new Student(“Hai”, null);

Student std1 = new Student(“Hau”, “Hung Yen”);

Trong trường hợp này, chúng ta tạo ra hai đối tượng Student thông qua constructor với tham số đầu vào Đối tượng đầu tiên có các giá trị khởi tạo: idNum = 0, name = "Hai", address = null, và nextID = 1 Đối tượng thứ hai được khởi tạo với idNum = 1 (giá trị nextID hiện tại), name = "Hau", address = "Hung Yen", và nextID = 2 (giá trị nextID sau khi tăng).

- Biến this được sử dụng như một tham chiếu đến đối tượng hiện tại

- Trong một constructor có thể dùng biến this để gọi một contructorkhác Nó phải được đặt trong dòng đầutiên của contructor sử dụng nó

- Biến this không thể được sử dụng trong một phương thức static

57 class Student { private long idNum; private String name; private String address; private static long nextID = 0; private static LinkedList studentList = new LinkedList();

Student(String name, String address) { this.name = name; this.address = address;

} private void inQueue() { studentList.add(this); // Them vao danh sach lien ket

Kế thừa và đa hình

Tính kế thừa trong Java là kỹ thuật cho phép một đối tượng thừa hưởng tính chất và hành vi từ đối tượng cha, giúp tạo ra các lớp mới dựa trên lớp đã tồn tại Khi kế thừa, người lập trình có thể tái sử dụng các phương thức và thuộc tính của lớp cha, đồng thời bổ sung thêm các phương thức và thuộc tính mới Tính kế thừa thể hiện mối quan hệ IS-A, hay còn gọi là mối quan hệ cha-con.

Lớp con sử dụng từ khóa extend để có thể kế thừa các thuộc tính của lớp cha trừ các thuộc tính private của lớp cha.

Sự kế thừa trong lập trình cho phép tạo ra một lớp mới dựa trên một lớp đã tồn tại, trong đó tất cả các thuộc tính và phương thức của lớp cũ sẽ được chuyển giao cho lớp mới Lớp cũ được gọi là lớp cha, trong khi lớp mới được gọi là lớp con.

Khai báo lớp kế thừa được thực hiện bởi từ khoá extends:

extends

58 public String name; public int age;

// Phương thức khởi tạo public Person(String name, int age)

{ this.name = name; this.age = age;

System.out.println( name + “ is ” + age + “ years old!”);

// Phương thức khởi dựng public Employee(String name, int age, float salary)

{ super(name, age); this.salary = salary;

Như vậy, khi có lớp: class EmployeeDemo1

{ public static void main(String args[])

Employee myEmployee = new Employee(“Nam”, 2 0, 300f); myEmployee.show();

Ví dụ 3.13: public class xe { public String tenxe; public String hangxe; public xe(String tenxe, String hangxe){ this.tenxe = tenxe; this.hangxe = hangxe;

System.out.println("Tenxe: " + tenxe + "hangxe: " + hangxe);

The class "oto" extends the "xe" class, incorporating properties such as price ("giaban") and speed ("tocdo") It includes a constructor that initializes the vehicle's name ("tenxe"), brand ("hangxe"), price, and speed, leveraging the parent class's constructor for the name and brand attributes.

} public class chitietxe { public static void main(String[] args) { oto xeoto = new oto("HCS","SNC",232,454); xeoto.Show();

In this example, the program demonstrates the implementation of the overloaded Show() method in the 'oto' class, which extends the 'xe' class, without utilizing the Show() method from the parent class The 'oto' class includes attributes for price (giaban) and speed (tocdo), initialized through its constructor, which also calls the parent class constructor to set the vehicle name (tenxe) and brand (hangxe).

System.out.println(tenxe+ "co gia ban ban " + giaban + " toc do:

Quy tắc truy nhập trong kế thừa

Các quy tắc này quy định khả năng truy nhập của lớp con đối với các thuộc tính và phương thức của lớp cha:

 private: chỉ được truy nhập trong phạm vi lớp cha, lớp con không truy nhập được Tất cả các lớp ngoài lớp cha đều không truy nhập được.

 protected: lớp con có thể truy nhập được Tất cả các lớp không kế thừa từ lớp cha đều không truy nhập được.

 final: lớp con có thể sử dụng được nhưng không thể khai báo nạp chồng được.

 public: lớp con có thể sử dụng và nạp chồng được Tất cả các lớp bên ngoài đều sử dụngđược.

Để tránh sự phức tạp của đa kế thừa trong C++, Java không cho phép kế thừa trực tiếp từ nhiều hơn một lớp cha Mặc dù Java không hỗ trợ đa kế thừa trực tiếp, nhưng nó cho phép cài đặt nhiều giao diện (Interface), giúp lập trình viên có thể thừa hưởng thêm các thuộc tính và phương thức từ các giao diện này.

Cú pháp khai báo một giao diệnnhư sau:

[Tính chất] interface [extends ]{

 Tính chất: một giao diện luôn là public Nếu không khai báo tường minh thì giá trị mặc định cũng là public.

 Tên giao diện: tuân thủ theo quy tắc đặt tên biến của Java

Danh sách các giao diện chứa các giao diện cha đã được định nghĩa để kế thừa, được phân cách bởi dấu phẩy Phần trong ngoặc vuông “[]” là tùy chọn.

Lưu ý: Một giao diện chỉ có thể kế thừa từ các giao diện khác mà không thể được kế thừa từ các lớp sẵn có.

Khai báo phương thức của giao diện

[Tính chất] ([]) [throws

Tính chất của thuộc tính hay phương thức trong giao diện luôn là public, và nếu không được khai báo rõ ràng, giá trị mặc định cũng sẽ là public Đối với thuộc tính, tính chất cần phải được khai báo là hằng (final) và tĩnh (static).

 Kiểu giá trị trả về: có thể là các kiểu cơ bản của Java, cũng có thể là kiểu do người dùng tự định nghĩa (kiểu đối tượng).

 Tên phương thức: tuân thủ theo quy tắc đặt tên phương thức của lớp

 Các tham số: nếu có thì mỗi tham số được xác định bằng một cặp

Các tham số được phân cách nhau bởi dấu phẩy.

 Các ngoại lệ: nếu có thì mỗi ngoại lệ được phân cách nhau bởi dấu phẩy.

Các phương thức của giao diện được khai báo dưới dạng mẫu, không có cài đặt chi tiết Mỗi khai báo kết thúc bằng dấu chấm phẩy và không bao gồm phần cài đặt trong dấu ngoặc.

“{}”) Phần cài đặt chi tiết của các phương thức chỉ được thực hiện trong các lớp (class) sử dụng giao diệnđó.

Các thuộc tính trong giao diện luôn được định nghĩa là hằng (final), tĩnh (static) và công khai (public) Vì vậy, khi khai báo thuộc tính của giao diện, cần phải gán giá trị khởi đầu ngay lập tức.

Ví dụ 3.15: Khai báo một giao diệnkhông kế thừa từ bất kì một giao diệnnào: public interface Product{

Giao diện Product được khai báo với một thuộc tính để lưu nhãn hiệu của nhà sản xuất và một phương thức nhằm truy xuất giá bán của sản phẩm.

{ public static final String MARK = “Adidas”; public float getCost();

Giao diện chỉ có thể được khai báo thông qua các phương thức mẫu và thuộc tính hằng, do đó, để sử dụng giao diện, cần có một lớp thực hiện cài đặt giao diện đó Việc khai báo lớp cài đặt giao diện được thực hiện bằng từ khóa "implement".

class implements {

 Tính chấtvà tên lớpđược sử dụng như trong khai báo lớp thông thường.

Một lớp trong lập trình có thể cài đặt nhiều giao diện, được phân cách bởi dấu phẩy Để đảm bảo tính tương thích, lớp đó cần phải cài đặt tất cả các phương thức của từng giao diện mà nó sử dụng.

Một phương thức được định nghĩa trong giao diện cần phải được triển khai cụ thể trong lớp thực hiện giao diện đó, và không được phép khai báo lại Điều này có nghĩa là số lượng tham số của phương thức trong giao diện phải được duy trì nguyên vẹn khi được triển khai trong lớp.

Chương trình này minh họa cách cài đặt lớp giày (Shoe) theo giao diện Product, với các thuộc tính và phương thức đã được định nghĩa trước đó.

Ví dụ 3.16: public class Shoe implements Product{

// Cài đặt phương thức được khai báo trong giao diện public float getCost() public float getCost()

// Phương thức truy nhập nhãn hiệu sản phẩm public String getMark()

// Phương thức main public static void main(String args[])

System.out.println(“This shoe is ” + myShoe.getMark() +“ having a cost of

Phương thức getMark() trả về nhãn hiệu của sản phẩm, thuộc tính được khai báo trong giao diện Trong khi đó, phương thức getCost() được cài đặt riêng cho lớp Shoe, trả về giá trị 10, theo quy định trong giao diện Product mà lớp Shoe sử dụng.

Lớp trừu tượng

Lớp trừu tượng là một loại lớp đặc biệt trong lập trình, nơi mà các phương thức chỉ được định nghĩa dưới dạng khuôn mẫu mà không có cài đặt cụ thể Các lớp con kế thừa từ lớp trừu tượng này sẽ thực hiện việc cài đặt chi tiết cho các phương thức đó.

Lớp trừu tượng được sử dụng khi muốn định nghĩa một lớp mà không thể biết và định nghĩa ngay được các thuộc tính và phương thức của nó.

Lớp trừu tượng được khái báo như cách khai báo các lớp thông thường, ngoại trừ có thêm từ khoá abstract trong phần tính chất:

[public] abstract class {

 Tính chất: mặc định là public, bắt buộc phải có từ khoá abstract để xác định đây là một lớp trừu tượng.

 Tên lớp: tuân thủ theo quy tắc đặt tên lớp thông thường của Java.

Lớp trừu tượng có khả năng kế thừa từ một lớp khác, tuy nhiên lớp cha cũng cần phải là một lớp trừu tượng Ví dụ, chương trình dưới đây khai báo một lớp trừu tượng có tên là động vật (Animal) theo cách tổng quát.

Khai báo phương thức của lớp trừu tượng

Tất cả các thuộc tính và phương thức trong lớp trừu tượng cần được khai báo là trừu tượng Hơn nữa, các phương thức của lớp này chỉ được định nghĩa dưới dạng khuôn mẫu mà không có phần triển khai chi tiết.

Cú pháp khai báo phương thức của lớp trừu tượng:

[public] abstract ([]) [throws ];

Tính chất của thuộc tính hoặc phương thức trong lớp trừu tượng luôn được định nghĩa là public Nếu không được khai báo một cách rõ ràng, giá trị mặc định của chúng cũng sẽ là public.

 Kiểu dữ liệu trả về: có thể là các kiểu cơ bản của Java, cũng có thể là kiểu do người dùng tự định nghĩa (kiểu đối tượng).

 Tên phương thức: tuân thủ theo quy tắc đặt tên phương thức của lớp

Các tham số, nếu tồn tại, được định nghĩa thông qua cặp Các tham số này được phân tách bằng dấu phẩy.

 Các ngoại lệ: nếu có thì mỗi ngoại lệ được phân cách nhau bởi dấu phẩy.

Phương thức trừu tượng không thể được khai báo là private hoặc static, vì chúng chỉ có thể được nạp chồng trong các lớp kế thừa Nếu phương thức được định nghĩa là private, nó sẽ không thể nạp chồng, và nếu là static, nó sẽ không thể thay đổi trong lớp dẫn xuất.

 Phương thức trừu tượng chỉ được khai báo dưới dạng khuôn mẫu nên không có phần dấu móc “{}” mà kết thúc bằng dấu chấm phẩy “;”.

Chương trình mô tả hai phương thức của lớp trừu tượng Animal: phương thức getName() trả về tên loài động vật dưới dạng String và phương thức getFeet() trả về số chân của loài động vật dưới dạng int.

Sử dụng lớp trừu tượng

Lớp trừu tượng chỉ có thể được sử dụng thông qua các lớp dẫn xuất của nó, vì chỉ các lớp dẫn xuất này mới thực hiện cụ thể các phương thức đã được khai báo trong lớp trừu tượng.

Chương trình lớp Bird kế thừa từ lớp Animal, cài đặt hai phương thức getName() và getFeet() Phương thức getName() trả về tên loài "Bird", trong khi phương thức getFeet() trả về số chân của loài chim là 2.

// Trả về tên loài chim public String getName()

// Trả về số chân của loài chim public int getFeet()

Chúng ta xây dựng lớp mèo (Cat) kế thừa từ lớp động vật (Animal) Lớp mèo cài đặt chi tiết hai phương thức từ lớp động vật: phương thức getName() trả về tên loài là “Cat” và phương thức getFeet() trả về số chân của mèo là 4.

// Trả về tên loài mèo public String getName()

// Trả về số chân của loài mèo public int getFeet()

Cuối cùng xây dựng lớp sử dụng lại hai lớp Bird và Cat trong các chương trình trên

Ví dụ 3.20: public class AnimalDemo

{ public static void main(String args[])

System.out.println(“The ” + myBird.getName() + “ has ”+ myBird.getFeet() +

“ feets”); Cat myCat = new Cat();

System.out.println(“The ” + myCat.getName() +“ has ”+ myCat.getFeet() + “ feets”); }}

Lớp Object

Tất cả các lớp trong Java đều kế thừa từ lớp Object, tức là lớp Object là lớp cha của mọi lớp Điều này cho phép sử dụng biến kiểu Object để tham chiếu đến các đối tượng thuộc bất kỳ kiểu nào trong ngôn ngữ lập trình này.

Object obj = new Employee("Harry Hacker", 35000);

Tất cả các kiểu mảng bất kế là mảng nguyên thủy hay mảng đối tượng đều kế thừa từ lớp Object

Employee [ ] staff = new Employee[ ]; obj= staff; obj= new int [10];

Phương thức equals trong lớp Object dùng để kiểm tra tính tương đương giữa hai đối tượng

public boolean equals(Object otherObject)

// Kiểm tra nếu các đối tượng là tương đương if (this == otherObject) return true; if (otherObject == null) return false;

// Nếu các lớp khác nhau chúng không thể bằng nhau if (getClass() != otherObject.getClass()) return false;

// Kiểm tra các trường có các giá trị giống nhau

72 return name.equals(other.name) && salary == other.salary && hireDay.equals(other.hireDay);

Một phương thức quan trọng trong lớp Object là toString ( ), trả về một chuỗi biểu diễn giá trị của đối tượng

Ví dụ 3.24: public String toString()

{ return "Employee[name=" + name + ",salary=" + salary + ",hireDay=" + hireDay+ "]";

Giao diện

Interface trong Java là một bản thiết kế cho lớp, chỉ chứa các phương thức trừu tượng, giúp đạt được tính trừu tượng hoàn toàn và hỗ trợ đa kế thừa Nó thể hiện mối quan hệ IS-A và không thể được khởi tạo như lớp trừu tượng.

Trong Java, một interface là tập hợp các phương thức trừu tượng mà không phải là một lớp Khi một lớp triển khai một interface, nó kế thừa các phương thức trừu tượng này Trong khi lớp mô tả các thuộc tính và hành vi của một đối tượng, interface lại định nghĩa các hành vi mà lớp đó cần phải triển khai.

Trừ khi một lớp triển khai interface là lớp trừu tượng abstract, còn lại tất cả các phương thức của interface cần được định nghĩa trong class.

Một interface tương tự với một class bởi những điểm sau đây:

 Một interface có thể bao gồm bất cứphương thức nào.

 Một interface được viết trong một file với định dạng java, với tên của interface cùng với tên của file.

 Bytecode của interface xuất hiện trong một class file.

 Interface xuất hiện trong package, những bytecode file tương ứng phải ở trong cấu trúc thư mục có cùng tên package.

Mặc dù vây, một interface khác với một class ở một số điểm sau đây, bao gồm:

 Không thể khởi tạo một interface.

 Một interface không chứa bất cứ hàm contructor nào.

 Tất cả các phương thức của interface đều là abstract.

 Một interface không thể chứa một trường nào trừ các trường vừa static và final

 Một interface không thể kế thừa từ lớp, nó được triển khai bởi một lớp.

 Một interface có thể kế thừa từ nhiều interface khác.

Ví dụ 3.25: Tạo Printable Interface có phương thức print (), sau đó khai báo lớp triển khai interface vừa tạo. interface printable{ void print();

} class A6 implements printable{ public void print(){System.out.println("Hello");} public static void main(String args[]){

3.6.2 Mục đích sử dụng giao diện

Trong nhiều trường hợp, việc sử dụng Interface là cần thiết để các nhóm phát triển khác nhau đạt được sự đồng thuận về một "hợp đồng", từ đó xác định cách thức phần mềm của họ sẽ tương tác với nhau.

 Mỗi nhóm nên có cách viết code theo cách riêng mà không cần biết cách các nhóm khác làm thế nào

 Các interface trong java có thể được sử dụng để xác định các contracts.

 Interface không thuộc bất kỳ lớp nào cho dù chúng làm việc kết hợp với các lớp khác.

 Java không cho phép đa kếthừa trong nhưng interface hỗ trợ điều đó

 Trong Java, một class có thể kế thừa từ chỉ một class nhưng nó có thể implement nhiều interfaces.

3.6.3 So sánh giao diện và lớp trừu tượng

Cả lớp trừu tượng và Interface đều được sử dụng để đạt được tính trừu tượng và cho phép khai báo các phương thức trừu tượng, nhưng chúng không thể được khởi tạo Tuy nhiên, giữa lớp trừu tượng và Interface tồn tại những điểm khác biệt quan trọng.

Lớp trừu tượng có thể có các phương thức abstract và non-abstract

Interface chỉ có thể có phương thức abstract

Lớp trừu tượng không hỗ trợđa kế thừa Interface hỗ trợđa kế thừa

Lớp trừu tượng có thể có các biến final, non- final, static và non-static

Interface chỉ có các biến static và final

Lớp trừu tượng có thểcó phương thức static, phương thức main và constructor

Interface không thể có phương thức static, main hoặc constructor

Từ khóa abstract được sử dụng để khai báo lớp trừu tượng

Từ khóa interface được sử dụng để khai báo Interface

Lớp trừu tượng có thể cung cấp trình triển khai của Interface

Interface không cung cấp trình triển khai cụ thể của lớp abstract

Ví dụ: public abstract class Shape{ public abstract void draw(); }

Ví dụ: public interface Drawable{ void draw(); }

Lớp nội

Java cho phép định nghĩa một lớp nằm trong một lớp khác, những lớp như vậy được gọi là lớplồng nhau (nested class)

Lớp Outer định nghĩa cấu trúc bên ngoài, trong khi lớp Nested (lồng) định nghĩa bên trong lớp Outer Lớp lồng được chia thành hai loại chính: lớp lồng tĩnh (static) và lớp nội (no-static).

Lớp nội liên kết với đối tượng của lớp bao bọc và có khả năng truy cập các phương thức và thuộc tính, bao gồm cả các thành phần khai báo private Để tạo một đối tượng lớp nội, trước tiên cần khởi tạo lớp ngoài, sau đó sử dụng cú pháp phù hợp để tạo đối tượng lớp nội.

OuterClass.InnerClass innerObject = outerObject.new InnerClass();

Lớp lồng static-tĩnh được liên kết với đối tượng trong lớp bao bọc, nhưng không cho phép truy cập vào các thuộc tính và phương thức của đối tượng đó Để truy xuất lớp lồng static, bạn chỉ cần thêm dấu chấm và tên lớp.

Lợi ích của việc sử dụng lớp nội: Gom nhóm các lớp có chung mục đích lại với nhau

 Tăng tính dễ đọc và dễ bảo trì cho code

Một lớp non-static được tạo ra bên trong một lớp nhưng ngoài một phương thức được gọi là lớp nội thành viên member inner class trong java

Ví dụ 3.26: class MemberOuterExample { private int data = 30; class Inner { void msg() {

System.out.println("data is " + data);

} public static void main(String args[]) {

MemberOuterExample.Inner in = obj.new Inner(); in.msg();

Lớp nội nặc danh (anonymous inner class) là một loại lớp không có tên, được sử dụng để ghi đè phương thức của lớp hoặc interface Có hai cách để tạo ra lớp nội nặc danh.

 Class: có thể là abstract class hoặc class cụ thể.

 Interface abstract class Person { abstract void eat();

} class TestAnonymousInner { public static void main(String args[]) {

Person p = new Person() { void eat() {

System.out.println("nice fruits");

A local inner class is defined within a method, allowing it to access the method's variables and parameters To invoke the methods of this inner class, an instance of the local class must be created within the containing method For example, in the public class `localInner1`, an instance variable `data` is defined, and a local class named `Local` contains a method `msg()` that can utilize this variable.

77 public static void main(String args[]) { localInner1 obj = new localInner1(); obj.display();

Xử lý ngoại lệ

Exception là lỗi đặc biệt xảy ra trong quá trình thực thi chương trình, thường do các trạng thái không bình thường Nếu không được xử lý, các exception có thể dẫn đến việc chương trình bị kết thúc đột ngột, như trường hợp chia cho 0 Ngôn ngữ lập trình Java cung cấp cơ chế xử lý ngoại lệ hiệu quả, giúp hạn chế tối đa tình trạng hệ thống bị hỏng hay ngắt đột ngột Tính năng này góp phần làm cho Java trở thành một ngôn ngữ lập trình mạnh mẽ.

3.8.2 Mục đích của việc xử lý ngoại lệ

Một chương trình cần có cơ chế xử lý ngoại lệ để tránh bị ngắt khi xảy ra lỗi Nếu không có cơ chế này, các nguồn tài nguyên do hệ thống cấp sẽ không được giải phóng, dẫn đến lãng phí Do đó, việc thu hồi tất cả các nguồn tài nguyên là rất quan trọng để đảm bảo hiệu quả sử dụng và tránh tình trạng lãng phí.

Lớp Exception và các lớp con của nó là một dạng Throwable chỉ ra các điều kiện mà một ứng dụng có thể muốn nắm bắt.

Lớp Exception dùng để kiểm tra ngoại lệ Đoạn code sau đây sẽ thể hiện cấu trúc của một lớp Exception.

Khi một ngoại lệ xảy ra, một đối tượng tương ứng sẽ được tạo ra và truyền đến phương thức nơi ngoại lệ xuất hiện Đối tượng này chứa thông tin chi tiết về ngoại lệ, giúp lập trình viên hiểu rõ nguyên nhân và xử lý sự cố hiệu quả.

Thông tin này có thể nhận và xử lý Lớp 'Throwable' là lớp cha của lớp Exception, đồng thời cũng là lớp cha của tất cả các ngoại lệ khác.

3.8.5 Mô hình xử lý ngoại lệ

Mô hình xử lý ngoại lệ trong Java, được gọi là 'catch and throw', cho phép chương trình chặn ngoại lệ khi xảy ra và chuyển đến khối xử lý ngoại lệ Lập trình viên cần phải xử lý các ngoại lệ phát sinh trong chương trình, hoặc lựa chọn thoát khỏi chương trình khi ngoại lệ xảy ra.

Dưới đây là cấu trúc của mô hình xử lý ngoại lệ: try

// đoạn mã có khả năng gây ra ngoại lệ

// Nếu các lệnh trong khối ‘try’ tạo ra ngoại lệ có loại e1, thì thực hiện //xử lý ngoại lệ nếu không chuyển xuống khối 'catch' tiếp theo

// Nếu các lệnh trong khối ‘try’ tạo ra ngoại lệ có loại e2, thì thực hiện //xử lý ngoại lệ nếu không chuyển xuống khối 'catch' tiếp theo

// Nếu các lệnh trong khối ‘try’ tạo ra ngoại lệ có loại eN, thì thực hiện //xử lý ngoại lệ nếu không chuyển xuống khối 'catch' tiếp theo

// khối lệnh nay luôn được thực hiện cho dù ngoại lệ có xảy ra hay không }

3.8.5.1 Các ưu điểm của mô hình ‘catch và throw’

Mô hình ‘catch và throw’ có hai ưu điểm:

 Người lập trình chỉ phải xử lý ngoại lệ khi cần thiết Không cần phải thực hiện tại mọi mức.

 Thông báo lỗi có thể được hiện ra khi tiến hành xử lý ngoại lệ.

3.8.5.2 Các khối ‘try’ và ‘catch’

Khối 'try-catch' thực hiện mô hình 'catch và throw' để xử lý ngoại lệ trong lập trình Sau khối 'try', có thể có một hoặc nhiều khối 'catch' nhằm bắt các ngoại lệ có thể xảy ra trong khối 'try'.

{ doFileProcessing(); // phương thức do người sử dụng định nghĩa displayResults();

} catch (Exeption e) // thể hiện của ngoại lệ

System.err.println(“Error :” + e.toString()); e.printStackTrace();

Đối tượng 'e' thuộc lớp 'Exception' cho phép chúng ta in ra các thông tin chi tiết về ngoại lệ Các phương thức 'toString' và 'printStackTrace' được sử dụng để mô tả các ngoại lệ xảy ra, như minh họa trong hình dưới đây.

Để xử lý ngoại lệ trong lập trình, chúng ta sử dụng khối Try và Catch, trong đó cần chỉ định kiểu ngoại lệ cụ thể bằng cách sử dụng catch(Exception e) Nếu không xác định được kiểu ngoại lệ, lớp 'Exception' có thể được sử dụng để bắt mọi loại ngoại lệ.

3.8.6 Các khối chứa nhiều Catch

Nhiều khối ‘catch’ xử lý các loại ngoại lệ khác nhau một cách độc lập Chúng được liệt kê trong đoạn mã sau: try

80 displayResults(); } catch(LookupException e) // e – LookupException object

{ handleLookupException(e); // phương thức xử lý lỗi do người sử dụng //định nghĩa

System.err.println(“Error:” + e.printStackTrace());

Trong trường hợp này, khối ‘catch’ đầu tiên sẽ bắt giữ một ‘LockupException’ Khối

‘catch’ thứ hai sẽ xử lý kiểu ngoại lệ khác với khối ‘catch’ thứ nhất.

Một chương trình cũng có thể chứa các khối ‘try’ lồng nhau Ví dụ đoạn mã dưới đây: try{ statement 1; statement 2; try{ statement1; statement2;

}catch(Exception e) { // của khối try trong

}catch(Exception e) { // của khối try ngoài

Khi sử dụng các khối 'try' lồng nhau, khối 'try' bên trong sẽ được thực thi trước Nếu có ngoại lệ xảy ra trong khối 'try' này, nó sẽ được xử lý bởi các khối 'catch' tương ứng Nếu không tìm thấy khối 'catch' phù hợp, các khối 'catch' của khối 'try' bên ngoài sẽ được xem xét Nếu vẫn không có khối 'catch' nào phù hợp, Java Runtime Environment sẽ đảm nhận việc xử lý các ngoại lệ.

Ví dụ 3.27: Chương trình sau minh họa cách sử dụng các khối ‘try’ và ‘catch’ class TryClass{ public static void main(String args[]){ int demo=0; try{

System.out.println(“Cannot Divide by zero”);

Kết xuất của chương trình:

Trong chương trình này, việc chia cho 0 không phải là phép toán hợp lệ, dẫn đến việc phát sinh ngoại lệ Ngoại lệ này được xử lý trong khối catch, nơi chúng ta xác định loại ngoại lệ có thể xảy ra Tại đây, đối tượng 'a' của ArithmeticException được sử dụng để in ra các thông tin chi tiết về ngoại lệ.

Nếu thay thế lệnh ‘System.out.println’ của khối ‘catch’ bằng “System.out.println (a.getMessage())” thì kết xuất của chương trình như sau:

Khi các khối 'try' được sử dụng mà không có khối 'catch', chương trình sẽ biên dịch thành công nhưng sẽ gặp lỗi và ngắt khi thực thi Điều này xảy ra do ngoại lệ không được xử lý trong quá trình thực hiện chương trình.

Khối 'finally' thực hiện việc thu dọn tài nguyên khi có ngoại lệ xảy ra, thường được kết hợp với khối 'try' Trong khối 'finally', các câu lệnh thu hồi tài nguyên hoặc thông báo sẽ được thực hiện, đảm bảo rằng mọi tài nguyên được giải phóng đúng cách.

 Đóng ResultSet (được sử dụng trong chương trình cơ sở dữ liệu).

 Đóng lại các kết nối được tạo trong cơ sở dữ liệu. try{ doSomethingThatMightThrowAnException();

Phương thức ‘cleanup()’ được thực hiện khi ‘doSomethingThatMightThrowAnException()’ gặp phải ngoại lệ, đồng thời cũng được gọi khi không có ngoại lệ xảy ra, tiếp tục thực hiện các lệnh trong khối ‘finally’.

Khối 'finally' là tùy chọn và không bắt buộc, thường được đặt sau khối 'catch' cuối cùng Chương trình sẽ thực hiện câu lệnh đầu tiên trong khối 'finally' ngay sau khi gặp lệnh.

‘return’ hay lệnh ‘break’ trong khối ‘try’ Khối ‘finally’ bảo đảm lúc nào cũng được thực thi, bất chấp có ngoại lệ xảy ra hay không.

FinallyDemo(String args[]){ try{ name=new String(“Aptech Limited”);

System.out.println(“Division Result is” + no1/no2);

System.out.println(“Cannot Divide by zero”);

}finally{ name=null; // clean up code System.out.println(“Finally executed”);

} } public static void main(String args[]{ new FinallyDemo(args);

Kết xuất của chương trình:

3.8.8 Các ngoại lệ được định nghĩa với lệnh ‘throw’ và ‘throws’

Các ngoại lệ có thể được tạo ra bằng từ khóa 'throw', trong đó toán hạng của 'throw' là một đối tượng thuộc lớp kế thừa từ 'Throwable' Ví dụ, trong đoạn lệnh sau, nếu biến 'flag' nhỏ hơn 0, một ngoại lệ do người dùng định nghĩa sẽ được ném ra: `try{ if (flag

Ngày đăng: 28/12/2021, 19:16

HÌNH ẢNH LIÊN QUAN

Hình  1.3.  Màn hình soạ n th ả o - Giáo trình Công nghệ Java  ĐH Kinh Tế Kỹ Thuật Công Nghiệp
nh 1.3. Màn hình soạ n th ả o (Trang 17)
Hình  1. 2. V ị trí lưu project - Giáo trình Công nghệ Java  ĐH Kinh Tế Kỹ Thuật Công Nghiệp
nh 1. 2. V ị trí lưu project (Trang 17)
Hình  2. 1. Chuy ển đổ i gi ữa các kiể u d ữ  li ệu cơ sở - Giáo trình Công nghệ Java  ĐH Kinh Tế Kỹ Thuật Công Nghiệp
nh 2. 1. Chuy ển đổ i gi ữa các kiể u d ữ li ệu cơ sở (Trang 21)
Hình  3.1. C ấu trúc phân cấ p theo quan h ệ  k ế  th ừ a c ủa các giao diện lõi - Giáo trình Công nghệ Java  ĐH Kinh Tế Kỹ Thuật Công Nghiệp
nh 3.1. C ấu trúc phân cấ p theo quan h ệ k ế th ừ a c ủa các giao diện lõi (Trang 92)
Hình  3.2.  Các giao diện lõi và các lớp cài đặt chúng - Giáo trình Công nghệ Java  ĐH Kinh Tế Kỹ Thuật Công Nghiệp
nh 3.2. Các giao diện lõi và các lớp cài đặt chúng (Trang 93)
Hình 3.3. Các trạng thái củ a Thread - Giáo trình Công nghệ Java  ĐH Kinh Tế Kỹ Thuật Công Nghiệp
Hình 3.3. Các trạng thái củ a Thread (Trang 94)
Hình dưới đây cho  th ấy cái nhìn nhìn tổ ng quan v ề  c ấu trúc theo thứ  b ậ c c ủa các lớ p  trong Java Swing - Giáo trình Công nghệ Java  ĐH Kinh Tế Kỹ Thuật Công Nghiệp
Hình d ưới đây cho th ấy cái nhìn nhìn tổ ng quan v ề c ấu trúc theo thứ b ậ c c ủa các lớ p trong Java Swing (Trang 111)
Hình 4.3.  JSlider - Giáo trình Công nghệ Java  ĐH Kinh Tế Kỹ Thuật Công Nghiệp
Hình 4.3. JSlider (Trang 123)
Hình  6.1. Ki ến trúc JDBC - Giáo trình Công nghệ Java  ĐH Kinh Tế Kỹ Thuật Công Nghiệp
nh 6.1. Ki ến trúc JDBC (Trang 163)
Hình  6.4. Trình điề u khi ể n JDBC-Net  Driver - Giáo trình Công nghệ Java  ĐH Kinh Tế Kỹ Thuật Công Nghiệp
nh 6.4. Trình điề u khi ể n JDBC-Net Driver (Trang 165)
Hình 6.3. Trình điề u khi ể n Native API Driver - Giáo trình Công nghệ Java  ĐH Kinh Tế Kỹ Thuật Công Nghiệp
Hình 6.3. Trình điề u khi ể n Native API Driver (Trang 165)
Bảng Products được tạo như sau : - Giáo trình Công nghệ Java  ĐH Kinh Tế Kỹ Thuật Công Nghiệp
ng Products được tạo như sau : (Trang 168)
Hình  7.1.  Lớp kế thừa từ lớp InetAddress và SocketAddress - Giáo trình Công nghệ Java  ĐH Kinh Tế Kỹ Thuật Công Nghiệp
nh 7.1. Lớp kế thừa từ lớp InetAddress và SocketAddress (Trang 184)
Hình  7.2.  Quá trình khởi tạo truyền thông với TCPSocket 7.3.2.1.  Chương trình phía server: - Giáo trình Công nghệ Java  ĐH Kinh Tế Kỹ Thuật Công Nghiệp
nh 7.2. Quá trình khởi tạo truyền thông với TCPSocket 7.3.2.1. Chương trình phía server: (Trang 194)

TÀI LIỆU CÙNG NGƯỜI DÙNG

TÀI LIỆU LIÊN QUAN

w