Java - Hướng dẫn nhanh

Ngôn ngữ lập trình Java ban đầu được phát triển bởi Sun Microsystems, do James Gosling khởi xướng và phát hành vào năm 1995 như là thành phần cốt lõi của nền tảng Java của Sun Microsystems (Java 1.0 [J2SE]).

Phiên bản mới nhất của Java Standard Edition là Java SE 8. Với sự tiến bộ của Java và sự phổ biến rộng rãi của nó, nhiều cấu hình đã được xây dựng để phù hợp với nhiều loại nền tảng khác nhau. Ví dụ: J2EE cho Ứng dụng Doanh nghiệp, J2ME cho Ứng dụng Di động.

Các phiên bản J2 mới lần lượt được đổi tên thành Java SE, Java EE và Java ME. Java được đảm bảoWrite Once, Run Anywhere.

Java là -

  • Object Oriented- Trong Java, mọi thứ đều là một Đối tượng. Java có thể dễ dàng mở rộng vì nó dựa trên mô hình Đối tượng.

  • Platform Independent- Không giống như nhiều ngôn ngữ lập trình khác bao gồm C và C ++, khi Java được biên dịch, nó không được biên dịch vào máy cụ thể của nền tảng, mà là mã byte độc ​​lập với nền tảng. Mã byte này được phân phối trên web và được Máy ảo (JVM) phiên dịch trên bất kỳ nền tảng nào mà nó đang được chạy.

  • Simple- Java được thiết kế để dễ học. Nếu bạn hiểu khái niệm cơ bản về OOP Java, bạn sẽ dễ dàng thành thạo.

  • Secure- Với tính năng bảo mật của Java, nó cho phép phát triển các hệ thống không có vi rút, không có giả mạo. Các kỹ thuật xác thực dựa trên mã hóa khóa công khai.

  • Architecture-neutral - Trình biên dịch Java tạo ra một định dạng tệp đối tượng trung lập về kiến ​​trúc, làm cho mã đã biên dịch có thể thực thi được trên nhiều bộ xử lý, với sự hiện diện của hệ thống thời gian chạy Java.

  • Portable- Không có kiến ​​trúc trung lập và không có các khía cạnh phụ thuộc vào việc triển khai của đặc tả làm cho Java trở nên linh hoạt. Trình biên dịch trong Java được viết bằng ANSI C với ranh giới khả năng di chuyển rõ ràng, là một tập con POSIX.

  • Robust - Java cố gắng loại bỏ các tình huống dễ xảy ra lỗi bằng cách nhấn mạnh chủ yếu vào kiểm tra lỗi thời gian biên dịch và kiểm tra thời gian chạy.

  • Multithreaded- Với tính năng đa luồng của Java có thể viết chương trình thực hiện nhiều tác vụ đồng thời. Tính năng thiết kế này cho phép các nhà phát triển xây dựng các ứng dụng tương tác có thể chạy trơn tru.

  • Interpreted- Mã byte Java được dịch nhanh chóng sang hướng dẫn máy bản địa và không được lưu trữ ở bất kỳ đâu. Quá trình phát triển nhanh hơn và mang tính phân tích cao hơn vì liên kết là một quá trình gia tăng và nhẹ hơn.

  • High Performance - Với việc sử dụng trình biên dịch Just-In-Time, Java cho phép hiệu suất cao.

  • Distributed - Java được thiết kế cho môi trường phân tán của internet.

  • Dynamic- Java được coi là năng động hơn C hoặc C ++ vì nó được thiết kế để thích ứng với môi trường đang phát triển. Các chương trình Java có thể mang một lượng lớn thông tin về thời gian chạy có thể được sử dụng để xác minh và giải quyết quyền truy cập vào các đối tượng trong thời gian chạy.

Lịch sử của Java

James Gosling đã khởi xướng dự án ngôn ngữ Java vào tháng 6 năm 1991 để sử dụng cho một trong nhiều dự án set-top box của mình. Ngôn ngữ, ban đầu được gọi là 'Oak' theo tên một cây sồi nằm bên ngoài văn phòng của Gosling, cũng có tên là 'Green' và cuối cùng sau đó được đổi tên thành Java, từ một danh sách các từ ngẫu nhiên.

Sun phát hành bản triển khai công khai đầu tiên dưới dạng Java 1.0 vào năm 1995. Nó hứa hẹn Write Once, Run Anywhere (WORA), cung cấp thời gian chạy miễn phí trên các nền tảng phổ biến.

Vào ngày 13 tháng 11 năm 2006, Sun đã phát hành phần lớn Java dưới dạng phần mềm mã nguồn mở và miễn phí theo các điều khoản của Giấy phép Công cộng GNU (GPL).

Vào ngày 8 tháng 5 năm 2007, Sun đã hoàn thành quá trình, biến tất cả mã lõi của Java trở nên miễn phí và là mã nguồn mở, ngoại trừ một phần nhỏ mã mà Sun không giữ bản quyền.

Công cụ bạn sẽ cần

Để thực hiện các ví dụ được thảo luận trong hướng dẫn này, bạn sẽ cần một máy tính Pentium 200-MHz với RAM tối thiểu 64 MB (khuyến nghị 128 MB RAM).

Bạn cũng sẽ cần các phần mềm sau:

  • Hệ điều hành Linux 7.1 hoặc Windows xp / 7/8
  • Java JDK 8
  • Microsoft Notepad hoặc bất kỳ trình soạn thảo văn bản nào khác

Hướng dẫn này sẽ cung cấp các kỹ năng cần thiết để tạo GUI, mạng và ứng dụng web bằng Java.

Tiếp theo là gì?

Chương tiếp theo sẽ hướng dẫn bạn cách bạn có thể lấy được Java và tài liệu của nó. Cuối cùng, nó hướng dẫn bạn cách cài đặt Java và chuẩn bị môi trường để phát triển các ứng dụng Java.

Trong chương này, chúng ta sẽ thảo luận về các khía cạnh khác nhau của việc thiết lập một môi trường tương thích cho Java.

Thiết lập môi trường cục bộ

Nếu bạn vẫn sẵn sàng thiết lập môi trường của mình cho ngôn ngữ lập trình Java, thì phần này sẽ hướng dẫn bạn cách tải xuống và thiết lập Java trên máy của bạn. Sau đây là các bước để thiết lập môi trường.

Java SE có sẵn miễn phí từ liên kết Tải xuống Java . Bạn có thể tải xuống phiên bản dựa trên hệ điều hành của mình.

Làm theo hướng dẫn để tải xuống Java và chạy .exeđể cài đặt Java trên máy của bạn. Khi bạn đã cài đặt Java trên máy của mình, bạn sẽ cần đặt các biến môi trường để trỏ đến các thư mục cài đặt chính xác -

Thiết lập đường dẫn cho Windows

Giả sử bạn đã cài đặt Java trong thư mục c: \ Program Files \ java \ jdk -

  • Nhấp chuột phải vào 'Máy tính của tôi' và chọn 'Thuộc tính'.

  • Nhấp vào nút 'Biến môi trường' trong tab 'Nâng cao'.

  • Bây giờ, hãy thay đổi biến 'Đường dẫn' để nó cũng chứa đường dẫn đến tệp thực thi Java. Ví dụ, nếu đường dẫn hiện được đặt thành 'C: \ WINDOWS \ SYSTEM32', thì hãy thay đổi đường dẫn của bạn thành 'C: \ WINDOWS \ SYSTEM32; c: \ Program Files \ java \ jdk \ bin'.

Thiết lập đường dẫn cho Linux, UNIX, Solaris, FreeBSD

Biến môi trường PATH nên được đặt để trỏ đến nơi các tệp nhị phân Java đã được cài đặt. Tham khảo tài liệu shell của bạn, nếu bạn gặp khó khăn khi thực hiện việc này.

Ví dụ, nếu bạn sử dụng bash làm trình bao, thì bạn sẽ thêm dòng sau vào cuối '.bashrc: export PATH = / path / to / java: $ PATH'

Trình chỉnh sửa Java phổ biến

Để viết các chương trình Java của bạn, bạn sẽ cần một trình soạn thảo văn bản. Thậm chí có nhiều IDE phức tạp hơn có sẵn trên thị trường. Nhưng hiện tại, bạn có thể xem xét một trong những điều sau:

  • Notepad - Trên máy Windows, bạn có thể sử dụng bất kỳ trình soạn thảo văn bản đơn giản nào như Notepad (Khuyến nghị cho hướng dẫn này), TextPad.

  • Netbeans - Một IDE Java là mã nguồn mở và miễn phí có thể được tải xuống từ https://www.netbeans.org/index.html.

  • Eclipse - Một IDE Java được phát triển bởi cộng đồng nguồn mở eclipse và có thể được tải xuống từ https://www.eclipse.org/.

Tiếp theo là gì?

Chương tiếp theo sẽ hướng dẫn bạn cách viết và chạy chương trình Java đầu tiên của bạn và một số cú pháp cơ bản quan trọng trong Java cần thiết để phát triển ứng dụng.

Khi chúng ta xem xét một chương trình Java, nó có thể được định nghĩa là một tập hợp các đối tượng giao tiếp thông qua việc gọi các phương thức của nhau. Bây giờ chúng ta hãy xem xét ngắn gọn ý nghĩa của các biến class, object, method và instance.

  • Object- Đối tượng có trạng thái và hành vi. Ví dụ: Một con chó có các trạng thái - màu sắc, tên, giống cũng như các hành vi như vẫy đuôi, sủa, ăn. Một đối tượng là một thể hiện của một lớp.

  • Class - Một lớp có thể được định nghĩa như một khuôn mẫu / bản thiết kế mô tả hành vi / trạng thái mà đối tượng thuộc kiểu của nó hỗ trợ.

  • Methods- Một phương pháp về cơ bản là một hành vi. Một lớp có thể chứa nhiều phương thức. Nó nằm trong các phương thức nơi logic được viết, dữ liệu được thao tác và tất cả các hành động được thực thi.

  • Instance Variables- Mỗi đối tượng có tập hợp các biến thể hiện duy nhất của nó. Trạng thái của một đối tượng được tạo bởi các giá trị được gán cho các biến thể hiện này.

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

Chúng ta hãy xem một đoạn mã đơn giản sẽ in ra các từ Hello World.

Thí dụ

public class MyFirstJavaProgram {

   /* This is my first java program.
    * This will print 'Hello World' as the output
    */

   public static void main(String []args) {
      System.out.println("Hello World"); // prints Hello World
   }
}

Hãy xem cách lưu tệp, biên dịch và chạy chương trình. Vui lòng làm theo các bước tiếp theo -

  • Mở notepad và thêm mã như trên.

  • Lưu tệp dưới dạng: MyFirstJavaProgram.java.

  • Mở cửa sổ nhắc lệnh và đi tới thư mục bạn đã lưu lớp. Giả sử đó là C: \.

  • Nhập 'javac MyFirstJavaProgram.java' và nhấn enter để biên dịch mã của bạn. Nếu không có lỗi nào trong mã của bạn, dấu nhắc lệnh sẽ đưa bạn đến dòng tiếp theo (Giả định: Biến đường dẫn được đặt).

  • Bây giờ, gõ 'java MyFirstJavaProgram' để chạy chương trình của bạn.

  • Bạn sẽ có thể thấy 'Hello World' được in trên cửa sổ.

Đầu ra

C:\> javac MyFirstJavaProgram.java
C:\> java MyFirstJavaProgram 
Hello World

Cú pháp cơ bản

Về các chương trình Java, bạn cần lưu ý những điểm sau.

  • Case Sensitivity - Java phân biệt chữ hoa chữ thường, có nghĩa là mã định danh Hellohello sẽ có ý nghĩa khác trong Java.

  • Class Names- Đối với tất cả các tên lớp, chữ cái đầu tiên phải là chữ hoa. Nếu một số từ được sử dụng để tạo thành tên của lớp, thì mỗi chữ cái đầu tiên của từ bên trong phải ở dạng Chữ hoa.

    Example: lớp MyFirstJavaClass

  • Method Names- Tất cả các tên phương thức phải bắt đầu bằng chữ thường. Nếu một số từ được sử dụng để tạo thành tên của phương thức, thì chữ cái đầu tiên của mỗi từ bên trong phải ở dạng Chữ hoa.

    Example: public void myMethodName ()

  • Program File Name - Tên tệp chương trình phải khớp chính xác với tên lớp.

    Khi lưu tệp, bạn nên lưu bằng tên lớp (Hãy nhớ Java phân biệt chữ hoa chữ thường) và thêm '.java' vào cuối tên (nếu tên tệp và tên lớp không khớp, chương trình của bạn sẽ không biên dịch ).

    Example:Giả sử 'MyFirstJavaProgram' là tên lớp. Sau đó, tệp sẽ được lưu dưới dạng 'MyFirstJavaProgram.java'

  • public static void main(String args[]) - Quá trình xử lý chương trình Java bắt đầu từ phương thức main () là một phần bắt buộc của mọi chương trình Java.

Số nhận dạng Java

Tất cả các thành phần Java đều yêu cầu tên. Tên được sử dụng cho các lớp, biến và phương thức được gọi làidentifiers.

Trong Java, có một số điểm cần nhớ về số nhận dạng. Chúng như sau:

  • Tất cả các số nhận dạng phải bắt đầu bằng chữ cái (A đến Z hoặc a đến z), ký tự tiền tệ ($) hoặc dấu gạch dưới (_).

  • Sau ký tự đầu tiên, số nhận dạng có thể có bất kỳ tổ hợp ký tự nào.

  • Một từ khóa không thể được sử dụng làm định danh.

  • Quan trọng nhất, số nhận dạng có phân biệt chữ hoa chữ thường.

  • Ví dụ về giá trị nhận dạng hợp pháp: tuổi, $ lương, _value, __1_value.

  • Ví dụ về số nhận dạng bất hợp pháp: 123abc, -salary.

Công cụ sửa đổi Java

Giống như các ngôn ngữ khác, có thể sửa đổi các lớp, phương thức, v.v., bằng cách sử dụng các bổ ngữ. Có hai loại bổ ngữ -

  • Access Modifiers - mặc định, công khai, được bảo vệ, riêng tư

  • Non-access Modifiers - cuối cùng, trừu tượng, nghiêm ngặt

Chúng tôi sẽ xem xét chi tiết hơn về các bổ ngữ trong phần tiếp theo.

Các biến Java

Sau đây là các loại biến trong Java:

  • Biến cục bộ
  • Biến lớp (Biến tĩnh)
  • Biến phiên bản (Biến không tĩnh)

Mảng Java

Mảng là các đối tượng lưu trữ nhiều biến cùng kiểu. Tuy nhiên, bản thân một mảng là một đối tượng trên heap. Chúng ta sẽ xem xét cách khai báo, xây dựng và khởi tạo trong các chương sắp tới.

Java Enums

Enums đã được giới thiệu trong Java 5.0. Enums hạn chế một biến chỉ có một trong một vài giá trị được xác định trước. Các giá trị trong danh sách liệt kê này được gọi là enums.

Với việc sử dụng enum, có thể giảm số lượng lỗi trong mã của bạn.

Ví dụ: nếu chúng tôi xem xét ứng dụng cho một cửa hàng nước trái cây tươi, có thể giới hạn kích thước ly ở mức nhỏ, vừa và lớn. Điều này sẽ đảm bảo rằng nó sẽ không cho phép bất kỳ ai đặt hàng bất kỳ kích thước nào khác ngoài nhỏ, vừa hoặc lớn.

Thí dụ

class FreshJuice {
   enum FreshJuiceSize{ SMALL, MEDIUM, LARGE }
   FreshJuiceSize size;
}

public class FreshJuiceTest {

   public static void main(String args[]) {
      FreshJuice juice = new FreshJuice();
      juice.size = FreshJuice.FreshJuiceSize.MEDIUM ;
      System.out.println("Size: " + juice.size);
   }
}

Ví dụ trên sẽ tạo ra kết quả sau:

Đầu ra

Size: MEDIUM

Note- Enums có thể được khai báo là của riêng chúng hoặc bên trong một lớp. Các phương thức, biến, hàm tạo cũng có thể được định nghĩa bên trong enum.

Từ khóa Java

Danh sách sau đây hiển thị các từ dành riêng trong Java. Những từ dành riêng này không được dùng làm hằng số hoặc biến hoặc bất kỳ tên định danh nào khác.

trừu tượng khẳng định boolean phá vỡ
byte trường hợp nắm lấy char
lớp học hăng sô tiếp tục mặc định
làm gấp đôi khác enum
kéo dài sau cùng cuối cùng Phao nổi
cho đi đến nếu dụng cụ
nhập khẩu ví dụ int giao diện
Dài tự nhiên Mới gói hàng
riêng tư được bảo vệ công cộng trở về
ngắn tĩnh nghiêm ngặt siêu
công tắc điện đồng bộ điều này phi
ném tạm thời thử vô hiệu
bay hơi trong khi

Nhận xét bằng Java

Java hỗ trợ chú thích một dòng và nhiều dòng rất giống với C và C ++. Tất cả các ký tự có sẵn bên trong bất kỳ bình luận nào đều bị trình biên dịch Java bỏ qua.

Thí dụ

public class MyFirstJavaProgram {

   /* This is my first java program.
    * This will print 'Hello World' as the output
    * This is an example of multi-line comments.
    */

   public static void main(String []args) {
      // This is an example of single line comment
      /* This is also an example of single line comment. */
      System.out.println("Hello World");
   }
}

Đầu ra

Hello World

Sử dụng dòng trống

Một dòng chỉ chứa khoảng trắng, có thể kèm theo chú thích, được gọi là dòng trống và Java hoàn toàn bỏ qua nó.

Di sản

Trong Java, các lớp có thể được dẫn xuất từ ​​các lớp. Về cơ bản, nếu bạn cần tạo một lớp mới và đây đã là một lớp có một số mã mà bạn yêu cầu, thì bạn có thể lấy lớp mới của mình từ mã đã có.

Khái niệm này cho phép bạn sử dụng lại các trường và phương thức của lớp hiện có mà không cần phải viết lại mã trong một lớp mới. Trong trường hợp này, lớp hiện có được gọi làsuperclass và lớp dẫn xuất được gọi là subclass.

Giao diện

Trong ngôn ngữ Java, một giao diện có thể được định nghĩa như một hợp đồng giữa các đối tượng về cách giao tiếp với nhau. Các giao diện đóng một vai trò quan trọng khi nói đến khái niệm kế thừa.

Một giao diện xác định các phương thức, một lớp dẫn xuất (lớp con) nên sử dụng. Nhưng việc triển khai các phương thức hoàn toàn phụ thuộc vào lớp con.

Tiếp theo là gì?

Phần tiếp theo giải thích về Đối tượng và các lớp trong lập trình Java. Vào cuối phiên, bạn sẽ có thể hình dung rõ ràng về các đối tượng là gì và các lớp là gì trong Java.

Java là một ngôn ngữ hướng đối tượng. Là một ngôn ngữ có tính năng Hướng đối tượng, Java hỗ trợ các khái niệm cơ bản sau:

  • Polymorphism
  • Inheritance
  • Encapsulation
  • Abstraction
  • Classes
  • Objects
  • Instance
  • Method
  • Thông qua

Trong chương này, chúng ta sẽ xem xét các khái niệm - Lớp và Đối tượng.

  • Object- Đối tượng có trạng thái và hành vi. Ví dụ: Một con chó có các trạng thái - màu sắc, tên, giống cũng như các hành vi - vẫy đuôi, sủa, ăn. Một đối tượng là một thể hiện của một lớp.

  • Class - Một lớp có thể được định nghĩa như một khuôn mẫu / bản thiết kế mô tả hành vi / trạng thái mà đối tượng thuộc kiểu của nó hỗ trợ.

Đối tượng trong Java

Bây giờ chúng ta hãy đi sâu tìm hiểu các đối tượng là gì. Nếu chúng ta xem xét thế giới thực, chúng ta có thể tìm thấy nhiều đối tượng xung quanh chúng ta, ô tô, con chó, con người, v.v. Tất cả những đối tượng này đều có trạng thái và hành vi.

Nếu chúng ta xem xét một con chó, thì trạng thái của nó là - tên, giống, màu sắc và hành vi là - sủa, vẫy đuôi, chạy.

Nếu bạn so sánh đối tượng phần mềm với một đối tượng trong thế giới thực, chúng có những đặc điểm rất giống nhau.

Các đối tượng phần mềm cũng có trạng thái và hành vi. Trạng thái của đối tượng phần mềm được lưu trữ trong các trường và hành vi được hiển thị qua các phương thức.

Vì vậy, trong phát triển phần mềm, các phương thức hoạt động trên trạng thái bên trong của một đối tượng và giao tiếp giữa đối tượng với đối tượng được thực hiện thông qua các phương thức.

Các lớp trong Java

Một lớp là một bản thiết kế mà từ đó các đối tượng riêng lẻ được tạo ra.

Sau đây là một mẫu của một lớp.

Thí dụ

public class Dog {
   String breed;
   int age;
   String color;

   void barking() {
   }

   void hungry() {
   }

   void sleeping() {
   }
}

Một lớp có thể chứa bất kỳ kiểu biến nào sau đây.

  • Local variables- Các biến được định nghĩa bên trong các phương thức, hàm tạo hoặc khối được gọi là biến cục bộ. Biến sẽ được khai báo và khởi tạo bên trong phương thức và biến sẽ bị hủy khi phương thức hoàn thành.

  • Instance variables- Biến thể hiện là các biến bên trong một lớp nhưng bên ngoài bất kỳ phương thức nào. Các biến này được khởi tạo khi lớp được khởi tạo. Các biến cá thể có thể được truy cập từ bên trong bất kỳ phương thức, hàm tạo hoặc khối nào của lớp cụ thể đó.

  • Class variables - Biến lớp là các biến được khai báo bên trong một lớp, bên ngoài bất kỳ phương thức nào, với từ khóa static.

Một lớp có thể có bất kỳ số phương thức nào để truy cập giá trị của nhiều loại phương thức khác nhau. Trong ví dụ trên, các phương thức: barking (), inherit () và sleep ().

Sau đây là một số chủ đề quan trọng cần được thảo luận khi xem xét các lớp của Ngôn ngữ Java.

Người xây dựng

Khi thảo luận về các lớp, một trong những chủ đề phụ quan trọng nhất sẽ là các hàm tạo. Mỗi lớp đều có một hàm tạo. Nếu chúng ta không viết một cách rõ ràng một phương thức khởi tạo cho một lớp, thì trình biên dịch Java sẽ xây dựng một phương thức khởi tạo mặc định cho lớp đó.

Mỗi khi một đối tượng mới được tạo, ít nhất một hàm tạo sẽ được gọi. Quy tắc chính của các hàm tạo là chúng phải có cùng tên với lớp. Một lớp có thể có nhiều hơn một hàm tạo.

Sau đây là một ví dụ về một hàm tạo:

Thí dụ

public class Puppy {
   public Puppy() {
   }

   public Puppy(String name) {
      // This constructor has one parameter, name.
   }
}

Java cũng hỗ trợ Lớp Singleton nơi bạn có thể chỉ tạo một thể hiện của một lớp.

Note- Chúng ta có hai loại constructor khác nhau. Chúng ta sẽ thảo luận chi tiết về các hàm tạo trong các chương tiếp theo.

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

Như đã đề cập trước đây, một lớp cung cấp bản thiết kế cho các đối tượng. Vì vậy, về cơ bản, một đối tượng được tạo ra từ một lớp. Trong Java, từ khóa mới được sử dụng để tạo các đối tượng mới.

Có ba bước khi tạo một đối tượng từ một lớp:

  • Declaration - Một khai báo biến với tên biến có kiểu đối tượng.

  • Instantiation - Từ khóa 'mới' được sử dụng để tạo đối tượng.

  • Initialization- Từ khóa 'mới' được theo sau bởi một cuộc gọi đến một hàm tạo. Cuộc gọi này khởi tạo đối tượng mới.

Sau đây là một ví dụ về việc tạo một đối tượng:

Thí dụ

public class Puppy {
   public Puppy(String name) {
      // This constructor has one parameter, name.
      System.out.println("Passed Name is :" + name );
   }

   public static void main(String []args) {
      // Following statement would create an object myPuppy
      Puppy myPuppy = new Puppy( "tommy" );
   }
}

Nếu chúng ta biên dịch và chạy chương trình trên, thì nó sẽ tạo ra kết quả sau:

Đầu ra

Passed Name is :tommy

Truy cập các biến và phương thức phiên bản

Các biến và phương thức thực thể được truy cập thông qua các đối tượng đã tạo. Để truy cập một biến phiên bản, sau đây là đường dẫn đầy đủ điều kiện:

/* First create an object */
ObjectReference = new Constructor();

/* Now call a variable as follows */
ObjectReference.variableName;

/* Now you can call a class method as follows */
ObjectReference.MethodName();

Thí dụ

Ví dụ này giải thích cách truy cập các biến cá thể và phương thức của một lớp.

public class Puppy {
   int puppyAge;

   public Puppy(String name) {
      // This constructor has one parameter, name.
      System.out.println("Name chosen is :" + name );
   }

   public void setAge( int age ) {
      puppyAge = age;
   }

   public int getAge( ) {
      System.out.println("Puppy's age is :" + puppyAge );
      return puppyAge;
   }

   public static void main(String []args) {
      /* Object creation */
      Puppy myPuppy = new Puppy( "tommy" );

      /* Call class method to set puppy's age */
      myPuppy.setAge( 2 );

      /* Call another class method to get puppy's age */
      myPuppy.getAge( );

      /* You can access instance variable as follows as well */
      System.out.println("Variable Value :" + myPuppy.puppyAge );
   }
}

Nếu chúng ta biên dịch và chạy chương trình trên, thì nó sẽ tạo ra kết quả sau:

Đầu ra

Name chosen is :tommy
Puppy's age is :2
Variable Value :2

Quy tắc khai báo tệp nguồn

Như phần cuối cùng của phần này, bây giờ chúng ta hãy xem xét các quy tắc khai báo tệp nguồn. Các quy tắc này rất cần thiết khi khai báo các lớp, câu lệnh nhập và câu lệnh gói trong tệp nguồn.

  • Chỉ có thể có một lớp công khai cho mỗi tệp nguồn.

  • Một tệp nguồn có thể có nhiều lớp không công khai.

  • Tên lớp công khai phải là tên của tệp nguồn cũng như phải được thêm vào bởi .javacuối cùng. Ví dụ: tên lớp là lớp công khai Employee {} thì tệp nguồn phải là Employee.java.

  • Nếu lớp được định nghĩa bên trong một gói, thì câu lệnh gói phải là câu lệnh đầu tiên trong tệp nguồn.

  • Nếu có các câu lệnh nhập thì chúng phải được viết giữa câu lệnh gói và phần khai báo lớp. Nếu không có câu lệnh gói nào, thì câu lệnh nhập phải là dòng đầu tiên trong tệp nguồn.

  • Câu lệnh nhập và gói sẽ ngụ ý cho tất cả các lớp có trong tệp nguồn. Không thể khai báo các câu lệnh nhập và / hoặc gói khác nhau cho các lớp khác nhau trong tệp nguồn.

Các lớp có một số cấp độ truy cập và có nhiều loại lớp khác nhau; các lớp trừu tượng, các lớp cuối cùng, v.v. Chúng tôi sẽ giải thích về tất cả những thứ này trong chương bổ trợ truy cập.

Ngoài các loại lớp đã đề cập ở trên, Java còn có một số lớp đặc biệt gọi là lớp Bên trong và lớp Ẩn danh.

Gói Java

Nói cách đơn giản, nó là một cách phân loại các lớp và giao diện. Khi phát triển các ứng dụng bằng Java, hàng trăm lớp và giao diện sẽ được viết, do đó việc phân loại các lớp này là điều bắt buộc cũng như giúp cuộc sống dễ dàng hơn nhiều.

Báo cáo nhập khẩu

Trong Java nếu một tên đủ điều kiện, bao gồm gói và tên lớp được đưa ra, thì trình biên dịch có thể dễ dàng định vị mã nguồn hoặc các lớp. Câu lệnh nhập là một cách cung cấp vị trí thích hợp cho trình biên dịch để tìm lớp cụ thể đó.

Ví dụ: dòng sau sẽ yêu cầu trình biên dịch tải tất cả các lớp có sẵn trong thư mục java_installation / java / io -

import java.io.*;

Một nghiên cứu điển hình đơn giản

Đối với nghiên cứu điển hình của chúng tôi, chúng tôi sẽ tạo hai lớp. Họ là Employee và EmployeeTest.

Đầu tiên mở notepad và thêm mã sau. Hãy nhớ rằng đây là lớp Nhân viên và lớp này là một lớp công khai. Bây giờ, hãy lưu tệp nguồn này với tên Employee.java.

Lớp Nhân viên có bốn biến cá thể - tên, tuổi, chỉ định và lương. Lớp có một hàm tạo được xác định rõ ràng, hàm này nhận một tham số.

Thí dụ

import java.io.*;
public class Employee {

   String name;
   int age;
   String designation;
   double salary;

   // This is the constructor of the class Employee
   public Employee(String name) {
      this.name = name;
   }

   // Assign the age of the Employee  to the variable age.
   public void empAge(int empAge) {
      age = empAge;
   }

   /* Assign the designation to the variable designation.*/
   public void empDesignation(String empDesig) {
      designation = empDesig;
   }

   /* Assign the salary to the variable	salary.*/
   public void empSalary(double empSalary) {
      salary = empSalary;
   }

   /* Print the Employee details */
   public void printEmployee() {
      System.out.println("Name:"+ name );
      System.out.println("Age:" + age );
      System.out.println("Designation:" + designation );
      System.out.println("Salary:" + salary);
   }
}

Như đã đề cập trước đó trong hướng dẫn này, quá trình xử lý bắt đầu từ phương thức chính. Do đó, để chúng ta chạy lớp Employee này, cần có một phương thức chính và các đối tượng phải được tạo. Chúng tôi sẽ tạo một lớp riêng cho các nhiệm vụ này.

Tiếp theo là lớp EmployeeTest , lớp này tạo ra hai trường hợp của lớp Employee và gọi các phương thức cho mỗi đối tượng để gán giá trị cho mỗi biến.

Lưu mã sau trong tệp EmployeeTest.java.

import java.io.*;
public class EmployeeTest {

   public static void main(String args[]) {
      /* Create two objects using constructor */
      Employee empOne = new Employee("James Smith");
      Employee empTwo = new Employee("Mary Anne");

      // Invoking methods for each object created
      empOne.empAge(26);
      empOne.empDesignation("Senior Software Engineer");
      empOne.empSalary(1000);
      empOne.printEmployee();

      empTwo.empAge(21);
      empTwo.empDesignation("Software Engineer");
      empTwo.empSalary(500);
      empTwo.printEmployee();
   }
}

Bây giờ, hãy biên dịch cả hai lớp và sau đó chạy EmployeeTest để xem kết quả như sau:

Đầu ra

C:\> javac Employee.java
C:\> javac EmployeeTest.java
C:\> java EmployeeTest
Name:James Smith
Age:26
Designation:Senior Software Engineer
Salary:1000.0
Name:Mary Anne
Age:21
Designation:Software Engineer
Salary:500.0

Tiếp theo là gì?

Trong phần tiếp theo, chúng ta sẽ thảo luận về các kiểu dữ liệu cơ bản trong Java và cách chúng có thể được sử dụng khi phát triển các ứng dụng Java.

Một hàm tạo khởi tạo một đối tượng khi nó được tạo. Nó có cùng tên với lớp của nó và tương tự về mặt cú pháp với một phương thức. Tuy nhiên, các hàm tạo không có kiểu trả về rõ ràng.

Thông thường, bạn sẽ sử dụng một hàm tạo để cung cấp các giá trị ban đầu cho các biến cá thể được xác định bởi lớp hoặc để thực hiện bất kỳ thủ tục khởi động nào khác được yêu cầu để tạo một đối tượng được hình thành đầy đủ.

Tất cả các lớp đều có các hàm tạo, cho dù bạn có xác định một hay không, bởi vì Java tự động cung cấp một hàm tạo mặc định khởi tạo tất cả các biến thành viên bằng 0. Tuy nhiên, khi bạn xác định hàm tạo của riêng mình, hàm tạo mặc định sẽ không còn được sử dụng nữa.

Cú pháp

Sau đây là cú pháp của một hàm tạo:

class ClassName {
   ClassName() {
   }
}

Java cho phép hai loại hàm tạo cụ thể là:

  • Không có trình tạo đối số
  • Trình xây dựng tham số

Không có trình tạo đối số

Vì tên chỉ định các hàm tạo không đối số của Java không chấp nhận bất kỳ tham số nào, thay vào đó, sử dụng các hàm tạo này, các biến cá thể của một phương thức sẽ được khởi tạo với các giá trị cố định cho tất cả các đối tượng.

Thí dụ

Public class MyClass {
   Int num;
   MyClass() {
      num = 100;
   }
}

Bạn sẽ gọi hàm tạo để khởi tạo các đối tượng như sau

public class ConsDemo {
   public static void main(String args[]) {
      MyClass t1 = new MyClass();
      MyClass t2 = new MyClass();
      System.out.println(t1.num + " " + t2.num);
   }
}

Điều này sẽ tạo ra kết quả sau

100 100

Trình xây dựng tham số

Thông thường, bạn sẽ cần một hàm tạo chấp nhận một hoặc nhiều tham số. Các tham số được thêm vào một phương thức khởi tạo giống như cách chúng được thêm vào một phương thức, chỉ cần khai báo chúng bên trong dấu ngoặc đơn sau tên của phương thức khởi tạo.

Thí dụ

Đây là một ví dụ đơn giản sử dụng một hàm tạo:

// A simple constructor.
class MyClass {
   int x;
   
   // Following is the constructor
   MyClass(int i ) {
      x = i;
   }
}

Bạn sẽ gọi hàm tạo để khởi tạo các đối tượng như sau:

public class ConsDemo {
   public static void main(String args[]) {
      MyClass t1 = new MyClass( 10 );
      MyClass t2 = new MyClass( 20 );
      System.out.println(t1.x + " " + t2.x);
   }
}

Điều này sẽ tạo ra kết quả sau:

10 20

Các biến không là gì ngoài các vị trí bộ nhớ dành riêng để lưu trữ các giá trị. Điều này có nghĩa là khi bạn tạo một biến, bạn dành một số không gian trong bộ nhớ.

Dựa trên kiểu dữ liệu của một biến, hệ điều hành cấp phát bộ nhớ và quyết định những gì có thể được lưu trữ trong bộ nhớ dành riêng. Do đó, bằng cách gán các kiểu dữ liệu khác nhau cho các biến, bạn có thể lưu trữ số nguyên, số thập phân hoặc ký tự trong các biến này.

Có hai kiểu dữ liệu có sẵn trong Java -

  • Các kiểu dữ liệu ban đầu
  • Các kiểu dữ liệu tham chiếu / đối tượng

Các kiểu dữ liệu ban đầu

Có tám kiểu dữ liệu nguyên thủy được hỗ trợ bởi Java. Các kiểu dữ liệu ban đầu được xác định trước bởi ngôn ngữ và được đặt tên bằng một từ khóa. Bây giờ chúng ta hãy xem xét chi tiết tám kiểu dữ liệu nguyên thủy.

byte

  • Kiểu dữ liệu byte là một số nguyên bổ sung 8 bit có dấu của hai

  • Giá trị nhỏ nhất là -128 (-2 ^ 7)

  • Giá trị tối đa là 127 (bao gồm) (2 ^ 7 -1)

  • Giá trị mặc định là 0

  • Kiểu dữ liệu byte được sử dụng để tiết kiệm không gian trong các mảng lớn, chủ yếu thay cho các số nguyên, vì một byte nhỏ hơn bốn lần so với một số nguyên.

  • Ví dụ: byte a = 100, byte b = -50

ngắn

  • Kiểu dữ liệu ngắn là một số nguyên bổ sung 16 bit có dấu của hai

  • Giá trị nhỏ nhất là -32,768 (-2 ^ 15)

  • Giá trị tối đa là 32,767 (bao gồm) (2 ^ 15 -1)

  • Kiểu dữ liệu ngắn cũng có thể được sử dụng để tiết kiệm bộ nhớ dưới dạng kiểu dữ liệu byte. Số ngắn nhỏ hơn số nguyên 2 lần

  • Giá trị mặc định là 0.

  • Ví dụ: short s = 10000, short r = -20000

int

  • Kiểu dữ liệu int là số nguyên bổ sung 32-bit có dấu của hai.

  • Giá trị nhỏ nhất là - 2,147,483,648 (-2 ^ 31)

  • Giá trị tối đa là 2,147,483,647 (bao gồm) (2 ^ 31 -1)

  • Số nguyên thường được sử dụng làm kiểu dữ liệu mặc định cho các giá trị tích phân trừ khi có mối lo ngại về bộ nhớ.

  • Giá trị mặc định là 0

  • Ví dụ: int a = 100000, int b = -200000

Dài

  • Kiểu dữ liệu dài là số nguyên bổ sung 64 bit có dấu của hai
  • Giá trị nhỏ nhất là -9,223,372,036,854,775,808 (-2 ^ 63)
  • Giá trị tối đa là 9.223.372.036.854.775.807 (bao gồm) (2 ^ 63 -1)
  • Loại này được sử dụng khi cần một phạm vi rộng hơn int
  • Giá trị mặc định là 0L
  • Ví dụ: dài a = 100000L, dài b = -200000L

Phao nổi

  • Kiểu dữ liệu nổi là một dấu chấm động IEEE 754 32 bit chính xác đơn

  • Float chủ yếu được sử dụng để tiết kiệm bộ nhớ trong mảng lớn các số dấu phẩy động

  • Giá trị mặc định là 0,0f

  • Kiểu dữ liệu float không bao giờ được sử dụng cho các giá trị chính xác như tiền tệ

  • Ví dụ: float f1 = 234.5f

gấp đôi

  • kiểu dữ liệu kép là dấu chấm động IEEE 754 64 bit chính xác kép

  • Kiểu dữ liệu này thường được sử dụng làm kiểu dữ liệu mặc định cho các giá trị thập phân, thường là lựa chọn mặc định

  • Kiểu dữ liệu kép không bao giờ được sử dụng cho các giá trị chính xác như tiền tệ

  • Giá trị mặc định là 0,0 ngày

  • Ví dụ: double d1 = 123,4

boolean

  • kiểu dữ liệu boolean đại diện cho một bit thông tin
  • Chỉ có hai giá trị có thể có: true và false
  • Kiểu dữ liệu này được sử dụng cho các cờ đơn giản theo dõi các điều kiện đúng / sai
  • Giá trị mặc định là sai
  • Ví dụ: boolean one = true

char

  • kiểu dữ liệu char là một ký tự Unicode 16 bit duy nhất
  • Giá trị nhỏ nhất là '\ u0000' (hoặc 0)
  • Giá trị tối đa là '\ uffff' (hoặc 65,535 bao gồm)
  • Kiểu dữ liệu Char được sử dụng để lưu trữ bất kỳ ký tự nào
  • Ví dụ: char letterA = 'A'

Tham khảo kiểu dữ liệu

  • Các biến tham chiếu được tạo bằng cách sử dụng các hàm tạo được xác định của các lớp. Chúng được sử dụng để truy cập các đối tượng. Các biến này được khai báo là một kiểu cụ thể không thể thay đổi. Ví dụ: Nhân viên, Cún con, v.v.

  • Các đối tượng lớp và nhiều loại biến mảng khác nhau nằm dưới kiểu dữ liệu tham chiếu.

  • Giá trị mặc định của bất kỳ biến tham chiếu nào là null.

  • Một biến tham chiếu có thể được sử dụng để tham chiếu đến bất kỳ đối tượng nào thuộc kiểu đã khai báo hoặc bất kỳ kiểu tương thích nào.

  • Ví dụ: Animal animal = new Animal ("giraffe");

Java Literals

Chữ là một biểu diễn mã nguồn của một giá trị cố định. Chúng được thể hiện trực tiếp trong mã mà không cần tính toán.

Literal có thể được gán cho bất kỳ biến kiểu nguyên thủy nào. Ví dụ -

byte a = 68;
char a = 'A';

byte, int, long và short cũng có thể được biểu thị trong hệ thống số thập phân (cơ số 10), thập lục phân (cơ số 16) hoặc bát phân (cơ số 8).

Tiền tố 0 được sử dụng để biểu thị hệ bát phân và tiền tố 0x biểu thị hệ thập lục phân khi sử dụng các hệ thống số này cho các chữ. Ví dụ -

int decimal = 100;
int octal = 0144;
int hexa =  0x64;

Chuỗi ký tự trong Java được chỉ định giống như trong hầu hết các ngôn ngữ khác bằng cách đặt một chuỗi ký tự giữa một cặp dấu ngoặc kép. Ví dụ về các ký tự chuỗi là -

Thí dụ

"Hello World"
"two\nlines"
"\"This is in quotes\""

Các kiểu chuỗi ký tự và ký tự ký tự có thể chứa bất kỳ ký tự Unicode nào. Ví dụ -

char a = '\u0001';
String a = "\u0001";

Ngôn ngữ Java cũng hỗ trợ một số chuỗi thoát đặc biệt cho chuỗi ký tự và ký tự char. Họ là -

Ký hiệu Ký tự đại diện
\ n Dòng mới (0x0a)
\ r Vận chuyển trở lại (0x0d)
\ f Nguồn cấp dữ liệu định dạng (0x0c)
\ b Backspace (0x08)
\S Không gian (0x20)
\ t chuyển hướng
\ " Dấu ngoặc kép
\ ' Trích dẫn duy nhất
\\ dấu gạch chéo ngược
\ ddd Ký tự bát phân (ddd)
\ uxxxx Ký tự UNICODE hệ thập lục phân (xxxx)

Tiếp theo là gì?

Chương này giải thích các kiểu dữ liệu khác nhau. Chủ đề tiếp theo giải thích các loại biến khác nhau và cách sử dụng chúng. Điều này sẽ giúp bạn hiểu rõ về cách chúng có thể được sử dụng trong các lớp Java, giao diện, v.v.

Một biến cung cấp cho chúng ta bộ nhớ được đặt tên mà chương trình của chúng ta có thể thao tác. Mỗi biến trong Java có một kiểu cụ thể, xác định kích thước và cách bố trí bộ nhớ của biến; phạm vi giá trị có thể được lưu trữ trong bộ nhớ đó; và tập hợp các thao tác có thể áp dụng cho biến.

Bạn phải khai báo tất cả các biến trước khi chúng có thể được sử dụng. Sau đây là dạng cơ bản của một khai báo biến:

data type variable [ = value][, variable [ = value] ...] ;

Ở đây kiểu dữ liệu là một trong những kiểu dữ liệu của Java và biến là tên của biến. Để khai báo nhiều biến thuộc kiểu đã chỉ định, bạn có thể sử dụng danh sách được phân tách bằng dấu phẩy.

Sau đây là các ví dụ hợp lệ về khai báo và khởi tạo biến trong Java:

Thí dụ

int a, b, c;         // Declares three ints, a, b, and c.
int a = 10, b = 10;  // Example of initialization
byte B = 22;         // initializes a byte type variable B.
double pi = 3.14159; // declares and assigns a value of PI.
char a = 'A';        // the char variable a iis initialized with value 'a'

Chương này sẽ giải thích các kiểu biến khác nhau có sẵn trong Ngôn ngữ Java. Có ba loại biến trong Java:

  • Biến cục bộ
  • Biến thể hiện
  • Biến lớp / tĩnh

Biến cục bộ

  • Các biến cục bộ được khai báo trong các phương thức, hàm tạo hoặc khối.

  • Biến cục bộ được tạo khi phương thức, hàm tạo hoặc khối được nhập và biến sẽ bị hủy khi nó thoát khỏi phương thức, hàm tạo hoặc khối.

  • Không thể sử dụng công cụ sửa đổi quyền truy cập cho các biến cục bộ.

  • Các biến cục bộ chỉ hiển thị trong phương thức, hàm tạo hoặc khối đã khai báo.

  • Các biến cục bộ được thực hiện ở cấp ngăn xếp trong nội bộ.

  • Không có giá trị mặc định cho các biến cục bộ, vì vậy các biến cục bộ nên được khai báo và một giá trị ban đầu nên được gán trước lần sử dụng đầu tiên.

Thí dụ

Ở đây, tuổi là một biến cục bộ. Điều này được định nghĩa bên trong phương thức PorAge () và phạm vi của nó được giới hạn trong chỉ phương thức này.

public class Test {
   public void pupAge() {
      int age = 0;
      age = age + 7;
      System.out.println("Puppy age is : " + age);
   }

   public static void main(String args[]) {
      Test test = new Test();
      test.pupAge();
   }
}

Điều này sẽ tạo ra kết quả sau:

Đầu ra

Puppy age is: 7

Thí dụ

Ví dụ sau sử dụng age mà không khởi tạo nó, vì vậy nó sẽ xuất hiện một lỗi tại thời điểm biên dịch.

public class Test {
   public void pupAge() {
      int age;
      age = age + 7;
      System.out.println("Puppy age is : " + age);
   }

   public static void main(String args[]) {
      Test test = new Test();
      test.pupAge();
   }
}

Điều này sẽ tạo ra lỗi sau khi biên dịch nó:

Đầu ra

Test.java:4:variable number might not have been initialized
age = age + 7;
         ^
1 error

Biến thể hiện

  • Các biến cá thể được khai báo trong một lớp, nhưng bên ngoài một phương thức, hàm tạo hoặc bất kỳ khối nào.

  • Khi một không gian được cấp phát cho một đối tượng trong heap, một vị trí cho mỗi giá trị biến cá thể sẽ được tạo.

  • Biến cá thể được tạo khi một đối tượng được tạo bằng cách sử dụng từ khóa 'mới' và bị hủy khi đối tượng bị phá hủy.

  • Các biến cá thể giữ các giá trị phải được tham chiếu bởi nhiều hơn một phương thức, phương thức khởi tạo hoặc khối hoặc các phần thiết yếu của trạng thái đối tượng phải có mặt trong toàn bộ lớp.

  • Các biến cá thể có thể được khai báo ở mức lớp trước hoặc sau khi sử dụng.

  • Các công cụ sửa đổi quyền truy cập có thể được cung cấp cho các biến cá thể.

  • Các biến cá thể hiển thị cho tất cả các phương thức, hàm tạo và khối trong lớp. Thông thường, bạn nên đặt các biến này ở chế độ riêng tư (mức truy cập). Tuy nhiên, khả năng hiển thị cho các lớp con có thể được cung cấp cho các biến này với việc sử dụng các công cụ sửa đổi truy cập.

  • Biến cá thể có giá trị mặc định. Đối với số, giá trị mặc định là 0, đối với Booleans là false và đối với tham chiếu đối tượng, giá trị này là null. Giá trị có thể được gán trong khi khai báo hoặc trong hàm tạo.

  • Các biến cá thể có thể được truy cập trực tiếp bằng cách gọi tên biến bên trong lớp. Tuy nhiên, bên trong các phương thức tĩnh (khi các biến thể hiện được cung cấp khả năng truy cập), chúng nên được gọi bằng tên đủ điều kiện. ObjectReference.VariableName .

Thí dụ

import java.io.*;
public class Employee {

   // this instance variable is visible for any child class.
   public String name;

   // salary  variable is visible in Employee class only.
   private double salary;

   // The name variable is assigned in the constructor.
   public Employee (String empName) {
      name = empName;
   }

   // The salary variable is assigned a value.
   public void setSalary(double empSal) {
      salary = empSal;
   }

   // This method prints the employee details.
   public void printEmp() {
      System.out.println("name  : " + name );
      System.out.println("salary :" + salary);
   }

   public static void main(String args[]) {
      Employee empOne = new Employee("Ransika");
      empOne.setSalary(1000);
      empOne.printEmp();
   }
}

Điều này sẽ tạo ra kết quả sau:

Đầu ra

name  : Ransika
salary :1000.0

Biến lớp / tĩnh

  • Biến lớp còn được gọi là biến tĩnh được khai báo với từ khóa static trong một lớp, nhưng bên ngoài một phương thức, hàm tạo hoặc một khối.

  • Sẽ chỉ có một bản sao của mỗi biến lớp cho mỗi lớp, bất kể có bao nhiêu đối tượng được tạo từ nó.

  • Biến static hiếm khi được sử dụng ngoài việc được khai báo dưới dạng hằng số. Hằng là các biến được khai báo là công khai / riêng tư, cuối cùng và tĩnh. Các biến không đổi không bao giờ thay đổi so với giá trị ban đầu của chúng.

  • Các biến tĩnh được lưu trữ trong bộ nhớ tĩnh. Rất hiếm khi sử dụng các biến tĩnh không phải là biến cuối cùng được khai báo và được sử dụng như các hằng số công khai hoặc riêng tư.

  • Biến static được tạo ra khi chương trình khởi động và bị hủy khi chương trình dừng.

  • Khả năng hiển thị tương tự như các biến cá thể. Tuy nhiên, hầu hết các biến tĩnh được khai báo công khai vì chúng phải có sẵn cho người dùng của lớp.

  • Giá trị mặc định giống như các biến cá thể. Đối với số, giá trị mặc định là 0; đối với Booleans, nó là sai; và đối với các tham chiếu đối tượng, nó là null. Giá trị có thể được gán trong khi khai báo hoặc trong hàm tạo. Ngoài ra, các giá trị có thể được gán trong các khối khởi tạo tĩnh đặc biệt.

  • Các biến static có thể được truy cập bằng cách gọi với tên lớp ClassName.VariableName .

  • Khi khai báo các biến lớp là public static final, thì tên biến (hằng số) đều ở dạng chữ hoa. Nếu các biến tĩnh không phải là công khai và cuối cùng, thì cú pháp đặt tên giống như các biến thể hiện và biến cục bộ.

Thí dụ

import java.io.*;
public class Employee {

   // salary  variable is a private static variable
   private static double salary;

   // DEPARTMENT is a constant
   public static final String DEPARTMENT = "Development ";

   public static void main(String args[]) {
      salary = 1000;
      System.out.println(DEPARTMENT + "average salary:" + salary);
   }
}

Điều này sẽ tạo ra kết quả sau:

Đầu ra

Development average salary:1000

Note - Nếu các biến được truy cập từ một lớp bên ngoài, hằng số phải được truy cập dưới dạng Employee.

Tiếp theo là gì?

Bạn đã sử dụng công cụ sửa đổi quyền truy cập (công khai và riêng tư) trong chương này. Chương tiếp theo sẽ giải thích chi tiết về Công cụ sửa đổi truy cập và Công cụ sửa đổi không truy cập.

Bổ ngữ là những từ khóa mà bạn thêm vào các định nghĩa đó để thay đổi ý nghĩa của chúng. Ngôn ngữ Java có nhiều loại bổ ngữ, bao gồm:

  • Công cụ sửa đổi quyền truy cập Java

  • Công cụ sửa đổi không truy cập

Để sử dụng một công cụ sửa đổi, bạn đưa từ khóa của nó vào định nghĩa của một lớp, phương thức hoặc biến. Bổ ngữ đứng trước phần còn lại của câu lệnh, như trong ví dụ sau.

Thí dụ

public class className {
   // ...
}

private boolean myFlag;
static final double weeks = 9.5;
protected static final int BOXWIDTH = 42;

public static void main(String[] arguments) {
   // body of method
}

Công cụ sửa đổi điều khiển truy cập

Java cung cấp một số công cụ sửa đổi quyền truy cập để thiết lập mức độ truy cập cho các lớp, biến, phương thức và hàm tạo. Bốn cấp độ truy cập là -

  • Hiển thị với gói, mặc định. Không cần bổ ngữ.
  • Chỉ hiển thị với lớp học (riêng tư).
  • Hiển thị với thế giới (công khai).
  • Hiển thị với gói và tất cả các lớp con (được bảo vệ).

Công cụ sửa đổi không truy cập

Java cung cấp một số công cụ sửa đổi không truy cập để đạt được nhiều chức năng khác.

  • Công cụ sửa đổi tĩnh để tạo các phương thức và biến lớp.

  • Công cụ sửa đổi cuối cùng để hoàn thiện việc triển khai các lớp, phương thức và biến.

  • Công cụ sửa đổi trừu tượng để tạo các lớp và phương thức trừu tượng.

  • Các công cụ sửa đổi đồng bộdễ bay hơi , được sử dụng cho các luồng.

Tiếp theo là gì?

Trong phần tiếp theo, chúng ta sẽ thảo luận về các toán tử cơ bản được sử dụng trong ngôn ngữ Java. Chương này sẽ cung cấp cho bạn một cái nhìn tổng quan về cách các toán tử này có thể được sử dụng trong quá trình phát triển ứng dụng.

Java cung cấp một tập hợp các toán tử phong phú để thao tác với các biến. Chúng ta có thể chia tất cả các toán tử Java thành các nhóm sau:

  • Toán tử số học
  • Toán tử quan hệ
  • Toán tử Bitwise
  • Toán tử logic
  • Người điều hành nhiệm vụ
  • Nhà điều hành khác

Các toán tử số học

Các toán tử số học được sử dụng trong các biểu thức toán học giống như cách chúng được sử dụng trong đại số. Bảng sau liệt kê các toán tử số học:

Giả sử biến số nguyên A giữ 10 và biến B giữ 20, sau đó -

Hiển thị các ví dụ

Nhà điều hành Sự miêu tả Thí dụ
+ (Bổ sung) Thêm giá trị vào hai bên của toán tử. A + B sẽ cho 30
- (Phép trừ) Trừ toán hạng bên phải khỏi toán hạng bên trái. A - B sẽ cho -10
* (Phép nhân) Nhân các giá trị ở hai bên của toán tử. A * B sẽ cho 200
/ (Bộ phận) Chia toán hạng bên trái cho toán hạng bên phải. B / A sẽ cho 2
% (Mô-đun) Chia toán hạng bên trái cho toán hạng bên phải và trả về phần dư. B% A sẽ cho 0
++ (Tăng dần) Tăng giá trị của toán hạng lên 1. B ++ cho 21
- (Giảm dần) Giảm giá trị của toán hạng đi 1. B-- cho 19

Các toán tử quan hệ

Có các toán tử quan hệ sau được hỗ trợ bởi ngôn ngữ Java.

Giả sử biến A giữ 10 và biến B giữ 20, thì -

Hiển thị các ví dụ

Nhà điều hành Sự miêu tả Thí dụ
== (bằng) Kiểm tra xem giá trị của hai toán hạng có bằng nhau hay không, nếu có thì điều kiện trở thành true. (A == B) không đúng.
! = (không bằng) Kiểm tra xem giá trị của hai toán hạng có bằng nhau hay không, nếu các giá trị không bằng nhau thì điều kiện trở thành true. (A! = B) là đúng.
> (lớn hơn) Kiểm tra xem giá trị của toán hạng bên trái có lớn hơn giá trị của toán hạng bên phải hay không, nếu có thì điều kiện trở thành true. (A> B) là không đúng.
<(nhỏ hơn) Kiểm tra xem giá trị của toán hạng bên trái có nhỏ hơn giá trị của toán hạng bên phải hay không, nếu có thì điều kiện trở thành true. (A <B) là đúng.
> = (lớn hơn hoặc bằng) Kiểm tra xem giá trị của toán hạng bên trái có lớn hơn hoặc bằng giá trị của toán hạng bên phải hay không, nếu có thì điều kiện trở thành true. (A> = B) là không đúng.
<= (nhỏ hơn hoặc bằng) Kiểm tra xem giá trị của toán hạng bên trái có nhỏ hơn hoặc bằng giá trị của toán hạng bên phải hay không, nếu có thì điều kiện trở thành true. (A <= B) là đúng.

Các toán tử Bitwise

Java định nghĩa một số toán tử bitwise, có thể được áp dụng cho các kiểu số nguyên, long, int, short, char và byte.

Toán tử bitwise hoạt động trên các bit và thực hiện hoạt động từng bit. Giả sử nếu a = 60 và b = 13; bây giờ ở định dạng nhị phân, chúng sẽ như sau:

a = 0011 1100

b = 0000 1101

-----------------

a & b = 0000 1100

a | b = 0011 1101

a ^ b = 0011 0001

~ a = 1100 0011

Bảng sau liệt kê các toán tử bitwise:

Giả sử biến số nguyên A giữ 60 và biến B giữ 13 thì -

Hiển thị các ví dụ

Nhà điều hành Sự miêu tả Thí dụ
& (bitwise và) Toán tử AND nhị phân sao chép một bit vào kết quả nếu nó tồn tại trong cả hai toán hạng. (A & B) sẽ cho kết quả 12 là 0000 1100
| (bitwise hoặc) Toán tử OR nhị phân sao chép một bit nếu nó tồn tại trong một trong hai toán hạng. (A | B) sẽ cho 61 là 0011 1101
^ (bitwise XOR) Toán tử XOR nhị phân sao chép bit nếu nó được đặt trong một toán hạng nhưng không phải cả hai. (A ^ B) sẽ cho 49 là 0011 0001
~ (lời khen nhẹ nhàng) Toán tử bổ sung số nhị phân là một ngôi và có tác dụng 'lật' các bit. (~ A) sẽ cho -61 là 1100 0011 ở dạng phần bù của 2 do một số nhị phân có dấu.
<< (dịch trái) Toán tử dịch chuyển trái nhị phân. Giá trị toán hạng bên trái được di chuyển sang trái bằng số bit được chỉ định bởi toán hạng bên phải. A << 2 sẽ cho 240 là 1111 0000
>> (ca phải) Toán tử Shift phải nhị phân. Giá trị của toán hạng bên trái được di chuyển sang phải bằng số bit được chỉ định bởi toán hạng bên phải. A >> 2 sẽ cho 15 là 1111
>>> (điền số 0 sang phải) Chuyển sang phải toán tử điền số 0. Giá trị toán hạng bên trái được di chuyển sang phải bằng số bit được chỉ định bởi toán hạng bên phải và các giá trị được dịch chuyển được điền bằng số không. A >>> 2 sẽ cho 15 là 0000 1111

Các toán tử logic

Bảng sau liệt kê các toán tử logic:

Giả sử biến Boolean A giữ đúng và biến B là sai, thì -

Hiển thị các ví dụ

Nhà điều hành Sự miêu tả Thí dụ
&& (logic và) Được gọi là toán tử logic AND. Nếu cả hai toán hạng đều khác 0, thì điều kiện trở thành true. (A && B) là sai
|| (logic hoặc) Được gọi là Toán tử logic HOẶC. Nếu bất kỳ toán hạng nào trong hai toán hạng khác 0, thì điều kiện trở thành true. (A || B) đúng
! (logic không) Được gọi là Toán tử logic NOT. Sử dụng để đảo ngược trạng thái logic của toán hạng của nó. Nếu một điều kiện là đúng thì toán tử logic NOT sẽ sai. ! (A && B) là đúng

Người điều hành nhiệm vụ

Sau đây là các toán tử gán được hỗ trợ bởi ngôn ngữ Java:

Hiển thị các ví dụ

Nhà điều hành Sự miêu tả Thí dụ
= Toán tử gán đơn giản. Gán giá trị từ toán hạng bên phải cho toán hạng bên trái. C = A + B sẽ gán giá trị của A + B vào C
+ = Thêm toán tử gán AND. Nó thêm toán hạng bên phải vào toán hạng bên trái và gán kết quả cho toán hạng bên trái. C + = A tương đương với C = C + A
- = Trừ toán tử gán AND. Nó trừ toán hạng bên phải khỏi toán hạng bên trái và gán kết quả cho toán hạng bên trái. C - = A tương đương với C = C - A
* = Nhân toán tử gán AND. Nó nhân toán hạng bên phải với toán hạng bên trái và gán kết quả cho toán hạng bên trái. C * = A tương đương với C = C * A
/ = Toán tử gán AND. Nó chia toán hạng bên trái với toán hạng bên phải và gán kết quả cho toán hạng bên trái. C / = A tương đương với C = C / A
% = Toán tử gán môđun AND. Cần mô đun bằng cách sử dụng hai toán hạng và gán kết quả cho toán hạng bên trái. C% = A tương đương với C = C% A
<< = Dịch chuyển trái toán tử gán AND. C << = 2 giống với C = C << 2
>> = Toán tử gán dịch chuyển phải AND. C >> = 2 giống với C = C >> 2
& = Toán tử gán bitwise AND. C & = 2 giống C = C & 2
^ = OR độc quyền theo bit và toán tử gán. C ^ = 2 giống với C = C ^ 2
| = bitwise bao gồm OR và toán tử gán. C | = 2 tương tự như C = C | 2

Các nhà khai thác khác

Có một vài toán tử khác được hỗ trợ bởi Ngôn ngữ Java.

Điều hành có điều kiện ( ? : )

Toán tử điều kiện còn được gọi là ternary operator. Toán tử này bao gồm ba toán hạng và được sử dụng để đánh giá các biểu thức Boolean. Mục tiêu của toán tử là quyết định, giá trị nào nên được gán cho biến. Toán tử được viết là -

variable x = (expression) ? value if true : value if false

Sau đây là một ví dụ -

Example

public class Test {

   public static void main(String args[]) {
      int a, b;
      a = 10;
      b = (a == 1) ? 20: 30;
      System.out.println( "Value of b is : " +  b );

      b = (a == 10) ? 20: 30;
      System.out.println( "Value of b is : " + b );
   }
}

Điều này sẽ tạo ra kết quả sau:

Output

Value of b is : 30
Value of b is : 20

Người điều hành instanceof

Toán tử này chỉ được sử dụng cho các biến tham chiếu đối tượng. Toán tử kiểm tra xem đối tượng có thuộc một kiểu cụ thể hay không (kiểu lớp hoặc kiểu giao diện). toán tử instanceof được viết là -

( Object reference variable ) instanceof  (class/interface type)

Nếu đối tượng được tham chiếu bởi biến ở phía bên trái của toán tử vượt qua kiểm tra IS-A cho loại lớp / giao diện ở phía bên phải, thì kết quả sẽ là true. Sau đây là một ví dụ -

Example

public class Test {

   public static void main(String args[]) {

      String name = "James";

      // following will return true since name is type of String
      boolean result = name instanceof String;
      System.out.println( result );
   }
}

Điều này sẽ tạo ra kết quả sau:

Output

true

Toán tử này sẽ vẫn trả về true, nếu đối tượng được so sánh là phép gán tương thích với kiểu ở bên phải. Sau đây là một ví dụ nữa -

Example

class Vehicle {}

public class Car extends Vehicle {

   public static void main(String args[]) {

      Vehicle a = new Car();
      boolean result =  a instanceof Car;
      System.out.println( result );
   }
}

Điều này sẽ tạo ra kết quả sau:

Output

true

Mức độ ưu tiên của các toán tử Java

Mức độ ưu tiên của toán tử xác định nhóm các từ trong một biểu thức. Điều này ảnh hưởng đến cách một biểu thức được đánh giá. Các toán tử nhất định có quyền ưu tiên cao hơn những toán tử khác; ví dụ, toán tử nhân có mức độ ưu tiên cao hơn toán tử cộng -

Ví dụ: x = 7 + 3 * 2; ở đây x được gán 13, không phải 20 vì toán tử * có mức độ ưu tiên cao hơn +, vì vậy đầu tiên nó được nhân với 3 * 2 và sau đó cộng thành 7.

Ở đây, các toán tử có mức độ ưu tiên cao nhất xuất hiện ở đầu bảng, những toán tử có mức độ ưu tiên thấp nhất xuất hiện ở cuối bảng. Trong một biểu thức, các toán tử có mức độ ưu tiên cao hơn sẽ được đánh giá đầu tiên.

thể loại Nhà điều hành Sự liên kết
Postfix biểu thức ++ biểu thức-- Trái sang phải
Một ngôi ++ biểu thức –- biểu thức + biểu thức – biểu thức ~! Phải sang trái
Phép nhân * /% Trái sang phải
Phụ gia + - Trái sang phải
Shift << >> >>> Trái sang phải
Quan hệ <> <=> = instanceof Trái sang phải
Bình đẳng ==! = Trái sang phải
Bitwise VÀ & Trái sang phải
Bitwise XOR ^ Trái sang phải
Bitwise HOẶC | Trái sang phải
Logic AND && Trái sang phải
Logic HOẶC || Trái sang phải
Có điều kiện ?: Phải sang trái
Chuyển nhượng = + = - = * = / =% = ^ = | = << = >> = >>> = Phải sang trái

Tiếp theo là gì?

Chương tiếp theo sẽ giải thích về điều khiển vòng lặp trong lập trình Java. Chương này sẽ mô tả các loại vòng lặp khác nhau và cách các vòng lặp này có thể được sử dụng trong phát triển chương trình Java và chúng đang được sử dụng cho những mục đích nào.

Có thể có một tình huống khi bạn cần thực thi một khối mã nhiều lần. Nói chung, các câu lệnh được thực hiện tuần tự: Câu lệnh đầu tiên trong một hàm được thực hiện đầu tiên, tiếp theo là câu lệnh thứ hai, v.v.

Các ngôn ngữ lập trình cung cấp các cấu trúc điều khiển khác nhau cho phép các đường dẫn thực thi phức tạp hơn.

A loop câu lệnh cho phép chúng ta thực hiện một câu lệnh hoặc một nhóm câu lệnh nhiều lần và sau đây là dạng chung của câu lệnh lặp trong hầu hết các ngôn ngữ lập trình:

Ngôn ngữ lập trình Java cung cấp các loại vòng lặp sau để xử lý các yêu cầu lặp. Nhấp vào các liên kết sau để kiểm tra chi tiết của chúng.

Sr.No. Vòng lặp & mô tả
1 trong khi lặp lại

Lặp lại một câu lệnh hoặc một nhóm câu lệnh trong khi một điều kiện đã cho là đúng. Nó kiểm tra điều kiện trước khi thực thi phần thân của vòng lặp.

2 vòng lặp for

Thực thi một chuỗi các câu lệnh nhiều lần và viết tắt mã quản lý biến vòng lặp.

3 vòng lặp do ... while

Giống như một câu lệnh while, ngoại trừ việc nó kiểm tra điều kiện ở cuối thân vòng lặp.

Tuyên bố kiểm soát vòng lặp

Các câu lệnh điều khiển vòng lặp thay đổi việc thực thi từ trình tự bình thường của nó. Khi việc thực thi rời khỏi một phạm vi, tất cả các đối tượng tự động được tạo trong phạm vi đó sẽ bị phá hủy.

Java hỗ trợ các câu lệnh điều khiển sau. Nhấp vào các liên kết sau để kiểm tra chi tiết của chúng.

Sr.No. Tuyên bố & Mô tả Kiểm soát
1 tuyên bố ngắt

Chấm dứt loop hoặc là switch và chuyển việc thực thi đến câu lệnh ngay sau vòng lặp hoặc chuyển đổi.

2 tiếp tục tuyên bố

Làm cho vòng lặp bỏ qua phần còn lại của phần thân và ngay lập tức kiểm tra lại tình trạng của nó trước khi nhắc lại.

Vòng lặp for nâng cao trong Java

Kể từ Java 5, vòng lặp for nâng cao đã được giới thiệu. Điều này chủ yếu được sử dụng để duyệt qua tập hợp các phần tử bao gồm cả mảng.

Cú pháp

Sau đây là cú pháp của vòng lặp for nâng cao:

for(declaration : expression) {
   // Statements
}
  • Declaration- Biến khối mới khai báo, có kiểu tương thích với các phần tử của mảng mà bạn đang truy cập. Biến sẽ có sẵn trong khối for và giá trị của nó sẽ giống như phần tử mảng hiện tại.

  • Expression- Điều này đánh giá mảng bạn cần lặp qua. Biểu thức có thể là một biến mảng hoặc lệnh gọi phương thức trả về một mảng.

Thí dụ

public class Test {

   public static void main(String args[]) {
      int [] numbers = {10, 20, 30, 40, 50};

      for(int x : numbers ) {
         System.out.print( x );
         System.out.print(",");
      }
      System.out.print("\n");
      String [] names = {"James", "Larry", "Tom", "Lacy"};

      for( String name : names ) {
         System.out.print( name );
         System.out.print(",");
      }
   }
}

Điều này sẽ tạo ra kết quả sau:

Đầu ra

10, 20, 30, 40, 50,
James, Larry, Tom, Lacy,

Tiếp theo là gì?

Trong chương sau, chúng ta sẽ tìm hiểu về các câu lệnh ra quyết định trong lập trình Java.

Cấu trúc ra quyết định có một hoặc nhiều điều kiện để được đánh giá hoặc kiểm tra bởi chương trình, cùng với một câu lệnh hoặc các câu lệnh sẽ được thực hiện nếu điều kiện được xác định là đúng và tùy chọn, các câu lệnh khác sẽ được thực hiện nếu điều kiện được xác định sai.

Sau đây là dạng chung của cấu trúc ra quyết định điển hình được tìm thấy trong hầu hết các ngôn ngữ lập trình:

Ngôn ngữ lập trình Java cung cấp các loại câu lệnh ra quyết định sau. Nhấp vào các liên kết sau để kiểm tra chi tiết của chúng.

Sr.No. Tuyên bố & Mô tả
1 câu lệnh if

An if statement bao gồm một biểu thức boolean theo sau bởi một hoặc nhiều câu lệnh.

2 câu lệnh if ... else

An if statement có thể được theo sau bởi một tùy chọn else statement, thực thi khi biểu thức boolean sai.

3 câu lệnh if lồng nhau

Bạn có thể sử dụng một if hoặc là else if tuyên bố bên trong khác if hoặc là else if các câu lệnh).

4 chuyển đổi tuyên bố

A switch câu lệnh cho phép một biến được kiểm tra tính bình đẳng với một danh sách các giá trị.

Các ? : Nhà điều hành

Chúng tôi đã bảo hiểm conditional operator ? : trong chương trước có thể được sử dụng để thay thế if...elsecác câu lệnh. Nó có dạng chung sau:

Exp1 ? Exp2 : Exp3;

Trong đó Exp1, Exp2 và Exp3 là các biểu thức. Chú ý công dụng và vị trí của dấu hai chấm.

Để xác định giá trị của toàn bộ biểu thức, ban đầu exp1 được đánh giá.

  • Nếu giá trị của exp1 là true, thì giá trị của Exp2 sẽ là giá trị của toàn bộ biểu thức.

  • Nếu giá trị của exp1 là false, thì Exp3 được đánh giá và giá trị của nó trở thành giá trị của toàn bộ biểu thức.

Tiếp theo là gì?

Trong chương tiếp theo, chúng ta sẽ thảo luận về lớp Số (trong gói java.lang) và các lớp con của nó trong Ngôn ngữ Java.

Chúng tôi sẽ xem xét một số tình huống mà bạn sẽ sử dụng các phần khởi tạo của các lớp này thay vì các kiểu dữ liệu nguyên thủy, cũng như các lớp như định dạng, các hàm toán học mà bạn cần biết khi làm việc với Numbers.

Thông thường, khi chúng ta làm việc với Numbers, chúng ta sử dụng các kiểu dữ liệu nguyên thủy như byte, int, long, double, v.v.

Thí dụ

int i = 5000;
float gpa = 13.65f;
double mask = 125;

Tuy nhiên, trong quá trình phát triển, chúng ta gặp phải những tình huống mà chúng ta cần sử dụng các đối tượng thay vì các kiểu dữ liệu nguyên thủy. Để đạt được điều này, Java cung cấpwrapper classes.

Tất cả các lớp bao bọc (Integer, Long, Byte, Double, Float, Short) là các lớp con của lớp trừu tượng Number.

Đối tượng của lớp wrapper chứa hoặc bao bọc kiểu dữ liệu nguyên thủy tương ứng của nó. Việc chuyển đổi các kiểu dữ liệu nguyên thủy thành đối tượng được gọi làboxing, và điều này được thực hiện bởi trình biên dịch. Do đó, trong khi sử dụng một lớp wrapper, bạn chỉ cần truyền giá trị của kiểu dữ liệu nguyên thủy cho phương thức khởi tạo của lớp Wrapper.

Và đối tượng Wrapper sẽ được chuyển đổi trở lại kiểu dữ liệu nguyên thủy, và quá trình này được gọi là unboxing. CácNumber lớp là một phần của gói java.lang.

Sau đây là một ví dụ về quyền anh và unboxing -

Thí dụ

public class Test {

   public static void main(String args[]) {
      Integer x = 5; // boxes int to an Integer object
      x =  x + 10;   // unboxes the Integer to a int
      System.out.println(x); 
   }
}

Điều này sẽ tạo ra kết quả sau:

Đầu ra

15

Khi x được gán một giá trị số nguyên, trình biên dịch sẽ đóng hộp số nguyên vì x là đối tượng số nguyên. Sau đó, x được mở hộp để chúng có thể được thêm vào dưới dạng số nguyên.

Phương pháp số

Sau đây là danh sách các phương thức thể hiện mà tất cả các lớp con của lớp Number triển khai:

Sr.No. Phương pháp & Mô tả
1 xxxValue ()

Chuyển đổi giá trị của đối tượng Number này thành kiểu dữ liệu xxx và trả về nó.

2 so với()

So sánh đối tượng Number này với đối số.

3 bằng ()

Xác định xem này đối tượng số tương đương với đối số.

4 giá trị của()

Trả về một đối tượng Integer giữ giá trị của giá trị nguyên thủy đã chỉ định.

5 toString ()

Trả về một đối tượng Chuỗi đại diện cho giá trị của một số nguyên hoặc số nguyên được chỉ định.

6 parseInt ()

Phương thức này dùng để lấy kiểu dữ liệu nguyên thủy của một Chuỗi nào đó.

7 abs ()

Trả về giá trị tuyệt đối của đối số.

số 8 ceil ()

Trả về số nguyên nhỏ nhất lớn hơn hoặc bằng đối số. Trả lại dưới dạng nhân đôi.

9 sàn nhà()

Trả về số nguyên lớn nhất nhỏ hơn hoặc bằng đối số. Trả lại dưới dạng nhân đôi.

10 rint ()

Trả về số nguyên có giá trị gần nhất với đối số. Trả lại dưới dạng nhân đôi.

11 tròn()

Trả về long hoặc int gần nhất, như được chỉ ra bởi kiểu trả về của phương thức cho đối số.

12 min ()

Trả về giá trị nhỏ hơn trong hai đối số.

13 max ()

Trả về giá trị lớn hơn trong hai đối số.

14 exp ()

Trả về cơ số của logarit tự nhiên, e, thành lũy thừa của đối số.

15 log ()

Trả về lôgarit tự nhiên của đối số.

16 pow ()

Trả về giá trị của đối số đầu tiên được nâng lên thành lũy thừa của đối số thứ hai.

17 sqrt ()

Trả về căn bậc hai của đối số.

18 tội()

Trả về sin của giá trị kép được chỉ định.

19 cos ()

Trả về cosine của giá trị kép được chỉ định.

20 tan ()

Trả về tang của giá trị kép được chỉ định.

21 asin ()

Trả về arcsine của giá trị kép được chỉ định.

22 acos ()

Trả về arccosine của giá trị kép được chỉ định.

23 atan ()

Trả về arctang của giá trị kép được chỉ định.

24 atan2 ()

Chuyển đổi tọa độ hình chữ nhật (x, y) thành tọa độ cực (r, theta) và trả về theta.

25 toDegrees ()

Chuyển đổi đối số thành độ.

26 toRadians ()

Chuyển đổi đối số thành radian.

27 ngẫu nhiên ()

Trả về một số ngẫu nhiên.

Tiếp theo là gì?

Trong phần tiếp theo, chúng ta sẽ đi qua lớp Character trong Java. Bạn sẽ học cách sử dụng các Ký tự đối tượng và kiểu dữ liệu nguyên thủy char trong Java.

Thông thường, khi chúng ta làm việc với các ký tự, chúng ta sử dụng kiểu dữ liệu nguyên thủy char.

Thí dụ

char ch = 'a';

// Unicode for uppercase Greek omega character
char uniChar = '\u039A'; 

// an array of chars
char[] charArray ={ 'a', 'b', 'c', 'd', 'e' };

Tuy nhiên trong quá trình phát triển, chúng ta gặp phải những tình huống mà chúng ta cần sử dụng các đối tượng thay vì các kiểu dữ liệu nguyên thủy. Để đạt được điều này, Java cung cấp lớp trình bao bọcCharacter cho kiểu dữ liệu nguyên thủy char.

Lớp Character cung cấp một số phương thức hữu ích của lớp (tức là, tĩnh) để thao tác các ký tự. Bạn có thể tạo một đối tượng Character với hàm tạo Character -

Character ch = new Character('a');

Trình biên dịch Java cũng sẽ tạo một đối tượng Character cho bạn trong một số trường hợp. Ví dụ: nếu bạn truyền một ký tự nguyên thủy vào một phương thức mong đợi một đối tượng, trình biên dịch sẽ tự động chuyển đổi ký tự này thành Ký tự cho bạn. Tính năng này được gọi là autoboxing hoặc unboxing, nếu quá trình chuyển đổi diễn ra theo hướng khác.

Thí dụ

// Here following primitive char 'a'
// is boxed into the Character object ch
Character ch = 'a';

// Here primitive 'x' is boxed for method test,
// return is unboxed to char 'c'
char c = test('x');

Trình tự thoát

Một ký tự đứng trước dấu gạch chéo ngược (\) là một chuỗi thoát và có ý nghĩa đặc biệt đối với trình biên dịch.

Ký tự dòng mới (\ n) đã được sử dụng thường xuyên trong hướng dẫn này trong các câu lệnh System.out.println () để chuyển sang dòng tiếp theo sau khi chuỗi được in.

Bảng sau đây cho thấy các trình tự thoát Java:

Trình tự thoát Sự miêu tả
\ t Chèn một tab trong văn bản tại điểm này.
\ b Chèn một backspace trong văn bản tại điểm này.
\ n Chèn một dòng mới trong văn bản tại điểm này.
\ r Chèn một dấu xuống dòng trong văn bản tại thời điểm này.
\ f Chèn một nguồn cấp dữ liệu biểu mẫu vào văn bản tại điểm này.
\ ' Chèn một ký tự trích dẫn duy nhất trong văn bản tại thời điểm này.
\ " Chèn một ký tự dấu ngoặc kép vào văn bản tại thời điểm này.
\\ Chèn một ký tự gạch chéo ngược trong văn bản tại điểm này.

Khi gặp trình tự thoát trong một câu lệnh in, trình biên dịch sẽ diễn giải nó theo đó.

Thí dụ

Nếu bạn muốn đặt dấu ngoặc kép trong dấu ngoặc kép, bạn phải sử dụng trình tự thoát, \ ", trên dấu ngoặc kép bên trong -

public class Test {

   public static void main(String args[]) {
      System.out.println("She said \"Hello!\" to me.");
   }
}

Điều này sẽ tạo ra kết quả sau:

Đầu ra

She said "Hello!" to me.

Phương thức ký tự

Sau đây là danh sách các phương thức cá thể quan trọng mà tất cả các lớp con của lớp Character triển khai:

Sr.No. Phương pháp & Mô tả
1 isLetter ()

Xác định xem giá trị char đã chỉ định có phải là một chữ cái hay không.

2 isDigit ()

Xác định xem giá trị char đã chỉ định có phải là một chữ số hay không.

3 isWhitespace ()

Xác định xem giá trị char đã chỉ định có phải là khoảng trắng hay không.

4 isUpperCase ()

Xác định xem giá trị char đã chỉ định có phải là chữ hoa hay không.

5 isLowerCase ()

Xác định xem giá trị char đã chỉ định có phải là chữ thường hay không.

6 Đến trường hợp trên()

Trả về dạng chữ hoa của giá trị char đã chỉ định.

7 toLowerCase ()

Trả về dạng chữ thường của giá trị char đã chỉ định.

số 8 toString ()

Trả về một đối tượng Chuỗi đại diện cho giá trị ký tự được chỉ định, một chuỗi một ký tự.

Để có danh sách đầy đủ các phương pháp, vui lòng tham khảo đặc tả API java.lang.Character.

Tiếp theo là gì?

Trong phần tiếp theo, chúng ta sẽ đi qua lớp String trong Java. Bạn sẽ học cách khai báo và sử dụng Chuỗi một cách hiệu quả cũng như một số phương thức quan trọng trong lớp Chuỗi.

Chuỗi, được sử dụng rộng rãi trong lập trình Java, là một chuỗi các ký tự. Trong ngôn ngữ lập trình Java, các chuỗi được coi như các đối tượng.

Nền tảng Java cung cấp lớp String để tạo và thao tác các chuỗi.

Tạo chuỗi

Cách trực tiếp nhất để tạo một chuỗi là viết:

String greeting = "Hello world!";

Bất cứ khi nào nó gặp một chuỗi ký tự trong mã của bạn, trình biên dịch sẽ tạo một đối tượng Chuỗi với giá trị của nó trong trường hợp này là "Hello world!".

Như với bất kỳ đối tượng nào khác, bạn có thể tạo các đối tượng Chuỗi bằng cách sử dụng từ khóa mới và một hàm tạo. Lớp String có 11 hàm tạo cho phép bạn cung cấp giá trị ban đầu của chuỗi bằng các nguồn khác nhau, chẳng hạn như một mảng ký tự.

Thí dụ

public class StringDemo {

   public static void main(String args[]) {
      char[] helloArray = { 'h', 'e', 'l', 'l', 'o', '.' };
      String helloString = new String(helloArray);  
      System.out.println( helloString );
   }
}

Điều này sẽ tạo ra kết quả sau:

Đầu ra

hello.

Note- Lớp String là bất biến, vì vậy khi nó được tạo ra, một đối tượng String không thể thay đổi. Nếu cần thiết phải thực hiện nhiều sửa đổi đối với Chuỗi ký tự, thì bạn nên sử dụng Bộ đệm chuỗi & Lớp xây dựng chuỗi .

Chiều dài chuỗi

Các phương pháp được sử dụng để thu thập thông tin về một đối tượng được gọi là accessor methods. Một phương thức truy cập mà bạn có thể sử dụng với các chuỗi là phương thức length (), phương thức này trả về số ký tự có trong đối tượng chuỗi.

Chương trình sau đây là một ví dụ về length(), method String class.

Thí dụ

public class StringDemo {

   public static void main(String args[]) {
      String palindrome = "Dot saw I was Tod";
      int len = palindrome.length();
      System.out.println( "String Length is : " + len );
   }
}

Điều này sẽ tạo ra kết quả sau:

Đầu ra

String Length is : 17

Nối các chuỗi

Lớp String bao gồm một phương thức để nối hai chuỗi:

string1.concat(string2);

Điều này trả về một chuỗi mới là string1 với string2 được thêm vào ở cuối. Bạn cũng có thể sử dụng phương thức concat () với chuỗi ký tự, như trong -

"My name is ".concat("Zara");

Các chuỗi thường được nối với toán tử +, như trong -

"Hello," + " world" + "!"

kết quả là -

"Hello, world!"

Chúng ta hãy xem ví dụ sau:

Thí dụ

public class StringDemo {

   public static void main(String args[]) {
      String string1 = "saw I was ";
      System.out.println("Dot " + string1 + "Tod");
   }
}

Điều này sẽ tạo ra kết quả sau:

Đầu ra

Dot saw I was Tod

Tạo chuỗi định dạng

Bạn có phương thức printf () và format () để in đầu ra với các số được định dạng. Lớp String có một phương thức lớp tương đương, format (), trả về một đối tượng String chứ không phải là một đối tượng PrintStream.

Sử dụng phương thức static format () của String cho phép bạn tạo một chuỗi được định dạng mà bạn có thể sử dụng lại, trái ngược với câu lệnh in một lần. Ví dụ, thay vì -

Thí dụ

System.out.printf("The value of the float variable is " +
                  "%f, while the value of the integer " +
                  "variable is %d, and the string " +
                  "is %s", floatVar, intVar, stringVar);

Bạn có thể viết -

String fs;
fs = String.format("The value of the float variable is " +
                   "%f, while the value of the integer " +
                   "variable is %d, and the string " +
                   "is %s", floatVar, intVar, stringVar);
System.out.println(fs);

Phương thức chuỗi

Đây là danh sách các phương thức được hỗ trợ bởi lớp String -

Sr.No. Phương pháp & Mô tả
1 char charAt (int index)

Trả về ký tự tại chỉ mục được chỉ định.

2 int CompareTo (Đối tượng o)

So sánh chuỗi này với một đối tượng khác.

3 int so sánhTo (Chuỗi khác Chuỗi)

So sánh hai chuỗi về mặt từ vựng.

4 int so sánhToIgnoreCase (Chuỗi str)

So sánh hai chuỗi về mặt từ vựng, bỏ qua sự khác biệt về chữ hoa và chữ thường.

5 String concat (String str)

Nối chuỗi được chỉ định với phần cuối của chuỗi này.

6 boolean contentEquals (StringBuffer sb)

Trả về true nếu và chỉ khi Chuỗi này đại diện cho cùng một chuỗi ký tự như StringBuffer được chỉ định.

7 static String copyValueOf (dữ liệu char [])

Trả về một Chuỗi đại diện cho chuỗi ký tự trong mảng được chỉ định.

số 8 static String copyValueOf (char [] data, int offset, int count)

Trả về một Chuỗi đại diện cho chuỗi ký tự trong mảng được chỉ định.

9 boolean endWith (Hậu tố chuỗi)

Kiểm tra xem chuỗi này có kết thúc bằng hậu tố được chỉ định hay không.

10 boolean bằng (Đối tượng anObject)

So sánh chuỗi này với đối tượng được chỉ định.

11 boolean equalsIgnoreCase (Chuỗi khác Chuỗi)

So sánh Chuỗi này với Chuỗi khác, bỏ qua các cân nhắc về chữ hoa và chữ thường.

12 byte getBytes ()

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

13 byte [] getBytes (String charsetName)

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

14 void getChars (int srcBegin, int srcEnd, char [] dst, int dstBegin)

Sao chép các ký tự từ chuỗi này vào mảng ký tự đích.

15 int hashCode ()

Trả về mã băm cho chuỗi này.

16 int indexOf (int ch)

Trả về chỉ mục trong chuỗi này của lần xuất hiện đầu tiên của ký tự được chỉ định.

17 int indexOf (int ch, int fromIndex)

Trả về chỉ mục trong chuỗi này của lần xuất hiện đầu tiên của ký tự được chỉ định, bắt đầu tìm kiếm tại chỉ mục được chỉ định.

18 int indexOf (Chuỗi str)

Trả về chỉ mục trong chuỗi này của lần xuất hiện đầu tiên của chuỗi con được chỉ định.

19 int indexOf (Chuỗi str, int fromIndex)

Trả về chỉ mục trong chuỗi này của lần xuất hiện đầu tiên của chuỗi con được chỉ định, bắt đầu từ chỉ mục được chỉ định.

20 String thực tập ()

Trả về một biểu diễn chính tắc cho đối tượng chuỗi.

21 int lastIndexOf (int ch)

Trả về chỉ mục trong chuỗi này về lần xuất hiện cuối cùng của ký tự được chỉ định.

22 int lastIndexOf (int ch, int fromIndex)

Trả về chỉ mục trong chuỗi này về lần xuất hiện cuối cùng của ký tự được chỉ định, tìm kiếm ngược lại bắt đầu từ chỉ mục đã chỉ định.

23 int lastIndexOf (Chuỗi str)

Trả về chỉ mục trong chuỗi này về lần xuất hiện ngoài cùng bên phải của chuỗi con được chỉ định.

24 int lastIndexOf (Chuỗi str, int fromIndex)

Trả về chỉ mục trong chuỗi này của lần xuất hiện cuối cùng của chuỗi con được chỉ định, tìm kiếm ngược lại bắt đầu từ chỉ mục đã chỉ định.

25 int length ()

Trả về độ dài của chuỗi này.

26 so khớp boolean (Chuỗi regex)

Cho biết chuỗi này có khớp với biểu thức chính quy đã cho hay không.

27 boolean regionMatches (boolean ignoreCase, int toffset, String other, int ooffset, int len)

Kiểm tra xem hai vùng chuỗi có bằng nhau không.

28 boolean regionMatches (int toffset, String other, int ooffset, int len)

Kiểm tra xem hai vùng chuỗi có bằng nhau không.

29 Thay thế chuỗi (char oldChar, char newChar)

Trả về một chuỗi mới do thay thế tất cả các lần xuất hiện của oldChar trong chuỗi này bằng newChar.

30 String ReplaceAll (String regex, String Replace

Thay thế từng chuỗi con của chuỗi này phù hợp với biểu thức chính quy đã cho bằng thay thế đã cho.

31 Chuỗi thay thếFirst (Chuỗi regex, Chuỗi thay thế)

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 đã cho bằng chuỗi thay thế đã cho.

32 Chuỗi [] tách (Chuỗi regex)

Tách chuỗi này xung quanh các kết quả phù hợp của biểu thức chính quy đã cho.

33 String [] split (String regex, int limit)

Tách chuỗi này xung quanh các kết quả phù hợp của biểu thức chính quy đã cho.

34 boolean startedWith (Tiền tố chuỗi)

Kiểm tra xem chuỗi này có bắt đầu bằng tiền tố được chỉ định hay không.

35 boolean startedWith (Tiền tố chuỗi, int toffset)

Kiểm tra xem chuỗi này có bắt đầu bằng tiền tố được chỉ định bắt đầu một chỉ mục được chỉ định không.

36 CharSequence subSequence (int beginIndex, int endIndex)

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

37 Chuỗi con (int beginIndex)

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

38 Chuỗi con (int beginIndex, int endIndex)

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

39 char [] toCharArray ()

Chuyển đổi chuỗi này thành một mảng ký tự mới.

40 Chuỗi toLowerCase ()

Chuyển đổi tất cả các ký tự trong Chuỗi này thành chữ thường bằng cách sử dụng các quy tắc của ngôn ngữ mặc định.

41 String toLowerCase (Locale locale)

Chuyển đổi tất cả các ký tự trong Chuỗi này thành chữ thường bằng cách sử dụng các quy tắc của Ngôn ngữ đã cho.

42 Chuỗi toString ()

Đối tượng này (đã là một chuỗi!) Được trả về chính nó.

43 Chuỗi toUpperCase ()

Chuyển đổi tất cả các ký tự trong Chuỗi này thành chữ hoa bằng cách sử dụng các quy tắc của ngôn ngữ mặc định.

44 String toUpperCase (Locale locale)

Chuyển đổi tất cả các ký tự trong Chuỗi này thành chữ hoa bằng cách sử dụng các quy tắc của Ngôn ngữ đã cho.

45 Xén chuỗi ()

Trả về bản sao của chuỗi, với khoảng trắng đầu và cuối bị bỏ qua.

46 static String valueOf (kiểu dữ liệu nguyên thủy x)

Trả về biểu diễn chuỗi của đối số kiểu dữ liệu đã truyền.

Java cung cấp một cấu trúc dữ liệu, array, nơi lưu trữ một tập hợp tuần tự có kích thước cố định của các phần tử cùng loại. Mảng được sử dụng để lưu trữ một tập hợp dữ liệu, nhưng thường hữu ích hơn nếu coi một mảng là một tập hợp các biến cùng kiểu.

Thay vì khai báo các biến riêng lẻ, chẳng hạn như number0, number1, ... và number99, bạn khai báo một biến mảng chẳng hạn như số và sử dụng số [0], số [1] và ..., số [99] để biểu diễn các biến riêng lẻ.

Hướng dẫn này giới thiệu cách khai báo biến mảng, tạo mảng và xử lý mảng bằng cách sử dụng các biến được lập chỉ mục.

Khai báo biến mảng

Để sử dụng mảng trong chương trình, bạn phải khai báo một biến để tham chiếu đến mảng và bạn phải chỉ định kiểu mảng mà biến có thể tham chiếu. Đây là cú pháp để khai báo một biến mảng:

Cú pháp

dataType[] arrayRefVar;   // preferred way.
or
dataType arrayRefVar[];  // works but not preferred way.

Note - Phong cách dataType[] arrayRefVarđược ưa thích. Phong cáchdataType arrayRefVar[] đến từ ngôn ngữ C / C ++ và được sử dụng trong Java để phù hợp với các lập trình viên C / C ++.

Thí dụ

Các đoạn mã sau là ví dụ về cú pháp này:

double[] myList;   // preferred way.
or
double myList[];   // works but not preferred way.

Tạo Mảng

Bạn có thể tạo một mảng bằng cách sử dụng toán tử mới với cú pháp sau:

Cú pháp

arrayRefVar = new dataType[arraySize];

Câu lệnh trên thực hiện hai điều -

  • Nó tạo ra một mảng bằng cách sử dụng dataType [arraySize] mới.

  • Nó gán tham chiếu của mảng mới tạo cho biến arrayRefVar.

Khai báo một biến mảng, tạo một mảng và gán tham chiếu của mảng cho biến có thể được kết hợp trong một câu lệnh, như được hiển thị bên dưới:

dataType[] arrayRefVar = new dataType[arraySize];

Ngoài ra, bạn có thể tạo các mảng như sau:

dataType[] arrayRefVar = {value0, value1, ..., valuek};

Các phần tử mảng được truy cập thông qua index. Chỉ số mảng dựa trên 0; nghĩa là, chúng bắt đầu từ 0 đếnarrayRefVar.length-1.

Thí dụ

Câu lệnh sau khai báo một biến mảng, myList, tạo một mảng gồm 10 phần tử kiểu kép và gán tham chiếu của nó cho myList:

double[] myList = new double[10];

Hình sau đại diện cho mảng myList. Ở đây, myList chứa mười giá trị kép và các chỉ số từ 0 đến 9.

Mảng xử lý

Khi xử lý các phần tử mảng, chúng ta thường sử dụng for vòng lặp hoặc foreach vòng lặp vì tất cả các phần tử trong một mảng có cùng kiểu và kích thước của mảng đã biết.

Thí dụ

Dưới đây là một ví dụ đầy đủ cho thấy cách tạo, khởi tạo và xử lý mảng -

public class TestArray {

   public static void main(String[] args) {
      double[] myList = {1.9, 2.9, 3.4, 3.5};

      // Print all the array elements
      for (int i = 0; i < myList.length; i++) {
         System.out.println(myList[i] + " ");
      }
     
      // Summing all elements
      double total = 0;
      for (int i = 0; i < myList.length; i++) {
         total += myList[i];
      }
      System.out.println("Total is " + total);
      
      // Finding the largest element
      double max = myList[0];
      for (int i = 1; i < myList.length; i++) {
         if (myList[i] > max) max = myList[i];
      }
      System.out.println("Max is " + max);  
   }
}

Điều này sẽ tạo ra kết quả sau:

Đầu ra

1.9
2.9
3.4
3.5
Total is 11.7
Max is 3.5

Vòng lặp foreach

JDK 1.5 đã giới thiệu một vòng lặp for mới được gọi là vòng lặp foreach hoặc vòng lặp for nâng cao, cho phép bạn duyệt toàn bộ mảng một cách tuần tự mà không cần sử dụng biến chỉ mục.

Thí dụ

Đoạn mã sau hiển thị tất cả các phần tử trong mảng myList:

public class TestArray {

   public static void main(String[] args) {
      double[] myList = {1.9, 2.9, 3.4, 3.5};

      // Print all the array elements
      for (double element: myList) {
         System.out.println(element);
      }
   }
}

Điều này sẽ tạo ra kết quả sau:

Đầu ra

1.9
2.9
3.4
3.5

Truyền Mảng cho các Phương thức

Cũng giống như bạn có thể truyền các giá trị kiểu nguyên thủy cho các phương thức, bạn cũng có thể truyền mảng cho các phương thức. Ví dụ: phương pháp sau đây hiển thị các phần tử trongint mảng -

Thí dụ

public static void printArray(int[] array) {
   for (int i = 0; i < array.length; i++) {
      System.out.print(array[i] + " ");
   }
}

Bạn có thể gọi nó bằng cách truyền một mảng. Ví dụ: câu lệnh sau gọi phương thức printArray để hiển thị 3, 1, 2, 6, 4 và 2 -

Thí dụ

printArray(new int[]{3, 1, 2, 6, 4, 2});

Trả về một mảng từ một phương thức

Một phương thức cũng có thể trả về một mảng. Ví dụ, phương thức sau đây trả về một mảng là sự đảo ngược của một mảng khác:

Thí dụ

public static int[] reverse(int[] list) {
   int[] result = new int[list.length];

   for (int i = 0, j = result.length - 1; i < list.length; i++, j--) {
      result[j] = list[i];
   }
   return result;
}

Lớp Mảng

Lớp java.util.Arrays chứa các phương thức tĩnh khác nhau để sắp xếp và tìm kiếm mảng, so sánh các mảng và điền vào các phần tử của mảng. Các phương thức này được nạp chồng cho tất cả các kiểu nguyên thủy.

Sr.No. Phương pháp & Mô tả
1

public static int binarySearch(Object[] a, Object key)

Tìm kiếm mảng Đối tượng được chỉ định (Byte, Int, double, v.v.) cho giá trị được chỉ định bằng cách sử dụng thuật toán tìm kiếm nhị phân. Mảng phải được sắp xếp trước khi thực hiện cuộc gọi này. Điều này trả về chỉ mục của khóa tìm kiếm, nếu nó được chứa trong danh sách; nếu không, nó trả về (- (điểm chèn + 1)).

2

public static boolean equals(long[] a, long[] a2)

Trả về true nếu hai mảng độ dài được chỉ định bằng nhau. Hai mảng được coi là bằng nhau nếu cả hai mảng chứa cùng một số phần tử và tất cả các cặp phần tử tương ứng trong hai mảng đều bằng nhau. Điều này trả về true nếu hai mảng bằng nhau. Tất cả các kiểu dữ liệu nguyên thủy khác có thể sử dụng cùng một phương pháp (Byte, short, Int, v.v.)

3

public static void fill(int[] a, int val)

Gán giá trị int đã chỉ định cho mỗi phần tử của mảng int được chỉ định. Phương pháp tương tự có thể được sử dụng bởi tất cả các kiểu dữ liệu nguyên thủy khác (Byte, short, Int, v.v.)

4

public static void sort(Object[] a)

Sắp xếp mảng đối tượng được chỉ định theo thứ tự tăng dần, theo thứ tự tự nhiên của các phần tử của nó. Phương pháp tương tự có thể được sử dụng bởi tất cả các kiểu dữ liệu nguyên thủy khác (Byte, short, Int, v.v.)

Java cung cấp Date lớp học có sẵn trong java.util gói, lớp này đóng gói ngày và giờ hiện tại.

Lớp Date hỗ trợ hai hàm tạo như được hiển thị trong bảng sau.

Sr.No. Hàm tạo & Mô tả
1

Date( )

Hàm tạo này khởi tạo đối tượng với ngày và giờ hiện tại.

2

Date(long millisec)

Hàm tạo này chấp nhận một đối số bằng số mili giây đã trôi qua kể từ nửa đêm, ngày 1 tháng 1 năm 1970.

Sau đây là các phương thức của lớp ngày.

Sr.No. Phương pháp & Mô tả
1

boolean after(Date date)

Trả về true nếu đối tượng Date đang gọi chứa ngày muộn hơn ngày được chỉ định bởi ngày tháng, nếu không, nó trả về false.

2

boolean before(Date date)

Trả về true nếu đối tượng Date đang gọi có chứa ngày sớm hơn ngày được chỉ định bởi ngày tháng, nếu không, nó trả về false.

3

Object clone( )

Nhân bản đối tượng Ngày đang gọi.

4

int compareTo(Date date)

So sánh giá trị của đối tượng đang gọi với giá trị của ngày tháng. Trả về 0 nếu các giá trị bằng nhau. Trả về giá trị âm nếu đối tượng gọi sớm hơn ngày. Trả về giá trị dương nếu đối tượng gọi muộn hơn ngày.

5

int compareTo(Object obj)

Hoạt động giống hệt nhau để so sánhTo (Ngày) nếu obj thuộc lớp Ngày. Nếu không, nó ném một ClassCastException.

6

boolean equals(Object date)

Trả về true nếu đối tượng Date đang gọi chứa cùng ngày và giờ với đối tượng được chỉ định theo ngày, ngược lại, nó trả về false.

7

long getTime( )

Trả về số mili giây đã trôi qua kể từ ngày 1 tháng 1 năm 1970.

số 8

int hashCode( )

Trả về mã băm cho đối tượng đang gọi.

9

void setTime(long time)

Đặt thời gian và ngày như được chỉ định theo thời gian, biểu thị thời gian đã trôi qua tính bằng mili giây từ nửa đêm, ngày 1 tháng 1 năm 1970.

10

String toString( )

Chuyển đổi đối tượng Date đang gọi thành một chuỗi và trả về kết quả.

Lấy ngày và giờ hiện tại

Đây là một phương pháp rất dễ dàng để lấy ngày và giờ hiện tại trong Java. Bạn có thể sử dụng một đối tượng Date đơn giản với phương thức toString () để in ngày và giờ hiện tại như sau:

Thí dụ

import java.util.Date;
public class DateDemo {

   public static void main(String args[]) {
      // Instantiate a Date object
      Date date = new Date();

      // display time and date using toString()
      System.out.println(date.toString());
   }
}

Điều này sẽ tạo ra kết quả sau:

Đầu ra

on May 04 09:51:52 CDT 2009

So sánh ngày

Sau đây là ba cách để so sánh hai ngày:

  • Bạn có thể sử dụng getTime () để lấy số mili giây đã trôi qua kể từ nửa đêm, ngày 1 tháng 1 năm 1970, cho cả hai đối tượng và sau đó so sánh hai giá trị này.

  • Bạn có thể sử dụng các phương thức trước (), sau () và bằng (). Vì ngày 12 của tháng đến trước ngày 18, ví dụ: new Date (99, 2, 12) .before (new Date (99, 2, 18)) trả về true.

  • Bạn có thể sử dụng phương thức CompareTo (), được xác định bởi giao diện So sánh và được triển khai theo Ngày.

Định dạng ngày bằng SimpleDateFormat

SimpleDateFormat là một lớp cụ thể để định dạng và phân tích cú pháp ngày tháng theo cách nhạy cảm với ngôn ngữ. SimpleDateFormat cho phép bạn bắt đầu bằng cách chọn bất kỳ mẫu nào do người dùng xác định để định dạng ngày-giờ.

Thí dụ

import java.util.*;
import java.text.*;

public class DateDemo {

   public static void main(String args[]) {
      Date dNow = new Date( );
      SimpleDateFormat ft = 
      new SimpleDateFormat ("E yyyy.MM.dd 'at' hh:mm:ss a zzz");

      System.out.println("Current Date: " + ft.format(dNow));
   }
}

Điều này sẽ tạo ra kết quả sau:

Đầu ra

Current Date: Sun 2004.07.18 at 04:14:09 PM PDT

Mã định dạng ngày tháng đơn giản

Để chỉ định định dạng thời gian, hãy sử dụng chuỗi mẫu thời gian. Trong mẫu này, tất cả các chữ cái ASCII được dành riêng dưới dạng chữ cái mẫu, được định nghĩa như sau:

Tính cách Sự miêu tả Thí dụ
G Người chỉ định kỷ nguyên QUẢNG CÁO
y Năm có bốn chữ số 2001
M Tháng trong năm Tháng bảy hoặc 07
d Ngày trong tháng 10
h Giờ tính theo SA / CH (1 ~ 12) 12
H Giờ trong ngày (0 ~ 23) 22
m Phút sau giờ 30
S Giây sau phút 55
S Mili giây 234
E Ngày trong tuần Thứ ba
D Ngày trong năm 360
F Ngày trong tuần trong tháng 2 (thứ tư thứ hai trong tháng bảy)
w Tuần trong năm 40
W Tuần trong tháng 1
a Điểm đánh dấu AM / PM BUỔI CHIỀU
k Giờ trong ngày (1 ~ 24) 24
K Giờ SAU / CH (0 ~ 11) 10
z Múi giờ giờ chuẩn phương Đông
' Thoát cho văn bản Dấu phân cách
" Trích dẫn duy nhất `

Định dạng ngày bằng printf

Định dạng ngày và giờ có thể được thực hiện rất dễ dàng bằng cách sử dụng printfphương pháp. Bạn sử dụng định dạng hai chữ cái, bắt đầu bằngt và kết thúc bằng một trong các chữ cái của bảng như trong đoạn mã sau.

Thí dụ

import java.util.Date;
public class DateDemo {

   public static void main(String args[]) {
      // Instantiate a Date object
      Date date = new Date();

      // display time and date
      String str = String.format("Current Date/Time : %tc", date );

      System.out.printf(str);
   }
}

Điều này sẽ tạo ra kết quả sau:

Đầu ra

Current Date/Time : Sat Dec 15 16:37:57 MST 2012

Sẽ hơi ngớ ngẩn nếu bạn phải cung cấp ngày tháng nhiều lần để định dạng từng phần. Vì lý do đó, một chuỗi định dạng có thể chỉ ra chỉ mục của đối số được định dạng.

Chỉ mục phải ngay lập tức theo sau% và nó phải được kết thúc bằng $.

Thí dụ

import java.util.Date;
public class DateDemo {

   public static void main(String args[]) {
      // Instantiate a Date object
      Date date = new Date();
  
      // display time and date
      System.out.printf("%1$s %2$tB %2$td, %2$tY", "Due date:", date);
   }
}

Điều này sẽ tạo ra kết quả sau:

Đầu ra

Due date: February 09, 2004

Ngoài ra, bạn có thể sử dụng cờ <. Nó chỉ ra rằng đối số tương tự như trong đặc tả định dạng trước đó sẽ được sử dụng lại.

Thí dụ

import java.util.Date;
public class DateDemo {

   public static void main(String args[]) {
      // Instantiate a Date object
      Date date = new Date();
  
      // display formatted date
      System.out.printf("%s %tB %<te, %<tY", "Due date:", date);
   }
}

Điều này sẽ tạo ra kết quả sau:

Đầu ra

Due date: February 09, 2004

Các ký tự chuyển đổi ngày và giờ

Tính cách Sự miêu tả Thí dụ
c Ngày và giờ đầy đủ Thứ Hai, 04 tháng 05 09:51:52 CĐT 2009
F Ngày ISO 8601 2004-02-09
D Ngày được định dạng ở Hoa Kỳ (tháng / ngày / năm) 02/09/2004
T Thời gian 24 giờ 18:05:19
r Thời gian 12 giờ 06:05:19 chiều
R Thời gian 24 giờ, không giây 18:05
Y Năm có bốn chữ số (với các số 0 đứng đầu) 2004
y Hai chữ số cuối cùng của năm (với các số 0 đứng đầu) 04
C Hai chữ số đầu tiên của năm (với các số 0 đứng đầu) 20
B Tên tháng đầy đủ tháng 2
b Tên tháng viết tắt Tháng hai
m Tháng có hai chữ số (với các số 0 ở đầu) 02
d Ngày có hai chữ số (với các số 0 ở đầu) 03
e Ngày có hai chữ số (không có số 0 ở đầu) 9
A Tên đầy đủ các ngày trong tuần Thứ hai
a Tên ngày trong tuần viết tắt Thứ hai
j Ngày có ba chữ số trong năm (với các số 0 ở đầu) 069
H Giờ có hai chữ số (với các số 0 ở đầu), từ 00 đến 23 18
k Giờ có hai chữ số (không có số 0 ở đầu), từ 0 đến 23 18
Tôi Giờ có hai chữ số (với các số 0 ở đầu), từ 01 đến 12 06
l Giờ có hai chữ số (không có số 0 ở đầu), từ 1 đến 12 6
M Phút có hai chữ số (với các số 0 ở đầu) 05
S Giây có hai chữ số (với các số 0 ở đầu) 19
L Ba chữ số mili giây (với các số 0 ở đầu) 047
N Chín chữ số nano giây (với các số 0 ở đầu) 047000000
P Viết hoa điểm đánh dấu buổi sáng hoặc buổi chiều BUỔI CHIỀU
p Viết thường điểm đánh dấu buổi sáng hoặc buổi chiều buổi chiều
z RFC 822 bù số từ GMT -0800
Z Múi giờ PST
S Giây kể từ 1970-01-01 00:00:00 GMT 1078884319
Q Mili giây kể từ 1970-01-01 00:00:00 GMT 1078884319047

Có các lớp hữu ích khác liên quan đến Ngày và giờ. Để biết thêm chi tiết, bạn có thể tham khảo tài liệu Java Standard.

Phân tích cú pháp chuỗi thành ngày

Lớp SimpleDateFormat có một số phương thức bổ sung, đáng chú ý là parse (), nó cố gắng phân tích cú pháp một chuỗi theo định dạng được lưu trữ trong đối tượng SimpleDateFormat đã cho.

Thí dụ

import java.util.*;
import java.text.*;
  
public class DateDemo {

   public static void main(String args[]) {
      SimpleDateFormat ft = new SimpleDateFormat ("yyyy-MM-dd"); 
      String input = args.length == 0 ? "1818-11-11" : args[0]; 

      System.out.print(input + " Parses as "); 
      Date t;
      try {
         t = ft.parse(input); 
         System.out.println(t); 
      } catch (ParseException e) { 
         System.out.println("Unparseable using " + ft); 
      }
   }
}

Một lần chạy mẫu của chương trình trên sẽ tạo ra kết quả sau:

Đầu ra

1818-11-11 Parses as Wed Nov 11 00:00:00 EST 1818

Ngủ một lúc

Bạn có thể ngủ trong bất kỳ khoảng thời gian nào từ một phần nghìn giây cho đến thời gian tồn tại của máy tính. Ví dụ: chương trình sau sẽ ngủ trong 3 giây -

Thí dụ

import java.util.*;
public class SleepDemo {

   public static void main(String args[]) {
      try { 
         System.out.println(new Date( ) + "\n"); 
         Thread.sleep(5*60*10); 
         System.out.println(new Date( ) + "\n"); 
      } catch (Exception e) {
         System.out.println("Got an exception!"); 
      }
   }
}

Điều này sẽ tạo ra kết quả sau:

Đầu ra

Sun May 03 18:04:41 GMT 2009
Sun May 03 18:04:51 GMT 2009

Đo thời gian đã trôi qua

Đôi khi, bạn có thể cần đo thời gian bằng mili giây. Vì vậy, hãy viết lại ví dụ trên một lần nữa -

Thí dụ

import java.util.*;
public class DiffDemo {

   public static void main(String args[]) {
      try {
         long start = System.currentTimeMillis( );
         System.out.println(new Date( ) + "\n");
         
         Thread.sleep(5*60*10);
         System.out.println(new Date( ) + "\n");
         
         long end = System.currentTimeMillis( );
         long diff = end - start;
         System.out.println("Difference is : " + diff);
      } catch (Exception e) {
         System.out.println("Got an exception!");
      }
   }
}

Điều này sẽ tạo ra kết quả sau:

Đầu ra

Sun May 03 18:16:51 GMT 2009
Sun May 03 18:16:57 GMT 2009
Difference is : 5993

Lớp GregorianCalendar

GregorianCalendar là một triển khai cụ thể của một lớp Lịch triển khai lịch Gregorian bình thường mà bạn đã quen thuộc. Chúng tôi không thảo luận về lớp Lịch trong hướng dẫn này, bạn có thể tra cứu tài liệu Java tiêu chuẩn cho việc này.

Các getInstance( )phương thức Lịch trả về một GregorianCalendar được khởi tạo với ngày và giờ hiện tại ở miền địa phương và múi giờ mặc định. GregorianCalendar định nghĩa hai trường: AD và BC. Chúng đại diện cho hai thời đại được xác định bởi lịch Gregory.

Ngoài ra còn có một số hàm tạo cho các đối tượng GregorianCalendar -

Sr.No. Hàm tạo & Mô tả
1

GregorianCalendar()

Tạo một GregorianCalendar mặc định sử dụng thời gian hiện tại trong múi giờ mặc định với ngôn ngữ mặc định.

2

GregorianCalendar(int year, int month, int date)

Tạo một GregorianCalendar với ngày cụ thể được đặt trong múi giờ mặc định với ngôn ngữ mặc định.

3

GregorianCalendar(int year, int month, int date, int hour, int minute)

Tạo GregorianCalendar với ngày và giờ nhất định được đặt cho múi giờ mặc định với ngôn ngữ mặc định.

4

GregorianCalendar(int year, int month, int date, int hour, int minute, int second)

Tạo GregorianCalendar với ngày và giờ nhất định được đặt cho múi giờ mặc định với ngôn ngữ mặc định.

5

GregorianCalendar(Locale aLocale)

Tạo GregorianCalendar dựa trên thời gian hiện tại trong múi giờ mặc định với ngôn ngữ nhất định.

6

GregorianCalendar(TimeZone zone)

Tạo GregorianCalendar dựa trên thời gian hiện tại trong múi giờ nhất định với ngôn ngữ mặc định.

7

GregorianCalendar(TimeZone zone, Locale aLocale)

Tạo GregorianCalendar dựa trên thời gian hiện tại trong múi giờ nhất định với ngôn ngữ nhất định.

Dưới đây là danh sách một số phương pháp hỗ trợ hữu ích được cung cấp bởi lớp GregorianCalendar -

Sr.No. Phương pháp & Mô tả
1

void add(int field, int amount)

Thêm khoảng thời gian được chỉ định (đã ký) vào trường thời gian nhất định, dựa trên quy tắc của lịch.

2

protected void computeFields()

Chuyển đổi UTC dưới dạng mili giây thành các giá trị trường thời gian.

3

protected void computeTime()

Ghi đè Lịch Chuyển đổi giá trị trường thời gian thành UTC dưới dạng mili giây.

4

boolean equals(Object obj)

So sánh GregorianCalendar này với một tham chiếu đối tượng.

5

int get(int field)

Nhận giá trị cho một trường thời gian nhất định.

6

int getActualMaximum(int field)

Trả về giá trị lớn nhất mà trường này có thể có, cho ngày hiện tại.

7

int getActualMinimum(int field)

Trả về giá trị nhỏ nhất mà trường này có thể có, cho ngày hiện tại.

số 8

int getGreatestMinimum(int field)

Trả về giá trị nhỏ nhất cao nhất cho trường đã cho nếu thay đổi.

9

Date getGregorianChange()

Nhận ngày thay đổi Lịch Gregorian.

10

int getLeastMaximum(int field)

Trả về giá trị lớn nhất thấp nhất cho trường đã cho nếu thay đổi.

11

int getMaximum(int field)

Trả về giá trị lớn nhất cho trường đã cho.

12

Date getTime()

Nhận thời gian hiện tại của Lịch này.

13

long getTimeInMillis()

Nhận thời gian hiện tại của Lịch này là lâu.

14

TimeZone getTimeZone()

Nhận múi giờ.

15

int getMinimum(int field)

Trả về giá trị nhỏ nhất cho trường đã cho.

16

int hashCode()

Ghi đè Mã băm.

17

boolean isLeapYear(int year)

Xác định xem năm đã cho có phải là năm nhuận hay không.

18

void roll(int field, boolean up)

Cộng hoặc trừ (lên / xuống) một đơn vị thời gian trên trường thời gian nhất định mà không thay đổi các trường lớn hơn.

19

void set(int field, int value)

Đặt trường thời gian với giá trị đã cho.

20

void set(int year, int month, int date)

Đặt giá trị cho các trường năm, tháng và ngày.

21

void set(int year, int month, int date, int hour, int minute)

Đặt giá trị cho các trường năm, tháng, ngày, giờ và phút.

22

void set(int year, int month, int date, int hour, int minute, int second)

Đặt giá trị cho các trường năm, tháng, ngày, giờ, phút và giây.

23

void setGregorianChange(Date date)

Đặt ngày thay đổi GregorianCalendar.

24

void setTime(Date date)

Đặt thời gian hiện tại của Lịch này với Ngày đã cho.

25

void setTimeInMillis(long millis)

Đặt thời gian hiện tại của Lịch này từ giá trị dài đã cho.

26

void setTimeZone(TimeZone value)

Đặt múi giờ với giá trị múi giờ đã cho.

27

String toString()

Trả về biểu diễn chuỗi của lịch này.

Thí dụ

import java.util.*;
public class GregorianCalendarDemo {

   public static void main(String args[]) {
      String months[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", 
         "Oct", "Nov", "Dec"};
      
      int year;
      // Create a Gregorian calendar initialized
      // with the current date and time in the
      // default locale and timezone.
      
      GregorianCalendar gcalendar = new GregorianCalendar();
      
      // Display current time and date information.
      System.out.print("Date: ");
      System.out.print(months[gcalendar.get(Calendar.MONTH)]);
      System.out.print(" " + gcalendar.get(Calendar.DATE) + " ");
      System.out.println(year = gcalendar.get(Calendar.YEAR));
      System.out.print("Time: ");
      System.out.print(gcalendar.get(Calendar.HOUR) + ":");
      System.out.print(gcalendar.get(Calendar.MINUTE) + ":");
      System.out.println(gcalendar.get(Calendar.SECOND));

      // Test if the current year is a leap year
      if(gcalendar.isLeapYear(year)) {
         System.out.println("The current year is a leap year");
      }else {
         System.out.println("The current year is not a leap year");
      }
   }
}

Điều này sẽ tạo ra kết quả sau:

Đầu ra

Date: Apr 22 2009
Time: 11:25:27
The current year is not a leap year

Để có danh sách đầy đủ các hằng số có sẵn trong lớp Lịch, bạn có thể tham khảo tài liệu Java tiêu chuẩn.

Java cung cấp gói java.util.regex để đối sánh mẫu với biểu thức chính quy. Các biểu thức chính quy trong Java rất giống với ngôn ngữ lập trình Perl và rất dễ học.

Biểu thức chính quy là một chuỗi ký tự đặc biệt giúp bạn so khớp hoặc tìm các chuỗi hoặc tập hợp chuỗi khác, sử dụng cú pháp chuyên biệt được tổ chức trong một mẫu. Chúng có thể được sử dụng để tìm kiếm, chỉnh sửa hoặc thao tác với văn bản và dữ liệu.

Gói java.util.regex chủ yếu bao gồm ba lớp sau:

  • Pattern Class- Đối tượng Pattern là một biểu diễn đã biên dịch của một biểu thức chính quy. Lớp Pattern không cung cấp hàm tạo công khai. Để tạo một mẫu, trước tiên bạn phải gọi một trong các lệnh tĩnh công khai của nócompile()phương thức này sẽ trả về một đối tượng Pattern. Các phương thức này chấp nhận một biểu thức chính quy làm đối số đầu tiên.

  • Matcher Class- Đối tượng Matcher là công cụ thông dịch mẫu và thực hiện các hoạt động so khớp với một chuỗi đầu vào. Giống như lớp Pattern, Matcher định nghĩa không có hàm tạo công khai. Bạn có được một đối tượng Matcher bằng cách gọimatcher() trên một đối tượng Pattern.

  • PatternSyntaxException - Đối tượng PatternSyntaxException là một ngoại lệ không được kiểm tra chỉ ra lỗi cú pháp trong một mẫu biểu thức chính quy.

Chụp nhóm

Chụp nhóm là một cách để coi nhiều ký tự như một đơn vị duy nhất. Chúng được tạo ra bằng cách đặt các ký tự được nhóm bên trong một tập hợp các dấu ngoặc đơn. Ví dụ: biểu thức chính quy (dog) tạo một nhóm duy nhất chứa các chữ cái "d", "o" và "g".

Các nhóm chụp được đánh số bằng cách đếm các dấu ngoặc đơn mở từ trái sang phải. Ví dụ: trong biểu thức ((A) (B (C)))), có bốn nhóm như vậy -

  • ((A)(B(C)))
  • (A)
  • (B(C))
  • (C)

Để biết có bao nhiêu nhóm hiện diện trong biểu thức, hãy gọi phương thức groupCount trên một đối tượng so khớp. Phương thức groupCount trả về mộtint hiển thị số lượng nhóm bắt có trong mẫu của trình đối sánh.

Ngoài ra còn có một nhóm đặc biệt, nhóm 0, luôn đại diện cho toàn bộ biểu thức. Nhóm này không được bao gồm trong tổng số được báo cáo bởi groupCount.

Example

Ví dụ sau minh họa cách tìm một chuỗi chữ số từ chuỗi chữ và số đã cho:

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class RegexMatches {

   public static void main( String args[] ) {
      // String to be scanned to find the pattern.
      String line = "This order was placed for QT3000! OK?";
      String pattern = "(.*)(\\d+)(.*)";

      // Create a Pattern object
      Pattern r = Pattern.compile(pattern);

      // Now create matcher object.
      Matcher m = r.matcher(line);
      if (m.find( )) {
         System.out.println("Found value: " + m.group(0) );
         System.out.println("Found value: " + m.group(1) );
         System.out.println("Found value: " + m.group(2) );
      }else {
         System.out.println("NO MATCH");
      }
   }
}

Điều này sẽ tạo ra kết quả sau:

Output

Found value: This order was placed for QT3000! OK?
Found value: This order was placed for QT300
Found value: 0

Cú pháp biểu thức chính quy

Đây là bảng liệt kê tất cả các cú pháp siêu ký tự biểu thức chính quy có sẵn trong Java -

Subexpression Diêm
^ Khớp với đầu dòng.
$ Khớp với cuối dòng.
. Khớp với bất kỳ ký tự đơn nào ngoại trừ dòng mới. Sử dụngm tùy chọn cho phép nó phù hợp với dòng mới.
[...] Khớp bất kỳ ký tự đơn nào trong ngoặc.
[^ ...] Khớp bất kỳ ký tự đơn nào không có trong ngoặc.
\ A Bắt đầu của toàn bộ chuỗi.
\ z Kết thúc toàn bộ chuỗi.
\ Z Kết thúc toàn bộ chuỗi ngoại trừ dấu chấm cuối dòng cuối cùng được phép.
lại * Khớp với 0 hoặc nhiều lần xuất hiện của biểu thức trước.
lại + Khớp với 1 hoặc nhiều điều trước đó.
lại? Khớp với 0 hoặc 1 lần xuất hiện của biểu thức trước.
lại {n} Khớp chính xác n số lần xuất hiện của biểu thức trước.
lại {n,} Khớp với n hoặc nhiều lần xuất hiện của biểu thức trước.
lại {n, m} Khớp ít nhất n và nhiều nhất m lần xuất hiện của biểu thức trước.
a | b Đối sánh với a hoặc b.
(lại) Nhóm các biểu thức chính quy và ghi nhớ văn bản phù hợp.
(?: lại) Nhóm các biểu thức chính quy mà không cần nhớ văn bản phù hợp.
(?> lại) Khớp với mẫu độc lập mà không bị bẻ khóa.
\ w Khớp các ký tự từ.
\ W Đối sánh các ký tự không phải từ khóa.
\S Khớp với khoảng trắng. Tương đương với [\ t \ n \ r \ f].
\S Khớp với khoảng trắng.
\ d Khớp các chữ số. Tương đương với [0-9].
\ D Phù hợp với nondigits.
\ A Khớp với phần đầu của chuỗi.
\ Z Khớp với phần cuối của chuỗi. Nếu một dòng mới tồn tại, nó sẽ khớp ngay trước dòng mới.
\ z Khớp với phần cuối của chuỗi.
\ G Khớp với điểm kết thúc trận đấu cuối cùng.
\ n Tham chiếu ngược để nắm bắt số "n" của nhóm.
\ b Khớp các ranh giới từ khi nằm ngoài dấu ngoặc. Khớp với khoảng trắng lùi (0x08) khi ở bên trong dấu ngoặc.
\ B Khớp với các ranh giới không có từ khóa.
\ n, \ t, v.v. Khớp với dòng mới, dấu xuống dòng, tab, v.v.
\ Q Escape (trích dẫn) tất cả các ký tự lên đến \ E.
\ E Kết thúc báo giá bắt đầu bằng \ Q.

Các phương thức của lớp Matcher

Đây là danh sách các phương thức phiên bản hữu ích:

Phương pháp chỉ mục

Phương thức chỉ mục cung cấp các giá trị chỉ mục hữu ích hiển thị chính xác vị trí khớp được tìm thấy trong chuỗi đầu vào -

Sr.No. Phương pháp & Mô tả
1

public int start()

Trả về chỉ số bắt đầu của trận đấu trước đó.

2

public int start(int group)

Trả về chỉ mục bắt đầu của dãy con được nhóm đã cho nắm bắt trong thao tác đối sánh trước đó.

3

public int end()

Trả về độ lệch sau khi ký tự cuối cùng được khớp.

4

public int end(int group)

Trả về phần bù sau ký tự cuối cùng của dãy con được nhóm nhất định bắt trong thao tác khớp trước đó.

Phương pháp học

Các phương pháp nghiên cứu xem xét chuỗi đầu vào và trả về một Boolean cho biết liệu mẫu có được tìm thấy hay không -

Sr.No. Phương pháp & Mô tả
1

public boolean lookingAt()

Attempts to match the input sequence, starting at the beginning of the region, against the pattern.

2

public boolean find()

Attempts to find the next subsequence of the input sequence that matches the pattern.

3

public boolean find(int start)

Resets this matcher and then attempts to find the next subsequence of the input sequence that matches the pattern, starting at the specified index.

4

public boolean matches()

Attempts to match the entire region against the pattern.

Replacement Methods

Replacement methods are useful methods for replacing text in an input string −

Sr.No. Method & Description
1

public Matcher appendReplacement(StringBuffer sb, String replacement)

Implements a non-terminal append-and-replace step.

2

public StringBuffer appendTail(StringBuffer sb)

Implements a terminal append-and-replace step.

3

public String replaceAll(String replacement)

Replaces every subsequence of the input sequence that matches the pattern with the given replacement string.

4

public String replaceFirst(String replacement)

Replaces the first subsequence of the input sequence that matches the pattern with the given replacement string.

5

public static String quoteReplacement(String s)

Returns a literal replacement String for the specified String. This method produces a String that will work as a literal replacement s in the appendReplacement method of the Matcher class.

The start and end Methods

Following is the example that counts the number of times the word "cat" appears in the input string −

Example

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class RegexMatches {

   private static final String REGEX = "\\bcat\\b";
   private static final String INPUT = "cat cat cat cattie cat";

   public static void main( String args[] ) {
      Pattern p = Pattern.compile(REGEX);
      Matcher m = p.matcher(INPUT);   // get a matcher object
      int count = 0;

      while(m.find()) {
         count++;
         System.out.println("Match number "+count);
         System.out.println("start(): "+m.start());
         System.out.println("end(): "+m.end());
      }
   }
}

This will produce the following result −

Output

Match number 1
start(): 0
end(): 3
Match number 2
start(): 4
end(): 7
Match number 3
start(): 8
end(): 11
Match number 4
start(): 19
end(): 22

You can see that this example uses word boundaries to ensure that the letters "c" "a" "t" are not merely a substring in a longer word. It also gives some useful information about where in the input string the match has occurred.

The start method returns the start index of the subsequence captured by the given group during the previous match operation, and the end returns the index of the last character matched, plus one.

The matches and lookingAt Methods

The matches and lookingAt methods both attempt to match an input sequence against a pattern. The difference, however, is that matches requires the entire input sequence to be matched, while lookingAt does not.

Both methods always start at the beginning of the input string. Here is the example explaining the functionality −

Example

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class RegexMatches {

   private static final String REGEX = "foo";
   private static final String INPUT = "fooooooooooooooooo";
   private static Pattern pattern;
   private static Matcher matcher;

   public static void main( String args[] ) {
      pattern = Pattern.compile(REGEX);
      matcher = pattern.matcher(INPUT);

      System.out.println("Current REGEX is: "+REGEX);
      System.out.println("Current INPUT is: "+INPUT);

      System.out.println("lookingAt(): "+matcher.lookingAt());
      System.out.println("matches(): "+matcher.matches());
   }
}

This will produce the following result −

Output

Current REGEX is: foo
Current INPUT is: fooooooooooooooooo
lookingAt(): true
matches(): false

The replaceFirst and replaceAll Methods

The replaceFirst and replaceAll methods replace the text that matches a given regular expression. As their names indicate, replaceFirst replaces the first occurrence, and replaceAll replaces all occurrences.

Here is the example explaining the functionality −

Example

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class RegexMatches {

   private static String REGEX = "dog";
   private static String INPUT = "The dog says meow. " + "All dogs say meow.";
   private static String REPLACE = "cat";

   public static void main(String[] args) {
      Pattern p = Pattern.compile(REGEX);
      
      // get a matcher object
      Matcher m = p.matcher(INPUT); 
      INPUT = m.replaceAll(REPLACE);
      System.out.println(INPUT);
   }
}

This will produce the following result −

Output

The cat says meow. All cats say meow.

The appendReplacement and appendTail Methods

The Matcher class also provides appendReplacement and appendTail methods for text replacement.

Here is the example explaining the functionality −

Example

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class RegexMatches {

   private static String REGEX = "a*b";
   private static String INPUT = "aabfooaabfooabfoob";
   private static String REPLACE = "-";
   public static void main(String[] args) {

      Pattern p = Pattern.compile(REGEX);
      
      // get a matcher object
      Matcher m = p.matcher(INPUT);
      StringBuffer sb = new StringBuffer();
      while(m.find()) {
         m.appendReplacement(sb, REPLACE);
      }
      m.appendTail(sb);
      System.out.println(sb.toString());
   }
}

This will produce the following result −

Output

-foo-foo-foo-

PatternSyntaxException Class Methods

A PatternSyntaxException is an unchecked exception that indicates a syntax error in a regular expression pattern. The PatternSyntaxException class provides the following methods to help you determine what went wrong −

Sr.No. Method & Description
1

public String getDescription()

Retrieves the description of the error.

2

public int getIndex()

Retrieves the error index.

3

public String getPattern()

Retrieves the erroneous regular expression pattern.

4

public String getMessage()

Returns a multi-line string containing the description of the syntax error and its index, the erroneous regular expression pattern, and a visual indication of the error index within the pattern.

A Java method is a collection of statements that are grouped together to perform an operation. When you call the System.out.println() method, for example, the system actually executes several statements in order to display a message on the console.

Now you will learn how to create your own methods with or without return values, invoke a method with or without parameters, and apply method abstraction in the program design.

Creating Method

Considering the following example to explain the syntax of a method −

Syntax

public static int methodName(int a, int b) {
   // body
}

Here,

  • public static − modifier

  • int − return type

  • methodName − name of the method

  • a, b − formal parameters

  • int a, int b − list of parameters

Method definition consists of a method header and a method body. The same is shown in the following syntax −

Syntax

modifier returnType nameOfMethod (Parameter List) {
   // method body
}

The syntax shown above includes −

  • modifier − It defines the access type of the method and it is optional to use.

  • returnType − Method may return a value.

  • nameOfMethod − This is the method name. The method signature consists of the method name and the parameter list.

  • Parameter List − The list of parameters, it is the type, order, and number of parameters of a method. These are optional, method may contain zero parameters.

  • method body − The method body defines what the method does with the statements.

Example

Here is the source code of the above defined method called min(). This method takes two parameters num1 and num2 and returns the maximum between the two −

/** the snippet returns the minimum between two numbers */

public static int minFunction(int n1, int n2) {
   int min;
   if (n1 > n2)
      min = n2;
   else
      min = n1;

   return min; 
}

Method Calling

For using a method, it should be called. There are two ways in which a method is called i.e., method returns a value or returning nothing (no return value).

The process of method calling is simple. When a program invokes a method, the program control gets transferred to the called method. This called method then returns control to the caller in two conditions, when −

  • the return statement is executed.
  • it reaches the method ending closing brace.

The methods returning void is considered as call to a statement. Lets consider an example −

System.out.println("This is tutorialspoint.com!");

The method returning value can be understood by the following example −

int result = sum(6, 9);

Following is the example to demonstrate how to define a method and how to call it −

Example

public class ExampleMinNumber {
   
   public static void main(String[] args) {
      int a = 11;
      int b = 6;
      int c = minFunction(a, b);
      System.out.println("Minimum Value = " + c);
   }

   /** returns the minimum of two numbers */
   public static int minFunction(int n1, int n2) {
      int min;
      if (n1 > n2)
         min = n2;
      else
         min = n1;

      return min; 
   }
}

This will produce the following result −

Output

Minimum value = 6

The void Keyword

The void keyword allows us to create methods which do not return a value. Here, in the following example we're considering a void method methodRankPoints. This method is a void method, which does not return any value. Call to a void method must be a statement i.e. methodRankPoints(255.7);. It is a Java statement which ends with a semicolon as shown in the following example.

Example

public class ExampleVoid {

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

   public static void methodRankPoints(double points) {
      if (points >= 202.5) {
         System.out.println("Rank:A1");
      }else if (points >= 122.4) {
         System.out.println("Rank:A2");
      }else {
         System.out.println("Rank:A3");
      }
   }
}

This will produce the following result −

Output

Rank:A1

Passing Parameters by Value

While working under calling process, arguments is to be passed. These should be in the same order as their respective parameters in the method specification. Parameters can be passed by value or by reference.

Passing Parameters by Value means calling a method with a parameter. Through this, the argument value is passed to the parameter.

Example

The following program shows an example of passing parameter by value. The values of the arguments remains the same even after the method invocation.

public class swappingExample {

   public static void main(String[] args) {
      int a = 30;
      int b = 45;
      System.out.println("Before swapping, a = " + a + " and b = " + b);

      // Invoke the swap method
      swapFunction(a, b);
      System.out.println("\n**Now, Before and After swapping values will be same here**:");
      System.out.println("After swapping, a = " + a + " and b is " + b);
   }

   public static void swapFunction(int a, int b) {
      System.out.println("Before swapping(Inside), a = " + a + " b = " + b);
      
      // Swap n1 with n2
      int c = a;
      a = b;
      b = c;
      System.out.println("After swapping(Inside), a = " + a + " b = " + b);
   }
}

This will produce the following result −

Output

Before swapping, a = 30 and b = 45
Before swapping(Inside), a = 30 b = 45
After swapping(Inside), a = 45 b = 30

**Now, Before and After swapping values will be same here**:
After swapping, a = 30 and b is 45

Method Overloading

When a class has two or more methods by the same name but different parameters, it is known as method overloading. It is different from overriding. In overriding, a method has the same method name, type, number of parameters, etc.

Let’s consider the example discussed earlier for finding minimum numbers of integer type. If, let’s say we want to find the minimum number of double type. Then the concept of overloading will be introduced to create two or more methods with the same name but different parameters.

The following example explains the same −

Example

public class ExampleOverloading {

   public static void main(String[] args) {
      int a = 11;
      int b = 6;
      double c = 7.3;
      double d = 9.4;
      int result1 = minFunction(a, b);
      
      // same function name with different parameters
      double result2 = minFunction(c, d);
      System.out.println("Minimum Value = " + result1);
      System.out.println("Minimum Value = " + result2);
   }

   // for integer
   public static int minFunction(int n1, int n2) {
      int min;
      if (n1 > n2)
         min = n2;
      else
         min = n1;

      return min; 
   }
   
   // for double
   public static double minFunction(double n1, double n2) {
     double min;
      if (n1 > n2)
         min = n2;
      else
         min = n1;

      return min; 
   }
}

This will produce the following result −

Output

Minimum Value = 6
Minimum Value = 7.3

Overloading methods makes program readable. Here, two methods are given by the same name but with different parameters. The minimum number from integer and double types is the result.

Using Command-Line Arguments

Sometimes you will want to pass some information into a program when you run it. This is accomplished by passing command-line arguments to main( ).

A command-line argument is the information that directly follows the program's name on the command line when it is executed. To access the command-line arguments inside a Java program is quite easy. They are stored as strings in the String array passed to main( ).

Example

The following program displays all of the command-line arguments that it is called with −

public class CommandLine {

   public static void main(String args[]) { 
      for(int i = 0; i<args.length; i++) {
         System.out.println("args[" + i + "]: " +  args[i]);
      }
   }
}

Try executing this program as shown here −

$java CommandLine this is a command line 200 -100

This will produce the following result −

Output

args[0]: this
args[1]: is
args[2]: a
args[3]: command
args[4]: line
args[5]: 200
args[6]: -100

The this keyword

this is a keyword in Java which is used as a reference to the object of the current class, with in an instance method or a constructor. Using this you can refer the members of a class such as constructors, variables and methods.

Note − The keyword this is used only within instance methods or constructors

In general, the keyword this is used to −

  • Differentiate the instance variables from local variables if they have same names, within a constructor or a method.

class Student {
   int age;   
   Student(int age) {
      this.age = age;	
   }
}
  • Call one type of constructor (Parameterized constructor or default) from other in a class. It is known as explicit constructor invocation.

class Student {
   int age
   Student() {
      this(20);
   }
   
   Student(int age) {
      this.age = age;	
   }
}

Example

Here is an example that uses this keyword to access the members of a class. Copy and paste the following program in a file with the name, This_Example.java.

public class This_Example {
   // Instance variable num
   int num = 10;
	
   This_Example() {
      System.out.println("This is an example program on keyword this");	
   }

   This_Example(int num) {
      // Invoking the default constructor
      this();
      
      // Assigning the local variable num to the instance variable num
      this.num = num;	   
   }
   
   public void greet() {
      System.out.println("Hi Welcome to Tutorialspoint");
   }
      
   public void print() {
      // Local variable num
      int num = 20;
      
      // Printing the local variable
      System.out.println("value of local variable num is : "+num);
      
      // Printing the instance variable
      System.out.println("value of instance variable num is : "+this.num);
      
      // Invoking the greet method of a class
      this.greet();     
   }
   
   public static void main(String[] args) {
      // Instantiating the class
      This_Example obj1 = new This_Example();
      
      // Invoking the print method
      obj1.print();
	  
      // Passing a new value to the num variable through Parameterized constructor
      This_Example obj2 = new This_Example(30);
      
      // Invoking the print method again
      obj2.print(); 
   }
}

This will produce the following result −

Output

This is an example program on keyword this 
value of local variable num is : 20
value of instance variable num is : 10
Hi Welcome to Tutorialspoint
This is an example program on keyword this 
value of local variable num is : 20
value of instance variable num is : 30
Hi Welcome to Tutorialspoint

Variable Arguments(var-args)

JDK 1.5 enables you to pass a variable number of arguments of the same type to a method. The parameter in the method is declared as follows −

typeName... parameterName

In the method declaration, you specify the type followed by an ellipsis (...). Only one variable-length parameter may be specified in a method, and this parameter must be the last parameter. Any regular parameters must precede it.

Example

public class VarargsDemo {

   public static void main(String args[]) {
      // Call method with variable args  
	   printMax(34, 3, 3, 2, 56.5);
      printMax(new double[]{1, 2, 3});
   }

   public static void printMax( double... numbers) {
      if (numbers.length == 0) {
         System.out.println("No argument passed");
         return;
      }

      double result = numbers[0];

      for (int i = 1; i <  numbers.length; i++)
      if (numbers[i] >  result)
      result = numbers[i];
      System.out.println("The max value is " + result);
   }
}

This will produce the following result −

Output

The max value is 56.5
The max value is 3.0

The finalize( ) Method

It is possible to define a method that will be called just before an object's final destruction by the garbage collector. This method is called finalize( ), and it can be used to ensure that an object terminates cleanly.

For example, you might use finalize( ) to make sure that an open file owned by that object is closed.

To add a finalizer to a class, you simply define the finalize( ) method. The Java runtime calls that method whenever it is about to recycle an object of that class.

Inside the finalize( ) method, you will specify those actions that must be performed before an object is destroyed.

The finalize( ) method has this general form −

protected void finalize( ) {
   // finalization code here
}

Here, the keyword protected is a specifier that prevents access to finalize( ) by code defined outside its class.

This means that you cannot know when or even if finalize( ) will be executed. For example, if your program ends before garbage collection occurs, finalize( ) will not execute.

The java.io package contains nearly every class you might ever need to perform input and output (I/O) in Java. All these streams represent an input source and an output destination. The stream in the java.io package supports many data such as primitives, object, localized characters, etc.

Stream

A stream can be defined as a sequence of data. There are two kinds of Streams −

  • InPutStream − The InputStream is used to read data from a source.

  • OutPutStream − The OutputStream is used for writing data to a destination.

Java provides strong but flexible support for I/O related to files and networks but this tutorial covers very basic functionality related to streams and I/O. We will see the most commonly used examples one by one −

Byte Streams

Java byte streams are used to perform input and output of 8-bit bytes. Though there are many classes related to byte streams but the most frequently used classes are, FileInputStream and FileOutputStream. Following is an example which makes use of these two classes to copy an input file into an output file −

Example

import java.io.*;
public class CopyFile {

   public static void main(String args[]) throws IOException {  
      FileInputStream in = null;
      FileOutputStream out = null;

      try {
         in = new FileInputStream("input.txt");
         out = new FileOutputStream("output.txt");
         
         int c;
         while ((c = in.read()) != -1) {
            out.write(c);
         }
      }finally {
         if (in != null) {
            in.close();
         }
         if (out != null) {
            out.close();
         }
      }
   }
}

Bây giờ chúng ta hãy có một tệp input.txt với nội dung sau -

This is test for copy file.

Bước tiếp theo, hãy biên dịch chương trình trên và thực thi nó, điều này sẽ dẫn đến việc tạo tệp output.txt với nội dung giống như chúng ta có trong input.txt. Vì vậy, hãy đặt đoạn mã trên vào tệp CopyFile.java và thực hiện như sau:

$javac CopyFile.java $java CopyFile

Luồng nhân vật

Java Byte luồng được sử dụng để thực hiện đầu vào và đầu ra của byte 8 bit, trong khi Java Charactercác luồng được sử dụng để thực hiện nhập và xuất cho unicode 16-bit. Mặc dù có nhiều lớp liên quan đến luồng ký tự nhưng các lớp được sử dụng thường xuyên nhất là,FileReaderFileWriter. Mặc dù bên trong FileReader sử dụng FileInputStream và FileWriter sử dụng FileOutputStream nhưng ở đây sự khác biệt chính là FileReader đọc hai byte một lúc và FileWriter ghi hai byte một lúc.

Chúng ta có thể viết lại ví dụ trên, sử dụng hai lớp này để sao chép tệp đầu vào (có các ký tự unicode) vào tệp đầu ra -

Example

import java.io.*;
public class CopyFile {

   public static void main(String args[]) throws IOException {
      FileReader in = null;
      FileWriter out = null;

      try {
         in = new FileReader("input.txt");
         out = new FileWriter("output.txt");
         
         int c;
         while ((c = in.read()) != -1) {
            out.write(c);
         }
      }finally {
         if (in != null) {
            in.close();
         }
         if (out != null) {
            out.close();
         }
      }
   }
}

Bây giờ chúng ta hãy có một tệp input.txt với nội dung sau -

This is test for copy file.

Bước tiếp theo, hãy biên dịch chương trình trên và thực thi nó, điều này sẽ dẫn đến việc tạo tệp output.txt với nội dung giống như chúng ta có trong input.txt. Vì vậy, hãy đặt đoạn mã trên vào tệp CopyFile.java và thực hiện như sau:

$javac CopyFile.java $java CopyFile

Luồng chuẩn

Tất cả các ngôn ngữ lập trình đều cung cấp hỗ trợ cho I / O tiêu chuẩn trong đó chương trình của người dùng có thể nhận đầu vào từ bàn phím và sau đó tạo ra đầu ra trên màn hình máy tính. Nếu bạn biết đến ngôn ngữ lập trình C hoặc C ++, thì bạn phải biết đến ba thiết bị tiêu chuẩn STDIN, STDOUT và STDERR. Tương tự, Java cung cấp ba luồng tiêu chuẩn sau:

  • Standard Input - Điều này được sử dụng để cung cấp dữ liệu cho chương trình của người dùng và thường bàn phím được sử dụng làm luồng nhập chuẩn và được biểu diễn dưới dạng System.in.

  • Standard Output - Điều này được sử dụng để xuất dữ liệu được tạo ra bởi chương trình của người dùng và thường màn hình máy tính được sử dụng cho luồng đầu ra tiêu chuẩn và được biểu diễn dưới dạng System.out.

  • Standard Error - Điều này được sử dụng để xuất dữ liệu lỗi do chương trình của người dùng tạo ra và thường màn hình máy tính được sử dụng cho luồng lỗi tiêu chuẩn và được biểu diễn dưới dạng System.err.

Sau đây là một chương trình đơn giản, tạo ra InputStreamReader để đọc luồng đầu vào chuẩn cho đến khi người dùng nhập "q" -

Example

import java.io.*;
public class ReadConsole {

   public static void main(String args[]) throws IOException {
      InputStreamReader cin = null;

      try {
         cin = new InputStreamReader(System.in);
         System.out.println("Enter characters, 'q' to quit.");
         char c;
         do {
            c = (char) cin.read();
            System.out.print(c);
         } while(c != 'q');
      }finally {
         if (cin != null) {
            cin.close();
         }
      }
   }
}

Hãy giữ đoạn mã trên trong tệp ReadConsole.java và cố gắng biên dịch và thực thi nó như được hiển thị trong chương trình sau. Chương trình này tiếp tục đọc và xuất cùng một ký tự cho đến khi chúng ta nhấn 'q' -

$javac ReadConsole.java $java ReadConsole
Enter characters, 'q' to quit.
1
1
e
e
q
q

Đọc và ghi tệp

Như đã mô tả trước đó, một luồng có thể được định nghĩa là một chuỗi dữ liệu. CácInputStream được sử dụng để đọc dữ liệu từ một nguồn và OutputStream được sử dụng để ghi dữ liệu đến một đích.

Đây là một hệ thống phân cấp các lớp để xử lý các luồng Đầu vào và Đầu ra.

Hai luồng quan trọng là FileInputStreamFileOutputStream, sẽ được thảo luận trong hướng dẫn này.

FileInputStream

Luồng này được sử dụng để đọc dữ liệu từ các tệp. Các đối tượng có thể được tạo bằng từ khóanew và có một số loại hàm tạo có sẵn.

Hàm tạo sau lấy tên tệp làm chuỗi để tạo đối tượng luồng đầu vào để đọc tệp:

InputStream f = new FileInputStream("C:/java/hello");

Hàm khởi tạo sau lấy một đối tượng tệp để tạo một đối tượng luồng đầu vào để đọc tệp. Đầu tiên, chúng ta tạo một đối tượng tệp bằng phương thức File () như sau:

File f = new File("C:/java/hello");
InputStream f = new FileInputStream(f);

Khi bạn đã có đối tượng InputStream trong tay, thì sẽ có một danh sách các phương thức trợ giúp có thể được sử dụng để đọc luồng hoặc thực hiện các thao tác khác trên luồng.

Sr.No. Phương pháp & Mô tả
1

public void close() throws IOException{}

Phương thức này đóng luồng xuất tệp. Giải phóng mọi tài nguyên hệ thống được liên kết với tệp. Ném IOException.

2

protected void finalize()throws IOException {}

Phương pháp này xóa kết nối với tệp. Đảm bảo rằng phương thức đóng của luồng xuất tệp này được gọi khi không còn tham chiếu nào đến luồng này. Ném IOException.

3

public int read(int r)throws IOException{}

Phương thức này đọc byte dữ liệu được chỉ định từ InputStream. Trả về một số nguyên. Trả về byte dữ liệu tiếp theo và -1 sẽ được trả về nếu đó là phần cuối của tệp.

4

public int read(byte[] r) throws IOException{}

Phương thức này đọc byte r.length từ luồng đầu vào vào một mảng. Trả về tổng số byte đã đọc. Nếu nó là phần cuối của tệp, -1 sẽ được trả về.

5

public int available() throws IOException{}

Cung cấp số byte có thể đọc được từ luồng nhập tệp này. Trả về một số nguyên.

Có sẵn các luồng đầu vào quan trọng khác, để biết thêm chi tiết, bạn có thể tham khảo các liên kết sau:

  • ByteArrayInputStream

  • DataInputStream

FileOutputStream

FileOutputStream được sử dụng để tạo một tệp và ghi dữ liệu vào đó. Luồng sẽ tạo một tệp, nếu nó chưa tồn tại, trước khi mở nó để xuất.

Đây là hai hàm tạo có thể được sử dụng để tạo một đối tượng FileOutputStream.

Hàm tạo sau lấy tên tệp làm chuỗi để tạo đối tượng luồng đầu vào để ghi tệp:

OutputStream f = new FileOutputStream("C:/java/hello")

Hàm khởi tạo sau lấy một đối tượng tệp để tạo một đối tượng luồng đầu ra để ghi tệp. Đầu tiên, chúng ta tạo một đối tượng tệp bằng phương thức File () như sau:

File f = new File("C:/java/hello");
OutputStream f = new FileOutputStream(f);

Khi bạn đã có đối tượng OutputStream trong tay, thì sẽ có một danh sách các phương thức trợ giúp, có thể được sử dụng để ghi vào luồng hoặc để thực hiện các thao tác khác trên luồng.

Sr.No. Phương pháp & Mô tả
1

public void close() throws IOException{}

Phương thức này đóng luồng xuất tệp. Giải phóng mọi tài nguyên hệ thống được liên kết với tệp. Ném IOException.

2

protected void finalize()throws IOException {}

Phương pháp này xóa kết nối với tệp. Đảm bảo rằng phương thức đóng của luồng xuất tệp này được gọi khi không còn tham chiếu nào đến luồng này. Ném IOException.

3

public void write(int w)throws IOException{}

Phương thức này ghi byte được chỉ định vào luồng đầu ra.

4

public void write(byte[] w)

Ghi các byte w.length từ mảng byte được đề cập vào OutputStream.

Có sẵn các luồng đầu ra quan trọng khác, để biết thêm chi tiết, bạn có thể tham khảo các liên kết sau:

  • ByteArrayOutputStream

  • DataOutputStream

Example

Sau đây là ví dụ để chứng minh InputStream và OutputStream:

import java.io.*;
public class fileStreamTest {

   public static void main(String args[]) {
   
      try {
         byte bWrite [] = {11,21,3,40,5};
         OutputStream os = new FileOutputStream("test.txt");
         for(int x = 0; x < bWrite.length ; x++) {
            os.write( bWrite[x] );   // writes the bytes
         }
         os.close();
     
         InputStream is = new FileInputStream("test.txt");
         int size = is.available();

         for(int i = 0; i < size; i++) {
            System.out.print((char)is.read() + "  ");
         }
         is.close();
      } catch (IOException e) {
         System.out.print("Exception");
      }	
   }
}

Đoạn mã trên sẽ tạo tệp test.txt và sẽ viết các số nhất định ở định dạng nhị phân. Tương tự sẽ là kết quả trên màn hình stdout.

Điều hướng tệp và I / O

Có một số lớp học khác mà chúng ta sẽ trải qua để tìm hiểu những kiến ​​thức cơ bản về Điều hướng tệp và I / O.

  • Lớp tệp

  • Lớp FileReader

  • Lớp FileWriter

Thư mục trong Java

Thư mục là một Tệp có thể chứa danh sách các tệp và thư mục khác. Bạn dùngFileđối tượng để tạo thư mục, liệt kê các tệp có sẵn trong một thư mục. Để biết chi tiết đầy đủ, hãy kiểm tra danh sách tất cả các phương thức mà bạn có thể gọi trên đối tượng Tệp và những gì liên quan đến thư mục.

Tạo thư mục

Có hai hữu ích File các phương thức tiện ích, có thể được sử dụng để tạo thư mục -

  • Các mkdir( )phương thức tạo một thư mục, trả về true khi thành công và false khi thất bại. Lỗi chỉ ra rằng đường dẫn được chỉ định trong đối tượng Tệp đã tồn tại hoặc không thể tạo thư mục vì toàn bộ đường dẫn chưa tồn tại.

  • Các mkdirs() phương thức này tạo ra cả một thư mục và tất cả các thư mục cha của thư mục.

Ví dụ sau tạo thư mục "/ tmp / user / java / bin" -

Example

import java.io.File;
public class CreateDir {

   public static void main(String args[]) {
      String dirname = "/tmp/user/java/bin";
      File d = new File(dirname);
      
      // Create directory now.
      d.mkdirs();
   }
}

Biên dịch và thực thi đoạn mã trên để tạo "/ tmp / user / java / bin".

Note- Java tự động xử lý các dấu phân cách đường dẫn trên UNIX và Windows theo quy ước. Nếu bạn sử dụng dấu gạch chéo (/) trên phiên bản Windows của Java, đường dẫn sẽ vẫn phân giải chính xác.

Danh sách thư mục

Bạn có thể dùng list( ) phương pháp được cung cấp bởi File đối tượng để liệt kê tất cả các tệp và thư mục có sẵn trong một thư mục như sau:

Example

import java.io.File;
public class ReadDir {

   public static void main(String[] args) {
      File file = null;
      String[] paths;
  
      try {      
         // create new file object
         file = new File("/tmp");

         // array of files and directory
         paths = file.list();

         // for each name in the path array
         for(String path:paths) {
            // prints filename and directory name
            System.out.println(path);
         }
      } catch (Exception e) {
         // if any error occurs
         e.printStackTrace();
      }
   }
}

Điều này sẽ tạo ra kết quả sau dựa trên các thư mục và tệp có sẵn trong /tmp thư mục -

Output

test1.txt
test2.txt
ReadDir.java
ReadDir.class

Một ngoại lệ (hoặc sự kiện đặc biệt) là một vấn đề phát sinh trong quá trình thực hiện một chương trình. Khi mộtException xảy ra dòng chảy bình thường của chương trình bị gián đoạn và chương trình / Ứng dụng kết thúc bất thường, điều này không được khuyến nghị, do đó, những trường hợp ngoại lệ này phải được xử lý.

Một ngoại lệ có thể xảy ra vì nhiều lý do khác nhau. Sau đây là một số trường hợp xảy ra ngoại lệ.

  • Một người dùng đã nhập một dữ liệu không hợp lệ.

  • Không thể tìm thấy tệp cần mở.

  • Kết nối mạng bị mất khi đang giao tiếp hoặc JVM hết bộ nhớ.

Một số trường hợp ngoại lệ này là do lỗi người dùng, một số trường hợp khác do lỗi của người lập trình và các trường hợp khác do tài nguyên vật lý bị lỗi theo cách nào đó.

Dựa trên những điều này, chúng tôi có ba loại Ngoại lệ. Bạn cần hiểu chúng để biết cách xử lý ngoại lệ hoạt động trong Java.

  • Checked exceptions- Một ngoại lệ đã kiểm tra là một ngoại lệ được kiểm tra (thông báo) bởi trình biên dịch tại thời điểm biên dịch, những ngoại lệ này còn được gọi là ngoại lệ thời gian biên dịch. Không thể đơn giản bỏ qua các ngoại lệ này, lập trình viên nên xử lý (xử lý) các ngoại lệ này.

Ví dụ, nếu bạn sử dụng FileReadertrong chương trình của bạn để đọc dữ liệu từ một tệp, nếu tệp được chỉ định trong phương thức khởi tạo của nó không tồn tại, thì một FileNotFoundException sẽ xảy ra và trình biên dịch sẽ nhắc người lập trình xử lý ngoại lệ.

Thí dụ

import java.io.File;
import java.io.FileReader;

public class FilenotFound_Demo {

   public static void main(String args[]) {		
      File file = new File("E://file.txt");
      FileReader fr = new FileReader(file); 
   }
}

Nếu bạn cố gắng biên dịch chương trình trên, bạn sẽ nhận được các ngoại lệ sau.

Đầu ra

C:\>javac FilenotFound_Demo.java
FilenotFound_Demo.java:8: error: unreported exception FileNotFoundException; must be caught or declared to be thrown
      FileReader fr = new FileReader(file);
                      ^
1 error

Note - Kể từ khi các phương pháp read()close() của lớp FileReader ném IOException, bạn có thể quan sát thấy rằng trình biên dịch thông báo xử lý IOException, cùng với FileNotFoundException.

  • Unchecked exceptions- Một ngoại lệ không được kiểm tra là một ngoại lệ xảy ra tại thời điểm thực thi. Chúng còn được gọi làRuntime Exceptions. Chúng bao gồm các lỗi lập trình, chẳng hạn như lỗi logic hoặc sử dụng API không đúng cách. Các ngoại lệ thời gian chạy được bỏ qua tại thời điểm biên dịch.

Ví dụ: nếu bạn đã khai báo một mảng có kích thước 5 trong chương trình của mình và cố gắng gọi phần tử thứ 6 của mảng thì ArrayIndexOutOfBoundsExceptionexception sẽ xảy ra.

Thí dụ

public class Unchecked_Demo {
   
   public static void main(String args[]) {
      int num[] = {1, 2, 3, 4};
      System.out.println(num[5]);
   }
}

Nếu bạn biên dịch và thực thi chương trình trên, bạn sẽ nhận được ngoại lệ sau.

Đầu ra

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 5
	at Exceptions.Unchecked_Demo.main(Unchecked_Demo.java:8)
  • Errors- Đây không phải là những trường hợp ngoại lệ mà là những vấn đề phát sinh ngoài tầm kiểm soát của người dùng hoặc người lập trình. Các lỗi thường bị bỏ qua trong mã của bạn vì bạn hiếm khi có thể làm gì với lỗi. Ví dụ, nếu xảy ra tràn ngăn xếp, lỗi sẽ phát sinh. Chúng cũng được bỏ qua tại thời điểm biên dịch.

Hệ thống phân cấp ngoại lệ

Tất cả các lớp ngoại lệ là kiểu con của lớp java.lang.Exception. Lớp ngoại lệ là một lớp con của lớp Throwable. Ngoài lớp ngoại lệ, có một lớp con khác được gọi là Lỗi được dẫn xuất từ ​​lớp Có thể ném.

Lỗi là tình trạng bất thường xảy ra trong trường hợp lỗi nghiêm trọng, những lỗi này không được xử lý bởi các chương trình Java. Lỗi được tạo ra để chỉ ra lỗi do môi trường thời gian chạy tạo ra. Ví dụ: JVM đã hết bộ nhớ. Thông thường, các chương trình không thể khôi phục sau lỗi.

Lớp Exception có hai lớp con chính: Lớp IOException và Lớp RuntimeException.

Sau đây là danh sách các Ngoại lệ tích hợp sẵn của Java được kiểm tra và bỏ chọn phổ biến nhất .

Phương pháp ngoại lệ

Sau đây là danh sách các phương thức quan trọng có sẵn trong lớp Throwable.

Sr.No. Phương pháp & Mô tả
1

public String getMessage()

Trả về một thông báo chi tiết về ngoại lệ đã xảy ra. Thông báo này được khởi tạo trong phương thức khởi tạo Throwable.

2

public Throwable getCause()

Trả về nguyên nhân của ngoại lệ như được đại diện bởi một đối tượng Có thể ném.

3

public String toString()

Trả về tên của lớp được nối với kết quả của getMessage ().

4

public void printStackTrace()

In kết quả của toString () cùng với dấu vết ngăn xếp vào System.err, luồng đầu ra lỗi.

5

public StackTraceElement [] getStackTrace()

Trả về một mảng chứa mỗi phần tử trên dấu vết ngăn xếp. Phần tử ở chỉ số 0 đại diện cho phần trên cùng của ngăn xếp cuộc gọi và phần tử cuối cùng trong mảng đại diện cho phương thức ở cuối ngăn xếp cuộc gọi.

6

public Throwable fillInStackTrace()

Làm đầy dấu vết ngăn xếp của đối tượng Có thể ném này bằng dấu vết ngăn xếp hiện tại, thêm vào bất kỳ thông tin nào trước đó trong dấu vết ngăn xếp.

Bắt ngoại lệ

Một phương thức bắt một ngoại lệ bằng cách sử dụng kết hợp trycatchtừ khóa. Một khối try / catch được đặt xung quanh mã có thể tạo ra một ngoại lệ. Mã trong khối try / catch được gọi là mã được bảo vệ và cú pháp để sử dụng try / catch trông giống như sau:

Cú pháp

try {
   // Protected code
} catch (ExceptionName e1) {
   // Catch block
}

Mã dễ bị ngoại lệ được đặt trong khối thử. Khi một ngoại lệ xảy ra, ngoại lệ đó xảy ra được xử lý bởi khối catch liên kết với nó. Mỗi khối thử phải được theo sau ngay lập tức bởi một khối bắt hoặc khối cuối cùng.

Một câu lệnh bắt liên quan đến việc khai báo loại ngoại lệ mà bạn đang cố bắt. Nếu một ngoại lệ xảy ra trong mã được bảo vệ, khối bắt (hoặc các khối) sau lần thử sẽ được chọn. Nếu loại ngoại lệ đã xảy ra được liệt kê trong một khối catch, thì ngoại lệ sẽ được truyền cho khối catch giống như một đối số được truyền vào một tham số phương thức.

Thí dụ

Sau đây là một mảng được khai báo với 2 phần tử. Sau đó, mã cố gắng truy cập phần tử thứ 3 của mảng sẽ ném ra một ngoại lệ.

// File Name : ExcepTest.java
import java.io.*;

public class ExcepTest {

   public static void main(String args[]) {
      try {
         int a[] = new int[2];
         System.out.println("Access element three :" + a[3]);
      } catch (ArrayIndexOutOfBoundsException e) {
         System.out.println("Exception thrown  :" + e);
      }
      System.out.println("Out of the block");
   }
}

Điều này sẽ tạo ra kết quả sau:

Đầu ra

Exception thrown  :java.lang.ArrayIndexOutOfBoundsException: 3
Out of the block

Nhiều khối bắt

Một khối thử có thể được theo sau bởi nhiều khối bắt. Cú pháp cho nhiều khối bắt giống như sau:

Cú pháp

try {
   // Protected code
} catch (ExceptionType1 e1) {
   // Catch block
} catch (ExceptionType2 e2) {
   // Catch block
} catch (ExceptionType3 e3) {
   // Catch block
}

Các câu lệnh trước chứng minh ba khối bắt, nhưng bạn có thể có bất kỳ số nào trong số chúng sau một lần thử. Nếu một ngoại lệ xảy ra trong mã được bảo vệ, thì ngoại lệ đó sẽ được ném vào khối bắt đầu tiên trong danh sách. Nếu kiểu dữ liệu của ngoại lệ được ném khớp với ExceptionType1, nó sẽ bị bắt ở đó. Nếu không, ngoại lệ chuyển xuống câu lệnh bắt thứ hai. Điều này tiếp tục cho đến khi ngoại lệ được bắt hoặc rơi qua tất cả các lần bắt, trong trường hợp đó phương thức hiện tại dừng thực thi và ngoại lệ được ném xuống phương thức trước đó trên ngăn xếp cuộc gọi.

Thí dụ

Đây là đoạn mã hiển thị cách sử dụng nhiều câu lệnh try / catch.

try {
   file = new FileInputStream(fileName);
   x = (byte) file.read();
} catch (IOException i) {
   i.printStackTrace();
   return -1;
} catch (FileNotFoundException f) // Not valid! {
   f.printStackTrace();
   return -1;
}

Bắt nhiều loại ngoại lệ

Kể từ Java 7, bạn có thể xử lý nhiều ngoại lệ bằng cách sử dụng một khối bắt duy nhất, tính năng này đơn giản hóa mã. Đây là cách bạn sẽ làm điều đó -

catch (IOException|FileNotFoundException ex) {
   logger.log(ex);
   throw ex;

Từ khóa ném / ném

Nếu một phương thức không xử lý một ngoại lệ đã kiểm tra, phương thức đó phải khai báo nó bằng cách sử dụng throwstừ khóa. Từ khóa throws xuất hiện ở cuối chữ ký của phương thức.

Bạn có thể đưa ra một ngoại lệ, một ngoại lệ mới được khởi tạo hoặc một ngoại lệ mà bạn vừa bắt được, bằng cách sử dụng throw từ khóa.

Cố gắng hiểu sự khác biệt giữa từ khóa ném và ném, ném được sử dụng để trì hoãn việc xử lý một ngoại lệ đã được kiểm tra và ném được sử dụng để gọi một ngoại lệ một cách rõ ràng.

Phương thức sau tuyên bố rằng nó ném một RemoteException:

Thí dụ

import java.io.*;
public class className {

   public void deposit(double amount) throws RemoteException {
      // Method implementation
      throw new RemoteException();
   }
   // Remainder of class definition
}

Một phương thức có thể khai báo rằng nó ném nhiều hơn một ngoại lệ, trong trường hợp đó, các ngoại lệ được khai báo trong danh sách được phân tách bằng dấu phẩy. Ví dụ: phương thức sau tuyên bố rằng nó ném một RemoteException và một InsuffnoughFundsException -

Thí dụ

import java.io.*;
public class className {

   public void withdraw(double amount) throws RemoteException, 
      InsufficientFundsException {
      // Method implementation
   }
   // Remainder of class definition
}

Khối cuối cùng

Khối cuối cùng theo sau khối thử hoặc khối bắt. Một khối mã cuối cùng luôn thực thi, bất kể sự xuất hiện của Ngoại lệ.

Sử dụng khối cuối cùng cho phép bạn chạy bất kỳ câu lệnh loại dọn dẹp nào mà bạn muốn thực thi, bất kể điều gì xảy ra trong mã được bảo vệ.

Một khối cuối cùng xuất hiện ở cuối các khối bắt và có cú pháp sau:

Cú pháp

try {
   // Protected code
} catch (ExceptionType1 e1) {
   // Catch block
} catch (ExceptionType2 e2) {
   // Catch block
} catch (ExceptionType3 e3) {
   // Catch block
}finally {
   // The finally block always executes.
}

Thí dụ

public class ExcepTest {

   public static void main(String args[]) {
      int a[] = new int[2];
      try {
         System.out.println("Access element three :" + a[3]);
      } catch (ArrayIndexOutOfBoundsException e) {
         System.out.println("Exception thrown  :" + e);
      }finally {
         a[0] = 6;
         System.out.println("First element value: " + a[0]);
         System.out.println("The finally statement is executed");
      }
   }
}

Điều này sẽ tạo ra kết quả sau:

Đầu ra

Exception thrown  :java.lang.ArrayIndexOutOfBoundsException: 3
First element value: 6
The finally statement is executed

Lưu ý những điều sau -

  • Một mệnh đề bắt không thể tồn tại nếu không có câu lệnh try.

  • Không bắt buộc phải có mệnh đề cuối cùng bất cứ khi nào có khối try / catch.

  • Khối try không thể hiện diện nếu không có mệnh đề bắt hoặc mệnh đề cuối cùng.

  • Không thể có bất kỳ mã nào ở giữa các khối thử, bắt, cuối cùng.

Thử tài nguyên

Nói chung, khi chúng tôi sử dụng bất kỳ tài nguyên nào như luồng, kết nối, v.v., chúng tôi phải đóng chúng một cách rõ ràng bằng cách sử dụng khối cuối cùng. Trong chương trình sau, chúng tôi đang đọc dữ liệu từ một tệp bằng cách sử dụngFileReader và chúng tôi đang đóng nó bằng cách sử dụng khối cuối cùng.

Thí dụ

import java.io.File;
import java.io.FileReader;
import java.io.IOException;

public class ReadData_Demo {

   public static void main(String args[]) {
      FileReader fr = null;		
      try {
         File file = new File("file.txt");
         fr = new FileReader(file); char [] a = new char[50];
         fr.read(a);   // reads the content to the array
         for(char c : a)
         System.out.print(c);   // prints the characters one by one
      } catch (IOException e) {
         e.printStackTrace();
      }finally {
         try {
            fr.close();
         } catch (IOException ex) {		
            ex.printStackTrace();
         }
      }
   }
}

try-with-resources, còn được gọi là automatic resource management, là một cơ chế xử lý ngoại lệ mới được giới thiệu trong Java 7, cơ chế này tự động đóng các tài nguyên được sử dụng trong khối try catch.

Để sử dụng câu lệnh này, bạn chỉ cần khai báo các tài nguyên cần thiết trong dấu ngoặc đơn và tài nguyên được tạo sẽ tự động đóng ở cuối khối. Sau đây là cú pháp của câu lệnh try-with-resources.

Cú pháp

try(FileReader fr = new FileReader("file path")) {
   // use the resource
   } catch () {
      // body of catch 
   }
}

Sau đây là chương trình đọc dữ liệu trong tệp bằng câu lệnh try-with-resources.

Thí dụ

import java.io.FileReader;
import java.io.IOException;

public class Try_withDemo {

   public static void main(String args[]) {
      try(FileReader fr = new FileReader("E://file.txt")) {
         char [] a = new char[50];
         fr.read(a);   // reads the contentto the array
         for(char c : a)
         System.out.print(c);   // prints the characters one by one
      } catch (IOException e) {
         e.printStackTrace();
      }
   }
}

Những điểm sau cần được ghi nhớ khi làm việc với câu lệnh try-with-resources.

  • Để sử dụng một lớp với câu lệnh try-with-resources, nó phải triển khai AutoCloseable giao diện và close() phương thức của nó được gọi tự động trong thời gian chạy.

  • Bạn có thể khai báo nhiều lớp trong câu lệnh try-with-resources.

  • Trong khi bạn khai báo nhiều lớp trong khối try của câu lệnh try-with-resources thì các lớp này được đóng theo thứ tự ngược lại.

  • Ngoại trừ việc khai báo tài nguyên trong dấu ngoặc đơn, mọi thứ đều giống như khối try / catch thông thường của khối try.

  • Tài nguyên được khai báo trong try được khởi tạo ngay trước khi bắt đầu khối try.

  • Tài nguyên được khai báo tại khối try được khai báo ngầm là cuối cùng.

Ngoại lệ do người dùng xác định

Bạn có thể tạo ngoại lệ của riêng mình trong Java. Hãy ghi nhớ những điểm sau khi viết các lớp ngoại lệ của riêng bạn -

  • Tất cả các trường hợp ngoại lệ phải là con của Throwable.

  • Nếu bạn muốn viết một ngoại lệ đã kiểm tra được tự động thực thi bởi Quy tắc Xử lý hoặc Khai báo, bạn cần mở rộng lớp Ngoại lệ.

  • Nếu bạn muốn viết một ngoại lệ thời gian chạy, bạn cần mở rộng lớp RuntimeException.

Chúng ta có thể định nghĩa lớp Ngoại lệ của riêng mình như sau:

class MyException extends Exception {
}

Bạn chỉ cần mở rộng Exceptionlớp để tạo Ngoại lệ của riêng bạn. Đây được coi là những ngoại lệ được kiểm tra. SauInsufficientFundsExceptionlớp là một ngoại lệ do người dùng định nghĩa mở rộng lớp Exception, làm cho nó trở thành một ngoại lệ được kiểm tra. Một lớp ngoại lệ cũng giống như bất kỳ lớp nào khác, chứa các trường và phương thức hữu ích.

Thí dụ

// File Name InsufficientFundsException.java
import java.io.*;

public class InsufficientFundsException extends Exception {
   private double amount;
   
   public InsufficientFundsException(double amount) {
      this.amount = amount;
   }
   
   public double getAmount() {
      return amount;
   }
}

Để chứng minh bằng cách sử dụng ngoại lệ do người dùng xác định của chúng tôi, lớp CheckAccount sau chứa một phương thức rút lại () ném ra một ngoại lệ InsuffnoughFundsException.

// File Name CheckingAccount.java
import java.io.*;

public class CheckingAccount {
   private double balance;
   private int number;
   
   public CheckingAccount(int number) {
      this.number = number;
   }
   
   public void deposit(double amount) {
      balance += amount;
   }
   
   public void withdraw(double amount) throws InsufficientFundsException {
      if(amount <= balance) {
         balance -= amount;
      }else {
         double needs = amount - balance;
         throw new InsufficientFundsException(needs);
      }
   }
   
   public double getBalance() {
      return balance;
   }
   
   public int getNumber() {
      return number;
   }
}

Chương trình BankDemo sau đây minh họa việc gọi phương thức gửi () và rút () của CheckAccount.

// File Name BankDemo.java
public class BankDemo {

   public static void main(String [] args) {
      CheckingAccount c = new CheckingAccount(101);
      System.out.println("Depositing $500..."); c.deposit(500.00); try { System.out.println("\nWithdrawing $100...");
         c.withdraw(100.00);
         System.out.println("\nWithdrawing $600..."); c.withdraw(600.00); } catch (InsufficientFundsException e) { System.out.println("Sorry, but you are short $" + e.getAmount());
         e.printStackTrace();
      }
   }
}

Biên dịch tất cả ba tệp trên và chạy BankDemo. Điều này sẽ tạo ra kết quả sau:

Đầu ra

Depositing $500... Withdrawing $100...

Withdrawing $600... Sorry, but you are short $200.0
InsufficientFundsException
         at CheckingAccount.withdraw(CheckingAccount.java:25)
         at BankDemo.main(BankDemo.java:13)

Các trường hợp ngoại lệ chung

Trong Java, có thể xác định hai danh mục Ngoại lệ và Lỗi.

  • JVM Exceptions- Đây là những ngoại lệ / lỗi được JVM ném ra một cách độc quyền hoặc hợp lý. Ví dụ: NullPointerException, ArrayIndexOutOfBoundsException, ClassCastException.

  • Programmatic Exceptions- Các ngoại lệ này được ứng dụng hoặc lập trình viên API đưa ra một cách rõ ràng. Ví dụ: IllegalArgumentException, IllegalStateException.

Trong chương này, chúng ta sẽ thảo luận về các lớp bên trong của Java.

Lớp học lồng nhau

Trong Java, cũng giống như các phương thức, các biến của một lớp cũng có thể có một lớp khác làm thành viên của nó. Viết một lớp trong một lớp khác được phép trong Java. Lớp được viết bên trong được gọi lànested class, và lớp chứa lớp bên trong được gọi là outer class.

Syntax

Sau đây là cú pháp để viết một lớp lồng nhau. Đây, lớpOuter_Demo là lớp ngoài và lớp Inner_Demo là lớp lồng nhau.

class Outer_Demo {
   class Inner_Demo {
   }
}

Các lớp lồng nhau được chia thành hai loại:

  • Non-static nested classes - Đây là các thành viên không tĩnh của một lớp.

  • Static nested classes - Đây là các thành viên tĩnh của một lớp.

Lớp bên trong (Lớp lồng nhau không tĩnh)

Các lớp bên trong là một cơ chế bảo mật trong Java. Chúng tôi biết một lớp không thể được liên kết với công cụ sửa đổi quyền truy cậpprivate, nhưng nếu chúng ta có lớp là thành viên của lớp khác, thì lớp bên trong có thể được đặt ở chế độ riêng tư. Và điều này cũng được sử dụng để truy cập các thành viên riêng của một lớp.

Các lớp bên trong có ba loại tùy thuộc vào cách thức và vị trí bạn định nghĩa chúng. Họ là -

  • Lớp bên trong
  • Lớp bên trong phương thức cục bộ
  • Lớp bên trong ẩn danh

Lớp bên trong

Tạo một lớp bên trong khá đơn giản. Bạn chỉ cần viết một lớp trong một lớp. Không giống như một lớp, một lớp bên trong có thể là private và một khi bạn khai báo một lớp bên trong là private, nó không thể được truy cập từ một đối tượng bên ngoài lớp.

Sau đây là chương trình để tạo một lớp bên trong và truy cập nó. Trong ví dụ đã cho, chúng ta đặt lớp bên trong là riêng tư và truy cập lớp thông qua một phương thức.

Example

class Outer_Demo {
   int num;
   
   // inner class
   private class Inner_Demo {
      public void print() {
         System.out.println("This is an inner class");
      }
   }
   
   // Accessing he inner class from the method within
   void display_Inner() {
      Inner_Demo inner = new Inner_Demo();
      inner.print();
   }
}
   
public class My_class {

   public static void main(String args[]) {
      // Instantiating the outer class 
      Outer_Demo outer = new Outer_Demo();
      
      // Accessing the display_Inner() method.
      outer.display_Inner();
   }
}

Ở đây bạn có thể quan sát thấy Outer_Demo là lớp bên ngoài, Inner_Demo là lớp bên trong, display_Inner() là phương thức bên trong mà chúng ta đang khởi tạo lớp bên trong và phương thức này được gọi từ main phương pháp.

Nếu bạn biên dịch và thực thi chương trình trên, bạn sẽ nhận được kết quả sau:

Output

This is an inner class.

Truy cập các thành viên riêng

Như đã đề cập trước đó, các lớp bên trong cũng được sử dụng để truy cập các thành viên riêng của một lớp. Giả sử, một lớp đang có các thành viên riêng tư để truy cập chúng. Viết một lớp bên trong vào đó, trả về các thành viên riêng tư từ một phương thức bên trong lớp bên trong, giả sử,getValue(), và cuối cùng từ một lớp khác (mà từ đó bạn muốn truy cập các thành viên riêng) gọi phương thức getValue () của lớp bên trong.

Để khởi tạo lớp bên trong, ban đầu bạn phải khởi tạo lớp bên ngoài. Sau đó, sử dụng đối tượng của lớp ngoài, sau đây là cách bạn có thể khởi tạo lớp bên trong.

Outer_Demo outer = new Outer_Demo();
Outer_Demo.Inner_Demo inner = outer.new Inner_Demo();

Chương trình sau đây cho thấy cách truy cập các thành viên riêng của một lớp bằng cách sử dụng lớp bên trong.

Example

class Outer_Demo {
   // private variable of the outer class
   private int num = 175;  
   
   // inner class
   public class Inner_Demo {
      public int getNum() {
         System.out.println("This is the getnum method of the inner class");
         return num;
      }
   }
}

public class My_class2 {

   public static void main(String args[]) {
      // Instantiating the outer class
      Outer_Demo outer = new Outer_Demo();
      
      // Instantiating the inner class
      Outer_Demo.Inner_Demo inner = outer.new Inner_Demo();
      System.out.println(inner.getNum());
   }
}

Nếu bạn biên dịch và thực thi chương trình trên, bạn sẽ nhận được kết quả sau:

Output

This is the getnum method of the inner class: 175

Lớp bên trong phương thức cục bộ

Trong Java, chúng ta có thể viết một lớp trong một phương thức và đây sẽ là một kiểu cục bộ. Giống như các biến cục bộ, phạm vi của lớp bên trong bị hạn chế trong phương thức.

Một lớp bên trong phương thức-cục bộ chỉ có thể được khởi tạo trong phương thức mà lớp bên trong được định nghĩa. Chương trình sau đây cho thấy cách sử dụng một lớp bên trong phương thức cục bộ.

Example

public class Outerclass {
   // instance method of the outer class 
   void my_Method() {
      int num = 23;

      // method-local inner class
      class MethodInner_Demo {
         public void print() {
            System.out.println("This is method inner class "+num);	   
         }   
      } // end of inner class
	   
      // Accessing the inner class
      MethodInner_Demo inner = new MethodInner_Demo();
      inner.print();
   }
   
   public static void main(String args[]) {
      Outerclass outer = new Outerclass();
      outer.my_Method();	   	   
   }
}

Nếu bạn biên dịch và thực thi chương trình trên, bạn sẽ nhận được kết quả sau:

Output

This is method inner class 23

Lớp bên trong ẩn danh

Một lớp bên trong được khai báo không có tên lớp được gọi là anonymous inner class. Trong trường hợp các lớp bên trong ẩn danh, chúng tôi khai báo và khởi tạo chúng cùng một lúc. Nói chung, chúng được sử dụng bất cứ khi nào bạn cần ghi đè phương thức của một lớp hoặc một giao diện. Cú pháp của một lớp bên trong ẩn danh như sau:

Syntax

AnonymousInner an_inner = new AnonymousInner() {
   public void my_method() {
      ........
      ........
   }   
};

Chương trình sau đây chỉ ra cách ghi đè phương thức của một lớp bằng cách sử dụng lớp bên trong ẩn danh.

Example

abstract class AnonymousInner {
   public abstract void mymethod();
}

public class Outer_class {

   public static void main(String args[]) {
      AnonymousInner inner = new AnonymousInner() {
         public void mymethod() {
            System.out.println("This is an example of anonymous inner class");
         }
      };
      inner.mymethod();	
   }
}

Nếu bạn biên dịch và thực thi chương trình trên, bạn sẽ nhận được kết quả sau:

Output

This is an example of anonymous inner class

Theo cách tương tự, bạn có thể ghi đè các phương thức của lớp cụ thể cũng như giao diện bằng cách sử dụng lớp bên trong ẩn danh.

Lớp bên trong ẩn danh làm đối số

Nói chung, nếu một phương thức chấp nhận một đối tượng của một giao diện, một lớp trừu tượng hoặc một lớp cụ thể, thì chúng ta có thể triển khai giao diện, mở rộng lớp trừu tượng và truyền đối tượng cho phương thức. Nếu nó là một lớp, thì chúng ta có thể truyền trực tiếp nó vào phương thức.

Nhưng trong cả ba trường hợp, bạn có thể truyền một lớp bên trong ẩn danh cho phương thức. Đây là cú pháp truyền một lớp bên trong ẩn danh làm đối số của phương thức:

obj.my_Method(new My_Class() {
   public void Do() {
      .....
      .....
   }
});

Chương trình sau đây chỉ ra cách truyền một lớp bên trong ẩn danh làm đối số phương thức.

Example

// interface
interface Message {
   String greet();
}

public class My_class {
   // method which accepts the object of interface Message
   public void displayMessage(Message m) {
      System.out.println(m.greet() +
         ", This is an example of anonymous inner class as an argument");  
   }

   public static void main(String args[]) {
      // Instantiating the class
      My_class obj = new My_class();

      // Passing an anonymous inner class as an argument
      obj.displayMessage(new Message() {
         public String greet() {
            return "Hello";
         }
      });
   }
}

Nếu bạn biên dịch và thực thi chương trình trên, nó sẽ cho bạn kết quả sau:

Output

Hello, This is an example of anonymous inner class as an argument

Lớp lồng nhau tĩnh

Một lớp bên trong tĩnh là một lớp lồng nhau là một thành viên tĩnh của lớp bên ngoài. Nó có thể được truy cập mà không cần khởi tạo lớp bên ngoài, sử dụng các thành viên tĩnh khác. Cũng giống như các thành viên tĩnh, một lớp lồng nhau tĩnh không có quyền truy cập vào các biến cá thể và phương thức của lớp bên ngoài. Cú pháp của lớp lồng nhau tĩnh như sau:

Syntax

class MyOuter {
   static class Nested_Demo {
   }
}

Việc khởi tạo một lớp lồng nhau tĩnh có một chút khác với việc tạo một lớp bên trong. Chương trình sau đây cho thấy cách sử dụng một lớp lồng nhau tĩnh.

Example

public class Outer {
   static class Nested_Demo {
      public void my_method() {
         System.out.println("This is my nested class");
      }
   }
   
   public static void main(String args[]) {
      Outer.Nested_Demo nested = new Outer.Nested_Demo();	 
      nested.my_method();
   }
}

Nếu bạn biên dịch và thực thi chương trình trên, bạn sẽ nhận được kết quả sau:

Output

This is my nested class

Kế thừa có thể được định nghĩa là quá trình trong đó một lớp mua các thuộc tính (phương thức và trường) của lớp khác. Với việc sử dụng tính kế thừa, thông tin được quản lý theo một thứ tự phân cấp.

Lớp kế thừa các thuộc tính của khác được gọi là lớp con (lớp dẫn xuất, lớp con) và lớp có các thuộc tính được kế thừa được gọi là lớp cha (lớp cơ sở, lớp cha).

mở rộng từ khóa

extendslà từ khóa dùng để kế thừa các thuộc tính của một lớp. Sau đây là cú pháp của từ khóa expand.

Syntax

class Super {
   .....
   .....
}
class Sub extends Super {
   .....
   .....
}

Mã mẫu

Sau đây là một ví dụ minh họa sự kế thừa Java. Trong ví dụ này, bạn có thể quan sát hai lớp là Tính toán và Tính_tính của tôi.

Sử dụng từ khóa expand, My_Calculation kế thừa các phương thức add () và Subtraction () của lớp Tính toán.

Sao chép và dán chương trình sau vào một tệp có tên My_Calculation.java

Example

class Calculation {
   int z;
	
   public void addition(int x, int y) {
      z = x + y;
      System.out.println("The sum of the given numbers:"+z);
   }
	
   public void Subtraction(int x, int y) {
      z = x - y;
      System.out.println("The difference between the given numbers:"+z);
   }
}

public class My_Calculation extends Calculation {
   public void multiplication(int x, int y) {
      z = x * y;
      System.out.println("The product of the given numbers:"+z);
   }
	
   public static void main(String args[]) {
      int a = 20, b = 10;
      My_Calculation demo = new My_Calculation();
      demo.addition(a, b);
      demo.Subtraction(a, b);
      demo.multiplication(a, b);
   }
}

Biên dịch và thực thi đoạn mã trên như hình dưới đây.

javac My_Calculation.java
java My_Calculation

Sau khi thực thi chương trình sẽ cho kết quả như sau:

Output

The sum of the given numbers:30
The difference between the given numbers:10
The product of the given numbers:200

Trong chương trình đã cho, khi một đối tượng My_Calculationlớp được tạo, một bản sao nội dung của lớp cha được tạo bên trong nó. Đó là lý do tại sao, bằng cách sử dụng đối tượng của lớp con, bạn có thể truy cập các thành viên của lớp cha.

Biến tham chiếu Superclass có thể chứa đối tượng của lớp con, nhưng sử dụng biến đó, bạn chỉ có thể truy cập vào các thành viên của lớp cha, do đó, để truy cập các thành viên của cả hai lớp, bạn nên luôn tạo biến tham chiếu cho lớp con.

Nếu bạn xem xét chương trình trên, bạn có thể khởi tạo lớp như dưới đây. Nhưng bằng cách sử dụng biến tham chiếu lớp cha (cal trong trường hợp này) bạn không thể gọi phương thức multiplication(), thuộc về lớp con My_Calculation.

Calculation demo = new My_Calculation();
demo.addition(a, b);
demo.Subtraction(a, b);

Note- Một lớp con kế thừa tất cả các thành viên (trường, phương thức và các lớp lồng nhau) từ lớp cha của nó. Các hàm tạo không phải là thành viên, vì vậy chúng không được kế thừa bởi các lớp con, nhưng hàm tạo của lớp cha có thể được gọi từ lớp con.

Từ khóa siêu

Các super từ khóa tương tự như thistừ khóa. Sau đây là các tình huống mà từ khóa siêu được sử dụng.

  • Nó được sử dụng để differentiate the members của lớp cha từ các thành viên của lớp con, nếu chúng có cùng tên.

  • Nó được sử dụng để invoke the superclass phương thức khởi tạo từ lớp con.

Phân biệt các thành viên

Nếu một lớp đang kế thừa các thuộc tính của lớp khác. Và nếu các thành viên của lớp cha có tên giống lớp con, để phân biệt các biến này chúng ta sử dụng từ khóa super như hình dưới đây.

super.variable
super.method();

Mã mẫu

Phần này cung cấp cho bạn một chương trình chứng minh việc sử dụng super từ khóa.

Trong chương trình đã cho, bạn có hai lớp là Sub_classSuper_class , cả hai đều có một phương thức có tên là display () với các cách triển khai khác nhau và một biến có tên là num với các giá trị khác nhau. Chúng tôi đang gọi phương thức display () của cả hai lớp và in giá trị của biến num của cả hai lớp. Ở đây bạn có thể thấy rằng chúng tôi đã sử dụng từ khóa super để phân biệt các thành viên của lớp cha với lớp con.

Sao chép và dán chương trình vào tệp có tên Sub_class.java.

Example

class Super_class {
   int num = 20;

   // display method of superclass
   public void display() {
      System.out.println("This is the display method of superclass");
   }
}

public class Sub_class extends Super_class {
   int num = 10;

   // display method of sub class
   public void display() {
      System.out.println("This is the display method of subclass");
   }

   public void my_method() {
      // Instantiating subclass
      Sub_class sub = new Sub_class();

      // Invoking the display() method of sub class
      sub.display();

      // Invoking the display() method of superclass
      super.display();

      // printing the value of variable num of subclass
      System.out.println("value of the variable named num in sub class:"+ sub.num);

      // printing the value of variable num of superclass
      System.out.println("value of the variable named num in super class:"+ super.num);
   }

   public static void main(String args[]) {
      Sub_class obj = new Sub_class();
      obj.my_method();
   }
}

Biên dịch và thực thi đoạn mã trên bằng cú pháp sau.

javac Super_Demo
java Super

Khi thực hiện chương trình, bạn sẽ nhận được kết quả sau:

Output

This is the display method of subclass
This is the display method of superclass
value of the variable named num in sub class:10
value of the variable named num in super class:20

Gọi hàm tạo siêu lớp

Nếu một lớp đang kế thừa các thuộc tính của một lớp khác, thì lớp con sẽ tự động lấy hàm tạo mặc định của lớp cha. Nhưng nếu bạn muốn gọi một hàm tạo tham số của lớp cha, bạn cần sử dụng từ khóa super như hình dưới đây.

super(values);

Mã mẫu

Chương trình đưa ra trong phần này trình bày cách sử dụng từ khóa super để gọi phương thức khởi tạo được tham số hóa của lớp cha. Chương trình này chứa một lớp cha và một lớp con, trong đó lớp cha chứa một phương thức khởi tạo được tham số hóa chấp nhận một giá trị số nguyên và chúng tôi đã sử dụng từ khóa super để gọi phương thức khởi tạo tham số hóa của lớp cha.

Sao chép và dán chương trình sau vào tệp có tên Subclass.java

Example

class Superclass {
   int age;

   Superclass(int age) {
      this.age = age; 		 
   }

   public void getAge() {
      System.out.println("The value of the variable named age in super class is: " +age);
   }
}

public class Subclass extends Superclass {
   Subclass(int age) {
      super(age);
   }

   public static void main(String args[]) {
      Subclass s = new Subclass(24);
      s.getAge();
   }
}

Biên dịch và thực thi đoạn mã trên bằng cú pháp sau.

javac Subclass
java Subclass

Khi thực hiện chương trình, bạn sẽ nhận được kết quả sau:

Output

The value of the variable named age in super class is: 24

Mối quan hệ IS-A

IS-A là một cách nói: Đối tượng này là một kiểu của đối tượng đó. Hãy để chúng tôi xem làm thế nàoextends từ khóa được sử dụng để đạt được tính kế thừa.

public class Animal {
}

public class Mammal extends Animal {
}

public class Reptile extends Animal {
}

public class Dog extends Mammal {
}

Bây giờ, dựa trên ví dụ trên, trong thuật ngữ Hướng đối tượng, những điều sau là đúng:

  • Động vật là lớp cha của lớp Động vật có vú.
  • Động vật là lớp phụ của lớp Bò sát.
  • Động vật có vú và Bò sát là các phân lớp của lớp Thú.
  • Chó là lớp con của cả lớp Động vật có vú và Lớp thú.

Bây giờ, nếu chúng ta xem xét mối quan hệ IS-A, chúng ta có thể nói -

  • Mammal IS-A Animal
  • Bò sát IS-A Animal
  • Dog IS-A Mammal
  • Do đó: Chó cũng là một loài động vật

Với việc sử dụng từ khóa expand, các lớp con sẽ có thể kế thừa tất cả các thuộc tính của lớp cha ngoại trừ các thuộc tính riêng của lớp cha.

Chúng ta có thể đảm bảo rằng Động vật có vú thực sự là Động vật với việc sử dụng toán tử cá thể.

Example

class Animal {
}

class Mammal extends Animal {
}

class Reptile extends Animal {
}

public class Dog extends Mammal {

   public static void main(String args[]) {
      Animal a = new Animal();
      Mammal m = new Mammal();
      Dog d = new Dog();

      System.out.println(m instanceof Animal);
      System.out.println(d instanceof Mammal);
      System.out.println(d instanceof Animal);
   }
}

Điều này sẽ tạo ra kết quả sau:

Output

true
true
true

Vì chúng tôi đã hiểu rõ về extends từ khóa, chúng ta hãy xem xét cách implements từ khóa được sử dụng để lấy mối quan hệ IS-A.

Nói chung, implementstừ khóa được sử dụng với các lớp để kế thừa các thuộc tính của một giao diện. Các giao diện không bao giờ có thể được mở rộng bởi một lớp.

Example

public interface Animal {
}

public class Mammal implements Animal {
}

public class Dog extends Mammal {
}

Phiên bản của Từ khoá

Hãy để chúng tôi sử dụng instanceof để kiểm tra xác định xem Động vật có vú có thực sự là Động vật hay không và chó có thực sự là Động vật hay không.

Example

interface Animal{}
class Mammal implements Animal{}

public class Dog extends Mammal {

   public static void main(String args[]) {
      Mammal m = new Mammal();
      Dog d = new Dog();

      System.out.println(m instanceof Animal);
      System.out.println(d instanceof Mammal);
      System.out.println(d instanceof Animal);
   }
}

Điều này sẽ tạo ra kết quả sau:

Output

true
true
true

HAS-A mối quan hệ

Các mối quan hệ này chủ yếu dựa trên cách sử dụng. Điều này xác định xem một lớp nhất địnhHAS-Ađiều chắc chắn. Mối quan hệ này giúp giảm thiểu trùng lặp mã cũng như lỗi.

Hãy xem xét một ví dụ -

Example

public class Vehicle{}
public class Speed{}

public class Van extends Vehicle {
   private Speed sp;
}

Điều này cho thấy Van HAS-A Speed ​​đẳng cấp. Bằng cách có một lớp riêng biệt cho Tốc độ, chúng tôi không phải đặt toàn bộ mã thuộc về tốc độ bên trong lớp Van, điều này có thể giúp sử dụng lại lớp Tốc độ trong nhiều ứng dụng.

Trong tính năng Hướng đối tượng, người dùng không cần phải bận tâm về đối tượng nào đang thực hiện công việc thực sự. Để đạt được điều này, lớp Van ẩn các chi tiết triển khai với người dùng của lớp Van. Vì vậy, về cơ bản những gì sẽ xảy ra là người dùng sẽ yêu cầu lớp Van thực hiện một hành động nhất định và lớp Van sẽ tự thực hiện công việc đó hoặc yêu cầu lớp khác thực hiện hành động đó.

Các loại thừa kế

Có nhiều kiểu thừa kế như được minh họa bên dưới.

Một thực tế rất quan trọng cần nhớ là Java không hỗ trợ đa kế thừa. Điều này có nghĩa là một lớp không thể mở rộng nhiều hơn một lớp. Do đó, hành vi sau là bất hợp pháp -

Example

public class extends Animal, Mammal{}

Tuy nhiên, một lớp có thể triển khai một hoặc nhiều giao diện, điều này đã giúp Java thoát khỏi tình trạng đa thừa kế bất khả thi.

Trong chương trước, chúng ta đã nói về lớp cha và lớp con. Nếu một lớp kế thừa một phương thức từ lớp cha của nó, thì sẽ có cơ hội ghi đè phương thức với điều kiện là nó không được đánh dấu là cuối cùng.

Lợi ích của việc ghi đè là: khả năng xác định một hành vi cụ thể cho kiểu lớp con, có nghĩa là một lớp con có thể triển khai một phương thức của lớp cha dựa trên yêu cầu của nó.

Theo thuật ngữ hướng đối tượng, ghi đè có nghĩa là ghi đè chức năng của một phương thức hiện có.

Thí dụ

Chúng ta hãy xem xét một ví dụ.

class Animal {
   public void move() {
      System.out.println("Animals can move");
   }
}

class Dog extends Animal {
   public void move() {
      System.out.println("Dogs can walk and run");
   }
}

public class TestDog {

   public static void main(String args[]) {
      Animal a = new Animal();   // Animal reference and object
      Animal b = new Dog();   // Animal reference but Dog object

      a.move();   // runs the method in Animal class
      b.move();   // runs the method in Dog class
   }
}

Điều này sẽ tạo ra kết quả sau:

Đầu ra

Animals can move
Dogs can walk and run

Trong ví dụ trên, bạn có thể thấy rằng mặc dù blà một loại Động vật nó chạy phương thức di chuyển trong lớp Chó. Lý do cho điều này là: Trong thời gian biên dịch, việc kiểm tra được thực hiện trên kiểu tham chiếu. Tuy nhiên, trong thời gian chạy, JVM tìm ra loại đối tượng và sẽ chạy phương thức thuộc về đối tượng cụ thể đó.

Do đó, trong ví dụ trên, chương trình sẽ biên dịch đúng cách vì lớp Animal có phương thức di chuyển. Sau đó, trong thời gian chạy, nó chạy phương thức cụ thể cho đối tượng đó.

Hãy xem xét ví dụ sau:

Thí dụ

class Animal {
   public void move() {
      System.out.println("Animals can move");
   }
}

class Dog extends Animal {
   public void move() {
      System.out.println("Dogs can walk and run");
   }
   public void bark() {
      System.out.println("Dogs can bark");
   }
}

public class TestDog {

   public static void main(String args[]) {
      Animal a = new Animal();   // Animal reference and object
      Animal b = new Dog();   // Animal reference but Dog object

      a.move();   // runs the method in Animal class
      b.move();   // runs the method in Dog class
      b.bark();
   }
}

Điều này sẽ tạo ra kết quả sau:

Đầu ra

TestDog.java:26: error: cannot find symbol
      b.bark();
       ^
  symbol:   method bark()
  location: variable b of type Animal
1 error

Chương trình này sẽ gây ra lỗi thời gian biên dịch vì kiểu tham chiếu của b là Animal không có phương thức có tên là vỏ cây.

Quy tắc ghi đè phương pháp

  • Danh sách đối số phải giống hoàn toàn với danh sách của phương thức được ghi đè.

  • Kiểu trả về phải giống hoặc một kiểu con của kiểu trả về được khai báo trong phương thức ghi đè ban đầu trong lớp cha.

  • Cấp độ truy cập không thể hạn chế hơn cấp độ truy cập của phương thức bị ghi đè. Ví dụ: Nếu phương thức của lớp cha được khai báo là public thì phương thức ghi đè trong lớp con không thể là private hoặc protected.

  • Các phương thức phiên bản chỉ có thể được ghi đè nếu chúng được kế thừa bởi lớp con.

  • Không thể ghi đè phương thức được khai báo cuối cùng.

  • Một phương thức được khai báo static không thể bị ghi đè nhưng có thể được khai báo lại.

  • Nếu một phương thức không thể được kế thừa, thì nó không thể được ghi đè.

  • Một lớp con trong cùng một gói với lớp cha của cá thể có thể ghi đè lên bất kỳ phương thức lớp cha nào không được khai báo là private hoặc cuối cùng.

  • Một lớp con trong một gói khác chỉ có thể ghi đè các phương thức không phải là phương thức cuối cùng được khai báo công khai hoặc được bảo vệ.

  • Một phương thức ghi đè có thể ném bất kỳ ngoại lệ nào chưa được chọn, bất kể phương thức ghi đè có ném ngoại lệ hay không. Tuy nhiên, phương thức ghi đè không nên ném các ngoại lệ đã kiểm tra mới hoặc rộng hơn các ngoại lệ được khai báo bởi phương thức ghi đè. Phương thức ghi đè có thể đưa ra các ngoại lệ hẹp hơn hoặc ít hơn phương thức ghi đè.

  • Không thể ghi đè các trình xây dựng.

Sử dụng siêu từ khóa

Khi gọi một phiên bản siêu lớp của một phương thức được ghi đè, super từ khóa được sử dụng.

Thí dụ

class Animal {
   public void move() {
      System.out.println("Animals can move");
   }
}

class Dog extends Animal {
   public void move() {
      super.move();   // invokes the super class method
      System.out.println("Dogs can walk and run");
   }
}

public class TestDog {

   public static void main(String args[]) {
      Animal b = new Dog();   // Animal reference but Dog object
      b.move();   // runs the method in Dog class
   }
}

Điều này sẽ tạo ra kết quả sau:

Đầu ra

Animals can move
Dogs can walk and run

Tính đa hình là khả năng của một đối tượng có nhiều dạng. Việc sử dụng đa hình phổ biến nhất trong OOP xảy ra khi một tham chiếu lớp cha được sử dụng để tham chiếu đến một đối tượng lớp con.

Bất kỳ đối tượng Java nào có thể vượt qua nhiều hơn một bài kiểm tra IS-A đều được coi là đa hình. Trong Java, tất cả các đối tượng Java là đa hình vì bất kỳ đối tượng nào cũng sẽ vượt qua bài kiểm tra IS-A cho kiểu riêng của chúng và cho đối tượng lớp.

Điều quan trọng cần biết là cách duy nhất có thể để truy cập một đối tượng là thông qua một biến tham chiếu. Một biến tham chiếu có thể chỉ có một kiểu. Sau khi được khai báo, không thể thay đổi kiểu của một biến tham chiếu.

Biến tham chiếu có thể được gán lại cho các đối tượng khác miễn là nó không được khai báo cuối cùng. Kiểu của biến tham chiếu sẽ xác định các phương thức mà nó có thể gọi trên đối tượng.

Một biến tham chiếu có thể tham chiếu đến bất kỳ đối tượng nào thuộc kiểu được khai báo của nó hoặc bất kỳ kiểu con nào của kiểu được khai báo. Một biến tham chiếu có thể được khai báo dưới dạng lớp hoặc kiểu giao diện.

Thí dụ

Chúng ta hãy xem xét một ví dụ.

public interface Vegetarian{}
public class Animal{}
public class Deer extends Animal implements Vegetarian{}

Bây giờ, lớp Deer được coi là đa hình vì nó có đa kế thừa. Sau đây là đúng cho các ví dụ trên -

  • Một con hươu là một con vật
  • A Deer IS-A Vegetarian
  • A Deer IS-A Deer
  • A Deer IS-A Object

Khi chúng tôi áp dụng các dữ kiện về biến tham chiếu cho tham chiếu đối tượng Deer, các khai báo sau là hợp pháp:

Thí dụ

Deer d = new Deer();
Animal a = d;
Vegetarian v = d;
Object o = d;

Tất cả các biến tham chiếu d, a, v, o tham chiếu đến cùng một đối tượng Deer trong heap.

Phương pháp ảo

Trong phần này, tôi sẽ chỉ cho bạn cách hoạt động của các phương thức bị ghi đè trong Java cho phép bạn tận dụng tính đa hình khi thiết kế các lớp của mình.

Chúng ta đã thảo luận về việc ghi đè phương thức, trong đó một lớp con có thể ghi đè một phương thức trong lớp cha của nó. Một phương thức được ghi đè về cơ bản được ẩn trong lớp cha và không được gọi ra trừ khi lớp con sử dụng từ khóa super trong phương thức ghi đè.

Thí dụ

/* File name : Employee.java */
public class Employee {
   private String name;
   private String address;
   private int number;

   public Employee(String name, String address, int number) {
      System.out.println("Constructing an Employee");
      this.name = name;
      this.address = address;
      this.number = number;
   }

   public void mailCheck() {
      System.out.println("Mailing a check to " + this.name + " " + this.address);
   }

   public String toString() {
      return name + " " + address + " " + number;
   }

   public String getName() {
      return name;
   }

   public String getAddress() {
      return address;
   }

   public void setAddress(String newAddress) {
      address = newAddress;
   }

   public int getNumber() {
      return number;
   }
}

Bây giờ, giả sử chúng ta mở rộng lớp Nhân viên như sau:

/* File name : Salary.java */
public class Salary extends Employee {
   private double salary; // Annual salary
   
   public Salary(String name, String address, int number, double salary) {
      super(name, address, number);
      setSalary(salary);
   }
   
   public void mailCheck() {
      System.out.println("Within mailCheck of Salary class ");
      System.out.println("Mailing check to " + getName()
      + " with salary " + salary);
   }
   
   public double getSalary() {
      return salary;
   }
   
   public void setSalary(double newSalary) {
      if(newSalary >= 0.0) {
         salary = newSalary;
      }
   }
   
   public double computePay() {
      System.out.println("Computing salary pay for " + getName());
      return salary/52;
   }
}

Bây giờ, bạn nghiên cứu kỹ chương trình sau và cố gắng xác định đầu ra của nó -

/* File name : VirtualDemo.java */
public class VirtualDemo {

   public static void main(String [] args) {
      Salary s = new Salary("Mohd Mohtashim", "Ambehta, UP", 3, 3600.00);
      Employee e = new Salary("John Adams", "Boston, MA", 2, 2400.00);
      System.out.println("Call mailCheck using Salary reference --");   
      s.mailCheck();
      System.out.println("\n Call mailCheck using Employee reference--");
      e.mailCheck();
   }
}

Điều này sẽ tạo ra kết quả sau:

Đầu ra

Constructing an Employee
Constructing an Employee

Call mailCheck using Salary reference --
Within mailCheck of Salary class
Mailing check to Mohd Mohtashim with salary 3600.0

Call mailCheck using Employee reference--
Within mailCheck of Salary class
Mailing check to John Adams with salary 2400.0

Ở đây, chúng tôi khởi tạo hai đối tượng Lương. Một sử dụng tham chiếu mức lươngsvà cái khác sử dụng tham chiếu Nhân viên e.

Trong khi gọi s.mailCheck () , trình biên dịch sẽ thấy mailCheck () trong lớp Lương tại thời điểm biên dịch và JVM gọi mailCheck () trong lớp Lương tại thời điểm chạy.

mailCheck () trên e khá khác biệt bởi vì elà một tài liệu tham khảo của Nhân viên. Khi trình biên dịch thấy e.mailCheck () , trình biên dịch sẽ thấy phương thức mailCheck () trong lớp Employee.

Ở đây, tại thời điểm biên dịch, trình biên dịch đã sử dụng mailCheck () trong Employee để xác thực câu lệnh này. Tuy nhiên, tại thời điểm chạy, JVM gọi mailCheck () trong lớp Lương.

Hành vi này được gọi là lệnh gọi phương thức ảo và các phương thức này được gọi là phương thức ảo. Một phương thức ghi đè được gọi trong thời gian chạy, bất kể kiểu dữ liệu nào mà tham chiếu đó được sử dụng trong mã nguồn tại thời điểm biên dịch.

Theo từ điển, abstractionlà chất lượng của việc xử lý các ý tưởng hơn là các sự kiện. Ví dụ, khi bạn xem xét trường hợp của e-mail, các chi tiết phức tạp như điều gì xảy ra ngay sau khi bạn gửi e-mail, giao thức mà máy chủ e-mail của bạn sử dụng sẽ bị ẩn khỏi người dùng. Do đó, để gửi e-mail bạn chỉ cần nhập nội dung, đề cập đến địa chỉ người nhận và nhấn gửi.

Tương tự như vậy trong lập trình hướng đối tượng, trừu tượng hóa là một quá trình ẩn các chi tiết thực hiện với người dùng, chỉ chức năng sẽ được cung cấp cho người dùng. Nói cách khác, người dùng sẽ có thông tin về những gì đối tượng làm thay vì cách nó thực hiện.

Trong Java, trừu tượng hóa đạt được bằng cách sử dụng các lớp và giao diện trừu tượng.

Lớp trừu tượng

Một lớp có chứa abstract từ khóa trong khai báo của nó được gọi là lớp trừu tượng.

  • Các lớp trừu tượng có thể có hoặc không chứa các phương thức trừu tượng , tức là các phương thức không có phần thân (public void get ();)

  • Tuy nhiên, nếu một lớp có ít nhất một phương thức trừu tượng, thì lớp must được khai báo trừu tượng.

  • Nếu một lớp được khai báo là trừu tượng, nó không thể được khởi tạo.

  • Để sử dụng một lớp trừu tượng, bạn phải kế thừa nó từ một lớp khác, cung cấp các triển khai cho các phương thức trừu tượng trong đó.

  • Nếu bạn kế thừa một lớp trừu tượng, bạn phải cung cấp các triển khai cho tất cả các phương thức trừu tượng trong đó.

Thí dụ

Phần này cung cấp cho bạn một ví dụ về lớp trừu tượng. Để tạo một lớp trừu tượng, chỉ cần sử dụngabstract từ khóa trước từ khóa lớp, trong khai báo lớp.

/* File name : Employee.java */
public abstract class Employee {
   private String name;
   private String address;
   private int number;

   public Employee(String name, String address, int number) {
      System.out.println("Constructing an Employee");
      this.name = name;
      this.address = address;
      this.number = number;
   }
   
   public double computePay() {
     System.out.println("Inside Employee computePay");
     return 0.0;
   }
   
   public void mailCheck() {
      System.out.println("Mailing a check to " + this.name + " " + this.address);
   }

   public String toString() {
      return name + " " + address + " " + number;
   }

   public String getName() {
      return name;
   }
 
   public String getAddress() {
      return address;
   }
   
   public void setAddress(String newAddress) {
      address = newAddress;
   }
 
   public int getNumber() {
      return number;
   }
}

Bạn có thể nhận thấy rằng ngoại trừ các phương thức trừu tượng, lớp Employee giống như lớp bình thường trong Java. Lớp bây giờ là trừu tượng, nhưng nó vẫn có ba trường, bảy phương thức và một hàm tạo.

Bây giờ bạn có thể thử khởi tạo lớp Nhân viên theo cách sau:

/* File name : AbstractDemo.java */
public class AbstractDemo {

   public static void main(String [] args) {
      /* Following is not allowed and would raise error */
      Employee e = new Employee("George W.", "Houston, TX", 43);
      System.out.println("\n Call mailCheck using Employee reference--");
      e.mailCheck();
   }
}

Khi bạn biên dịch lớp trên, nó sẽ cho bạn lỗi sau:

Employee.java:46: Employee is abstract; cannot be instantiated
      Employee e = new Employee("George W.", "Houston, TX", 43);
                   ^
1 error

Kế thừa lớp trừu tượng

Chúng ta có thể kế thừa các thuộc tính của lớp Employee giống như lớp cụ thể theo cách sau:

Thí dụ

/* File name : Salary.java */
public class Salary extends Employee {
   private double salary;   // Annual salary
   
   public Salary(String name, String address, int number, double salary) {
      super(name, address, number);
      setSalary(salary);
   }
   
   public void mailCheck() {
      System.out.println("Within mailCheck of Salary class ");
      System.out.println("Mailing check to " + getName() + " with salary " + salary);
   }
 
   public double getSalary() {
      return salary;
   }
   
   public void setSalary(double newSalary) {
      if(newSalary >= 0.0) {
         salary = newSalary;
      }
   }
   
   public double computePay() {
      System.out.println("Computing salary pay for " + getName());
      return salary/52;
   }
}

Ở đây, bạn không thể khởi tạo lớp Nhân viên, nhưng bạn có thể khởi tạo Lớp Lương và sử dụng trường hợp này, bạn có thể truy cập tất cả ba trường và bảy phương thức của lớp Nhân viên như được hiển thị bên dưới.

/* File name : AbstractDemo.java */
public class AbstractDemo {

   public static void main(String [] args) {
      Salary s = new Salary("Mohd Mohtashim", "Ambehta, UP", 3, 3600.00);
      Employee e = new Salary("John Adams", "Boston, MA", 2, 2400.00);
      System.out.println("Call mailCheck using Salary reference --");
      s.mailCheck();
      System.out.println("\n Call mailCheck using Employee reference--");
      e.mailCheck();
   }
}

Điều này tạo ra kết quả sau:

Đầu ra

Constructing an Employee
Constructing an Employee
Call mailCheck using Salary reference --
Within mailCheck of Salary class 
Mailing check to Mohd Mohtashim with salary 3600.0

 Call mailCheck using Employee reference--
Within mailCheck of Salary class 
Mailing check to John Adams with salary 2400.0

Phương pháp trừu tượng

Nếu bạn muốn một lớp chứa một phương thức cụ thể nhưng bạn muốn việc triển khai thực sự của phương thức đó được xác định bởi các lớp con, bạn có thể khai báo phương thức trong lớp cha dưới dạng trừu tượng.

  • abstract từ khóa được sử dụng để khai báo phương thức là trừu tượng.

  • Bạn phải đặt abstract từ khóa trước tên phương thức trong khai báo phương thức.

  • Một phương thức trừu tượng chứa một chữ ký phương thức, nhưng không có thân phương thức.

  • Thay vì dấu ngoặc nhọn, một phương thức trừu tượng sẽ có dấu hai chấm semoi (;) ở cuối.

Sau đây là một ví dụ về phương thức trừu tượng.

Thí dụ

public abstract class Employee {
   private String name;
   private String address;
   private int number;
   
   public abstract double computePay();
   // Remainder of class definition
}

Khai báo một phương thức dưới dạng trừu tượng có hai hệ quả:

  • Lớp chứa nó phải được khai báo là trừu tượng.

  • Bất kỳ lớp nào kế thừa lớp hiện tại phải ghi đè phương thức trừu tượng hoặc khai báo chính nó là trừu tượng.

Note- Cuối cùng, một lớp con phải thực hiện phương thức trừu tượng; nếu không, bạn sẽ có một hệ thống phân cấp các lớp trừu tượng không thể được khởi tạo.

Giả sử lớp Lương kế thừa lớp Nhân viên, sau đó nó sẽ triển khai computePay() như hình dưới đây -

/* File name : Salary.java */
public class Salary extends Employee {
   private double salary;   // Annual salary
  
   public double computePay() {
      System.out.println("Computing salary pay for " + getName());
      return salary/52;
   }
   // Remainder of class definition
}

Encapsulationlà một trong bốn khái niệm OOP cơ bản. Ba phần còn lại là kế thừa, đa hình và trừu tượng.

Đóng gói trong Java là một cơ chế gói dữ liệu (biến) và mã tác động lên dữ liệu (phương thức) lại với nhau như một đơn vị duy nhất. Trong tính năng đóng gói, các biến của một lớp sẽ bị ẩn khỏi các lớp khác và chỉ có thể được truy cập thông qua các phương thức của lớp hiện tại của chúng. Do đó, nó còn được gọi làdata hiding.

Để đạt được tính đóng gói trong Java -

  • Khai báo các biến của một lớp là private.

  • Cung cấp phương thức setter và getter công khai để sửa đổi và xem các giá trị của biến.

Thí dụ

Sau đây là một ví dụ minh họa cách đạt được tính năng Đóng gói trong Java:

/* File name : EncapTest.java */
public class EncapTest {
   private String name;
   private String idNum;
   private int age;

   public int getAge() {
      return age;
   }

   public String getName() {
      return name;
   }

   public String getIdNum() {
      return idNum;
   }

   public void setAge( int newAge) {
      age = newAge;
   }

   public void setName(String newName) {
      name = newName;
   }

   public void setIdNum( String newId) {
      idNum = newId;
   }
}

Phương thức public setXXX () và getXXX () là các điểm truy cập của các biến thể hiện của lớp EncapTest. Thông thường, các phương pháp này được gọi là getters và setters. Do đó, bất kỳ lớp nào muốn truy cập các biến nên truy cập chúng thông qua các getters và setters này.

Các biến của lớp EncapTest có thể được truy cập bằng chương trình sau:

/* File name : RunEncap.java */
public class RunEncap {

   public static void main(String args[]) {
      EncapTest encap = new EncapTest();
      encap.setName("James");
      encap.setAge(20);
      encap.setIdNum("12343ms");

      System.out.print("Name : " + encap.getName() + " Age : " + encap.getAge());
   }
}

Điều này sẽ tạo ra kết quả sau:

Đầu ra

Name : James Age : 20

Lợi ích của việc đóng gói

  • Các trường của một lớp có thể được đặt ở chế độ chỉ đọc hoặc chỉ ghi.

  • Một lớp có thể có toàn quyền kiểm soát những gì được lưu trữ trong các trường của nó.

Giao diện là một kiểu tham chiếu trong Java. Nó tương tự như lớp học. Nó là một tập hợp các phương thức trừu tượng. Một lớp thực hiện một giao diện, do đó kế thừa các phương thức trừu tượng của giao diện.

Cùng với các phương thức trừu tượng, một giao diện cũng có thể chứa các hằng số, phương thức mặc định, phương thức tĩnh và các kiểu lồng nhau. Các thân phương thức chỉ tồn tại cho các phương thức mặc định và phương thức tĩnh.

Viết một giao diện tương tự như viết một lớp. Nhưng một lớp mô tả các thuộc tính và hành vi của một đối tượng. Và một giao diện chứa các hành vi mà một lớp thực hiện.

Trừ khi lớp triển khai giao diện là trừu tượng, tất cả các phương thức của giao diện cần được định nghĩa trong lớp.

Giao diện tương tự như một lớp theo những cách sau:

  • Một giao diện có thể chứa bất kỳ số lượng phương thức nào.

  • Giao diện được viết trong một tệp có .java phần mở rộng, với tên của giao diện khớp với tên của tệp.

  • Mã byte của một giao diện xuất hiện trong một .class tập tin.

  • Các giao diện xuất hiện trong các gói và tệp bytecode tương ứng của chúng phải nằm trong cấu trúc thư mục khớp với tên gói.

Tuy nhiên, giao diện khác với một lớp theo một số cách, bao gồm:

  • Bạn không thể khởi tạo một giao diện.

  • Một giao diện không chứa bất kỳ hàm tạo nào.

  • Tất cả các phương thức trong một giao diện là trừu tượng.

  • Một giao diện không thể chứa các trường cá thể. Các trường duy nhất có thể xuất hiện trong giao diện phải được khai báo cả tĩnh và cuối cùng.

  • Một giao diện không được mở rộng bởi một lớp; nó được thực hiện bởi một lớp.

  • Một giao diện có thể mở rộng nhiều giao diện.

Khai báo giao diện

Các interfacetừ khóa được sử dụng để khai báo một giao diện. Đây là một ví dụ đơn giản để khai báo một giao diện -

Thí dụ

Sau đây là một ví dụ về giao diện -

/* File name : NameOfInterface.java */
import java.lang.*;
// Any number of import statements

public interface NameOfInterface {
   // Any number of final, static fields
   // Any number of abstract method declarations\
}

Các giao diện có các thuộc tính sau:

  • Một giao diện là hoàn toàn trừu tượng. Bạn không cần phải sử dụngabstract trong khi khai báo một giao diện.

  • Mỗi phương thức trong một giao diện cũng hoàn toàn trừu tượng, vì vậy từ khóa trừu tượng là không cần thiết.

  • Các phương thức trong một giao diện là hoàn toàn công khai.

Thí dụ

/* File name : Animal.java */
interface Animal {
   public void eat();
   public void travel();
}

Triển khai giao diện

Khi một lớp triển khai một giao diện, bạn có thể coi lớp đó giống như việc ký một hợp đồng, đồng ý thực hiện các hành vi cụ thể của giao diện. Nếu một lớp không thực hiện tất cả các hành vi của giao diện, thì lớp đó phải tự khai báo là trừu tượng.

Một lớp sử dụng implementstừ khóa để triển khai một giao diện. Từ khóa triển khai xuất hiện trong khai báo lớp sau phần mở rộng của khai báo.

Thí dụ

/* File name : MammalInt.java */
public class MammalInt implements Animal {

   public void eat() {
      System.out.println("Mammal eats");
   }

   public void travel() {
      System.out.println("Mammal travels");
   } 

   public int noOfLegs() {
      return 0;
   }

   public static void main(String args[]) {
      MammalInt m = new MammalInt();
      m.eat();
      m.travel();
   }
}

Điều này sẽ tạo ra kết quả sau:

Đầu ra

Mammal eats
Mammal travels

Khi ghi đè các phương thức được xác định trong giao diện, có một số quy tắc cần tuân theo:

  • Các ngoại lệ đã kiểm tra không được khai báo trên các phương thức thực thi khác với các ngoại lệ được khai báo bởi phương thức giao diện hoặc các lớp con của những ngoại lệ được khai báo bởi phương thức giao diện.

  • Chữ ký của phương thức giao diện và cùng kiểu trả về hoặc kiểu con phải được duy trì khi ghi đè các phương thức.

  • Bản thân một lớp thực thi có thể trừu tượng và nếu vậy, các phương thức giao diện không cần được thực hiện.

Khi giao diện triển khai, có một số quy tắc:

  • Một lớp có thể triển khai nhiều giao diện cùng một lúc.

  • Một lớp chỉ có thể mở rộng một lớp, nhưng triển khai nhiều giao diện.

  • Một giao diện có thể mở rộng một giao diện khác, theo cách tương tự như một lớp có thể mở rộng một lớp khác.

Mở rộng giao diện

Một giao diện có thể mở rộng một giao diện khác giống như cách mà một lớp có thể mở rộng một lớp khác. Cácextends từ khóa được sử dụng để mở rộng giao diện và giao diện con kế thừa các phương thức của giao diện mẹ.

Giao diện Thể thao sau đây được mở rộng bởi giao diện Khúc côn cầu và Bóng đá.

Thí dụ

// Filename: Sports.java
public interface Sports {
   public void setHomeTeam(String name);
   public void setVisitingTeam(String name);
}

// Filename: Football.java
public interface Football extends Sports {
   public void homeTeamScored(int points);
   public void visitingTeamScored(int points);
   public void endOfQuarter(int quarter);
}

// Filename: Hockey.java
public interface Hockey extends Sports {
   public void homeGoalScored();
   public void visitingGoalScored();
   public void endOfPeriod(int period);
   public void overtimePeriod(int ot);
}

Giao diện Hockey có bốn phương thức, nhưng nó kế thừa hai phương thức từ Sports; do đó, một lớp triển khai Hockey cần thực hiện tất cả sáu phương thức. Tương tự, một lớp triển khai Bóng đá cần xác định ba phương thức từ Bóng đá và hai phương thức từ Thể thao.

Mở rộng nhiều giao diện

Một lớp Java chỉ có thể mở rộng một lớp cha. Không cho phép nhiều thừa kế. Tuy nhiên, các giao diện không phải là các lớp và một giao diện có thể mở rộng nhiều hơn một giao diện mẹ.

Từ khóa expand được sử dụng một lần và các giao diện mẹ được khai báo trong danh sách được phân tách bằng dấu phẩy.

Ví dụ: nếu giao diện Khúc côn cầu mở rộng cả Thể thao và Sự kiện, nó sẽ được khai báo là:

Thí dụ

public interface Hockey extends Sports, Event

Gắn thẻ giao diện

Việc sử dụng giao diện mở rộng phổ biến nhất xảy ra khi giao diện mẹ không chứa bất kỳ phương thức nào. Ví dụ: giao diện MouseListener trong gói java.awt.event mở rộng java.util.EventListener, được định nghĩa là:

Thí dụ

package java.util;
public interface EventListener
{}

Một giao diện không có phương thức nào trong đó được gọi là tagginggiao diện. Có hai mục đích thiết kế cơ bản của giao diện gắn thẻ:

Creates a common parent- Như với giao diện EventListener, được mở rộng bởi hàng chục giao diện khác trong Java API, bạn có thể sử dụng giao diện gắn thẻ để tạo giao diện mẹ chung giữa một nhóm giao diện. Ví dụ: khi một giao diện mở rộng EventListener, JVM biết rằng giao diện cụ thể này sẽ được sử dụng trong một kịch bản ủy quyền sự kiện.

Adds a data type to a class- Tình huống này là do thuật ngữ, việc gắn thẻ đến từ đâu. Một lớp thực hiện giao diện gắn thẻ không cần xác định bất kỳ phương thức nào (vì giao diện không có bất kỳ phương thức nào), nhưng lớp này trở thành một kiểu giao diện thông qua tính đa hình.

Các gói được sử dụng trong Java để ngăn xung đột đặt tên, kiểm soát quyền truy cập, giúp tìm kiếm / định vị và sử dụng các lớp, giao diện, liệt kê và chú thích dễ dàng hơn, v.v.

A Package có thể được định nghĩa là một nhóm các kiểu liên quan (lớp, giao diện, liệt kê và chú thích) cung cấp khả năng bảo vệ truy cập và quản lý vùng tên.

Một số gói hiện có trong Java là:

  • java.lang - gói các lớp cơ bản

  • java.io - các lớp cho chức năng đầu vào, đầu ra được đóng gói trong gói này

Lập trình viên có thể xác định các gói của riêng họ để đóng gói nhóm lớp / giao diện, v.v. Bạn nên nhóm các lớp liên quan do bạn thực hiện để lập trình viên có thể dễ dàng xác định rằng các lớp, giao diện, liệt kê và chú thích có liên quan với nhau.

Vì gói tạo một không gian tên mới nên sẽ không có bất kỳ xung đột tên nào với các tên trong các gói khác. Sử dụng gói, việc cung cấp kiểm soát truy cập dễ dàng hơn và định vị các lớp liên quan cũng dễ dàng hơn.

Tạo một gói

Trong khi tạo một gói, bạn nên chọn tên cho gói và bao gồm package câu lệnh cùng với tên đó ở đầu mỗi tệp nguồn chứa các lớp, giao diện, kiểu liệt kê và chú thích mà bạn muốn đưa vào gói.

Câu lệnh gói phải là dòng đầu tiên trong tệp nguồn. Chỉ có thể có một câu lệnh gói trong mỗi tệp nguồn và nó áp dụng cho tất cả các loại trong tệp.

Nếu một câu lệnh gói không được sử dụng thì lớp, giao diện, kiểu liệt kê và chú thích sẽ được đặt trong gói mặc định hiện tại.

Để biên dịch các chương trình Java với các câu lệnh gói, bạn phải sử dụng tùy chọn -d như hình dưới đây.

javac -d Destination_folder file_name.java

Sau đó, một thư mục với tên gói đã cho được tạo ở đích được chỉ định và các tệp lớp đã biên dịch sẽ được đặt trong thư mục đó.

Thí dụ

Chúng ta hãy xem một ví dụ tạo một gói có tên animals. Một thực tiễn tốt là sử dụng tên của các gói bằng chữ thường để tránh bất kỳ xung đột nào với tên của các lớp và giao diện.

Ví dụ gói sau chứa giao diện có tên động vật :

/* File name : Animal.java */
package animals;

interface Animal {
   public void eat();
   public void travel();
}

Bây giờ, chúng ta hãy triển khai giao diện trên trong cùng một gói động vật -

package animals;
/* File name : MammalInt.java */

public class MammalInt implements Animal {

   public void eat() {
      System.out.println("Mammal eats");
   }

   public void travel() {
      System.out.println("Mammal travels");
   } 

   public int noOfLegs() {
      return 0;
   }

   public static void main(String args[]) {
      MammalInt m = new MammalInt();
      m.eat();
      m.travel();
   }
}

Bây giờ biên dịch các tệp java như được hiển thị bên dưới:

$ javac -d . Animal.java $ javac -d . MammalInt.java

Bây giờ là một gói / thư mục có tên animals sẽ được tạo trong thư mục hiện tại và các tệp lớp này sẽ được đặt trong đó như hình dưới đây.

Bạn có thể thực thi tệp lớp trong gói và nhận được kết quả như hình dưới đây.

Mammal eats
Mammal travels

Từ khoá nhập

Nếu một lớp muốn sử dụng một lớp khác trong cùng một gói thì không cần sử dụng tên gói. Các lớp trong cùng một gói tìm thấy nhau mà không cần bất kỳ cú pháp đặc biệt nào.

Thí dụ

Ở đây, một lớp có tên là Boss được thêm vào gói bảng lương đã chứa Nhân viên. Sau đó, Sếp có thể tham chiếu đến lớp Nhân viên mà không cần sử dụng tiền tố bảng lương, như được chứng minh bởi lớp Sếp sau đây.

package payroll;
public class Boss {
   public void payEmployee(Employee e) {
      e.mailCheck();
   }
}

Điều gì xảy ra nếu lớp Nhân viên không có trong gói trả lương? Sau đó, lớp Boss phải sử dụng một trong các kỹ thuật sau để tham chiếu đến một lớp trong một gói khác.

  • Tên đủ điều kiện của lớp có thể được sử dụng. Ví dụ -
payroll.Employee
  • Có thể nhập gói bằng từ khóa nhập và ký tự đại diện (*). Ví dụ -

import payroll.*;
  • Bản thân lớp có thể được nhập bằng từ khóa import. Ví dụ -
import payroll.Employee;

Note- Một tệp lớp có thể chứa bất kỳ số lượng câu lệnh nhập nào. Các câu lệnh nhập phải xuất hiện sau câu lệnh gói và trước phần khai báo lớp.

Cấu trúc thư mục của các gói

Hai kết quả chính xảy ra khi một lớp được đặt trong một gói:

  • Tên của gói trở thành một phần của tên của lớp, như chúng ta vừa thảo luận trong phần trước.

  • Tên của gói phải phù hợp với cấu trúc thư mục nơi cư trú của mã bytecode tương ứng.

Đây là cách đơn giản để quản lý các tệp của bạn trong Java -

Đặt mã nguồn cho một loại lớp, giao diện, liệt kê hoặc chú thích trong tệp văn bản có tên là tên đơn giản của loại và có phần mở rộng là .java.

Ví dụ -

// File Name :  Car.java
package vehicle;

public class Car {
   // Class implementation.   
}

Bây giờ, hãy đặt tệp nguồn vào một thư mục có tên phản ánh tên của gói mà lớp thuộc về -

....\vehicle\Car.java

Bây giờ, tên lớp đủ điều kiện và tên đường dẫn sẽ như sau:

  • Tên lớp → xe.Car
  • Tên đường dẫn → xe \ Car.java (trong cửa sổ)

Nói chung, một công ty sử dụng tên miền Internet đảo ngược cho các tên gói của nó.

Example- Tên miền Internet của một công ty là apple.com, sau đó tất cả các tên gói của nó sẽ bắt đầu bằng com.apple. Mỗi thành phần của tên gói tương ứng với một thư mục con.

Example - Công ty có một gói com.apple.computers chứa tệp nguồn Dell.java, nó sẽ được chứa trong một loạt các thư mục con như thế này -

....\com\apple\computers\Dell.java

Tại thời điểm biên dịch, trình biên dịch tạo một tệp đầu ra khác nhau cho mỗi lớp, giao diện và kiểu liệt kê được xác định trong đó. Tên cơ sở của tệp đầu ra là tên của loại và phần mở rộng của nó là.class.

Ví dụ -

// File Name: Dell.java
package com.apple.computers;

public class Dell {
}

class Ups {
}

Bây giờ, hãy biên dịch tệp này như sau bằng cách sử dụng tùy chọn -d -

$javac -d . Dell.java

Các tập tin sẽ được biên dịch như sau:

.\com\apple\computers\Dell.class
.\com\apple\computers\Ups.class

Bạn có thể nhập tất cả các lớp hoặc giao diện được xác định trong \ com \ apple \ computer \ như sau:

import com.apple.computers.*;

Giống như các tệp nguồn .java, các tệp .class được biên dịch phải nằm trong một loạt các thư mục phản ánh tên gói. Tuy nhiên, đường dẫn đến tệp .class không nhất thiết phải giống với đường dẫn đến tệp nguồn .java. Bạn có thể sắp xếp các thư mục nguồn và thư mục lớp của mình một cách riêng biệt, như:

<path-one>\sources\com\apple\computers\Dell.java

<path-two>\classes\com\apple\computers\Dell.class

Bằng cách này, có thể cấp quyền truy cập vào thư mục lớp cho các lập trình viên khác mà không tiết lộ nguồn của bạn. Bạn cũng cần quản lý các tệp nguồn và lớp theo cách này để trình biên dịch và Máy ảo Java (JVM) có thể tìm thấy tất cả các kiểu chương trình của bạn sử dụng.

Đường dẫn đầy đủ đến thư mục lớp, <path-two> \ các lớp, được gọi là đường dẫn lớp và được đặt bằng biến hệ thống CLASSPATH. Cả trình biên dịch và JVM đều xây dựng đường dẫn đến tệp .class của bạn bằng cách thêm tên gói vào đường dẫn lớp.

Giả sử các lớp <path-two> \ là đường dẫn lớp và tên gói là com.apple.computers, sau đó trình biên dịch và JVM sẽ tìm kiếm các tệp .class trong máy tính <path-two> \ class \ com \ apple \.

Một đường dẫn lớp có thể bao gồm một số đường dẫn. Nhiều đường dẫn phải được phân tách bằng dấu chấm phẩy (Windows) hoặc dấu hai chấm (Unix). Theo mặc định, trình biên dịch và JVM tìm kiếm thư mục hiện tại và tệp JAR chứa các lớp nền tảng Java để các thư mục này tự động nằm trong đường dẫn lớp.

Đặt biến hệ thống CLASSPATH

Để hiển thị biến CLASSPATH hiện tại, hãy sử dụng các lệnh sau trong Windows và UNIX (Bourne shell):

  • Trong Windows → C: \> đặt CLASSPATH
  • Trong UNIX →% echo $ CLASSPATH

Để xóa nội dung hiện tại của biến CLASSPATH, hãy sử dụng -

  • Trong Windows → C: \> đặt CLASSPATH =
  • Trong UNIX →% không đặt CLASSPATH; xuất CLASSPATH

Để đặt biến CLASSPATH -

  • Trong Windows → đặt CLASSPATH = C: \ users \ jack \ java \ class
  • Trong UNIX →% CLASSPATH = / home / jack / java / class; xuất CLASSPATH

Các cấu trúc dữ liệu được cung cấp bởi gói tiện ích Java rất mạnh và thực hiện một loạt các chức năng. Các cấu trúc dữ liệu này bao gồm giao diện và các lớp sau:

  • Enumeration
  • BitSet
  • Vector
  • Stack
  • Dictionary
  • Hashtable
  • Properties

Tất cả các lớp này hiện là kế thừa và Java-2 đã giới thiệu một khuôn khổ mới có tên là Collections Framework, sẽ được thảo luận trong chương tiếp theo. -

Bảng kê

Bản thân giao diện Enumeration không phải là một cấu trúc dữ liệu, nhưng nó rất quan trọng trong bối cảnh của các cấu trúc dữ liệu khác. Giao diện Enumeration định nghĩa một phương tiện để truy xuất các phần tử kế tiếp từ một cấu trúc dữ liệu.

Ví dụ, Enumeration định nghĩa một phương thức được gọi là nextElement được sử dụng để lấy phần tử tiếp theo trong cấu trúc dữ liệu có chứa nhiều phần tử.

Để biết thêm chi tiết về giao diện này, hãy kiểm tra Danh sách .

BitSet

Lớp BitSet thực hiện một nhóm các bit hoặc cờ có thể được đặt và xóa riêng lẻ.

Lớp này rất hữu ích trong trường hợp bạn cần theo kịp một tập các giá trị Boolean; bạn chỉ cần gán một chút cho mỗi giá trị và đặt hoặc xóa nó khi thích hợp.

Để biết thêm chi tiết về lớp này, hãy xem BitSet .

Véc tơ

Lớp Vector tương tự như một mảng Java truyền thống, ngoại trừ việc nó có thể phát triển khi cần thiết để chứa các phần tử mới.

Giống như một mảng, các phần tử của đối tượng Vector có thể được truy cập thông qua một chỉ mục vào vector.

Điều thú vị khi sử dụng lớp Vector là bạn không phải lo lắng về việc đặt nó thành một kích thước cụ thể khi tạo; nó tự động thu nhỏ và phát triển khi cần thiết.

Để biết thêm chi tiết về lớp này, hãy kiểm tra Vector .

Ngăn xếp

Lớp Stack thực hiện một ngăn xếp các phần tử cuối cùng trong đầu ra (LIFO).

Bạn có thể nghĩ về một ngăn xếp theo nghĩa đen là một chồng các đối tượng theo chiều dọc; khi bạn thêm một phần tử mới, phần tử đó sẽ được xếp chồng lên các phần tử khác.

Khi bạn kéo một phần tử ra khỏi ngăn xếp, phần tử đó sẽ xuất hiện trên cùng. Nói cách khác, phần tử cuối cùng bạn thêm vào ngăn xếp là phần tử đầu tiên quay trở lại.

Để biết thêm chi tiết về lớp này, hãy kiểm tra The Stack .

Từ điển

Lớp Từ điển là một lớp trừu tượng xác định cấu trúc dữ liệu để ánh xạ các khóa thành các giá trị.

Điều này hữu ích trong trường hợp bạn muốn có thể truy cập dữ liệu thông qua một khóa cụ thể chứ không phải chỉ mục số nguyên.

Vì lớp Từ điển là trừu tượng, nó chỉ cung cấp khuôn khổ cho cấu trúc dữ liệu ánh xạ khóa chứ không phải là một triển khai cụ thể.

Để biết thêm chi tiết về lớp này, hãy xem Từ điển .

Hashtable

Lớp Hashtable cung cấp một phương tiện tổ chức dữ liệu dựa trên một số cấu trúc khóa do người dùng định nghĩa.

Ví dụ, trong bảng băm danh sách địa chỉ, bạn có thể lưu trữ và sắp xếp dữ liệu dựa trên một khóa như mã ZIP thay vì tên của một người.

Ý nghĩa cụ thể của các khóa liên quan đến bảng băm hoàn toàn phụ thuộc vào việc sử dụng bảng băm và dữ liệu mà nó chứa.

Để biết thêm chi tiết về lớp này, hãy xem Hashtable .

Các thuộc tính

Thuộc tính là một lớp con của Hashtable. Nó được sử dụng để duy trì danh sách các giá trị trong đó khóa là một Chuỗi và giá trị cũng là một Chuỗi.

Lớp Thuộc tính được sử dụng bởi nhiều lớp Java khác. Ví dụ, nó là kiểu đối tượng được trả về bởi System.getProperties () khi lấy các giá trị môi trường.

Để biết thêm chi tiết về lớp này, hãy kiểm tra Thuộc tính .

Trước Java 2, Java đã cung cấp các lớp đặc biệt như Dictionary, Vector, Stack,Propertiesđể lưu trữ và thao tác các nhóm đối tượng. Mặc dù các lớp học này khá hữu ích, nhưng chúng thiếu một chủ đề trung tâm, thống nhất. Do đó, cách bạn sử dụng Vector khác với cách bạn sử dụng Thuộc tính.

Khung bộ sưu tập được thiết kế để đáp ứng một số mục tiêu, chẳng hạn như -

  • Khung phải có hiệu suất cao. Việc triển khai các tập hợp cơ bản (mảng động, danh sách liên kết, cây và bảng băm) phải có hiệu quả cao.

  • Khung công tác phải cho phép các loại bộ sưu tập khác nhau hoạt động theo cách tương tự và với mức độ tương tác cao.

  • Khuôn khổ phải mở rộng và / hoặc điều chỉnh một bộ sưu tập một cách dễ dàng.

Hướng tới mục tiêu này, toàn bộ khuôn khổ bộ sưu tập được thiết kế xung quanh một tập hợp các giao diện tiêu chuẩn. Một số triển khai tiêu chuẩn nhưLinkedList, HashSet,TreeSet, trong số các giao diện này được cung cấp để bạn có thể sử dụng nguyên trạng và bạn cũng có thể triển khai bộ sưu tập của riêng mình, nếu bạn chọn.

Khung bộ sưu tập là một kiến ​​trúc thống nhất để đại diện và thao tác các bộ sưu tập. Tất cả các khung bộ sưu tập chứa những điều sau:

  • Interfaces- Đây là các kiểu dữ liệu trừu tượng đại diện cho các tập hợp. Các giao diện cho phép các tập hợp được thao tác độc lập với các chi tiết của biểu diễn của chúng. Trong ngôn ngữ hướng đối tượng, các giao diện thường tạo thành một hệ thống phân cấp.

  • Implementations, i.e., Classes- Đây là những triển khai cụ thể của các giao diện bộ sưu tập. Về bản chất, chúng là cấu trúc dữ liệu có thể tái sử dụng.

  • Algorithms- Đây là những phương thức thực hiện các tính toán hữu ích, chẳng hạn như tìm kiếm và sắp xếp, trên các đối tượng thực hiện giao diện thu thập. Các thuật toán được cho là đa hình: có nghĩa là, cùng một phương pháp có thể được sử dụng trên nhiều cách triển khai khác nhau của giao diện thu thập thích hợp.

Ngoài các bộ sưu tập, khung công tác xác định một số giao diện và lớp bản đồ. Bản đồ lưu trữ các cặp khóa / giá trị. Mặc dù bản đồ không phải là bộ sưu tập trong cách sử dụng thuật ngữ thích hợp, nhưng chúng được tích hợp đầy đủ với các bộ sưu tập.

Giao diện Bộ sưu tập

Khung tập hợp xác định một số giao diện. Phần này cung cấp tổng quan về từng giao diện -

Sr.No. Giao diện & Mô tả
1 Giao diện Bộ sưu tập

Điều này cho phép bạn làm việc với các nhóm đối tượng; nó nằm trên cùng của hệ thống phân cấp bộ sưu tập.

2 Giao diện danh sách

Điều này kéo dài Collection và một thể hiện của Danh sách lưu trữ một tập hợp các phần tử có thứ tự.

3 Bộ

Điều này mở rộng Bộ sưu tập để xử lý các tập hợp phải chứa các phần tử duy nhất.

4 SortedSet

Điều này mở rộng Set để xử lý các tập hợp đã sắp xếp.

5 Bản đô

Điều này ánh xạ các khóa duy nhất cho các giá trị.

6 Bản đồ.Entry

Điều này mô tả một phần tử (một cặp khóa / giá trị) trong bản đồ. Đây là một lớp bên trong của Bản đồ.

7 Bản đồ sắp xếp

Điều này mở rộng Bản đồ để các khóa được duy trì theo thứ tự tăng dần.

số 8 Bảng kê

Đây là giao diện kế thừa xác định các phương thức mà bạn có thể liệt kê (lấy từng phần tử một) các phần tử trong một tập hợp các đối tượng. Giao diện kế thừa này đã được thay thế bởi Iterator.

Các lớp bộ sưu tập

Java cung cấp một tập hợp các lớp bộ sưu tập tiêu chuẩn thực hiện các giao diện Bộ sưu tập. Một số lớp cung cấp các triển khai đầy đủ có thể được sử dụng nguyên trạng và những lớp khác là lớp trừu tượng, cung cấp các triển khai bộ xương được sử dụng làm điểm khởi đầu để tạo các tập hợp cụ thể.

Các lớp tập hợp tiêu chuẩn được tóm tắt trong bảng sau:

Sr.No. Lớp & Mô tả
1

AbstractCollection

Triển khai hầu hết giao diện Bộ sưu tập.

2

AbstractList

Mở rộng AbstractCollection và triển khai hầu hết giao diện Danh sách.

3

AbstractSequentialList

Mở rộng danh sách AbstractList để sử dụng bởi một tập hợp sử dụng truy cập tuần tự chứ không phải ngẫu nhiên vào các phần tử của nó.

4 LinkedList

Triển khai một danh sách được liên kết bằng cách mở rộng AbstractSequentialList.

5 Lập danh sách

Triển khai một mảng động bằng cách mở rộng AbstractList.

6

AbstractSet

Mở rộng AbstractCollection và triển khai hầu hết giao diện Set.

7 HashSet

Mở rộng AbstractSet để sử dụng với bảng băm.

số 8 LinkedHashSet

Mở rộng HashSet để cho phép lặp lại thứ tự chèn.

9 TreeSet

Triển khai một tập hợp được lưu trữ trong một cây. Mở rộng AbstractSet.

10

AbstractMap

Triển khai hầu hết giao diện Bản đồ.

11 Bản đồ băm

Mở rộng AbstractMap để sử dụng bảng băm.

12 TreeMap

Mở rộng AbstractMap để sử dụng một cây.

13 WeakHashMap

Mở rộng AbstractMap để sử dụng một bảng băm với các khóa yếu.

14 LinkedHashMap

Mở rộng HashMap để cho phép lặp lại thứ tự chèn.

15 IdentityHashMap

Mở rộng Bản đồ trừu tượng và sử dụng bình đẳng tham chiếu khi so sánh các tài liệu.

Các lớp AbstractCollection, AbstractSet, AbstractList, AbstractSequentialListAbstractMap cung cấp các triển khai cơ bản của các giao diện bộ sưu tập cốt lõi, để giảm thiểu nỗ lực cần thiết để triển khai chúng.

Các lớp kế thừa sau đây được định nghĩa bởi java.util đã được thảo luận trong chương trước:

Sr.No. Lớp & Mô tả
1 Véc tơ

Điều này thực hiện một mảng động. Nó tương tự như ArrayList, nhưng có một số khác biệt.

2 Cây rơm

Stack là một lớp con của Vector thực hiện một ngăn xếp tiêu chuẩn nhập trước, xuất trước.

3 Từ điển

Từ điển là một lớp trừu tượng đại diện cho một kho lưu trữ khóa / giá trị và hoạt động giống như Bản đồ.

4 Hashtable

Hashtable là một phần của java.util ban đầu và là một triển khai cụ thể của Từ điển.

5 Tính chất

Thuộc tính là một lớp con của Hashtable. Nó được sử dụng để duy trì danh sách các giá trị trong đó khóa là một Chuỗi và giá trị cũng là một Chuỗi.

6 BitSet

Một lớp BitSet tạo ra một kiểu mảng đặc biệt chứa các giá trị bit. Mảng này có thể tăng kích thước khi cần thiết.

Thuật toán thu thập

Khung tập hợp xác định một số thuật toán có thể được áp dụng cho tập hợp và bản đồ. Các thuật toán này được định nghĩa là các phương thức tĩnh trong lớp Collections.

Một số phương pháp có thể ném ClassCastException, xảy ra khi cố gắng so sánh các loại không tương thích hoặc UnsupportedOperationException, xảy ra khi cố gắng sửa đổi một tập hợp không thể sửa đổi.

Bộ sưu tập xác định ba biến tĩnh: EMPTY_SET, EMPTY_LIST và EMPTY_MAP. Tất cả đều bất biến.

Sr.No. Thuật toán & Mô tả
1 Thuật toán thu thập

Đây là danh sách tất cả các thực thi thuật toán.

Làm thế nào để sử dụng một lặp lại?

Thông thường, bạn sẽ muốn duyệt qua các phần tử trong một bộ sưu tập. Ví dụ: bạn có thể muốn hiển thị từng phần tử.

Cách dễ nhất để làm điều này là sử dụng một trình vòng lặp, là một đối tượng thực thi giao diện Trình lặp lại hoặc ListIterator.

Iterator cho phép bạn xoay vòng qua một tập hợp, lấy hoặc xóa các phần tử. ListIterator mở rộng Iterator để cho phép duyệt hai chiều danh sách và sửa đổi các phần tử.

Sr.No. Mô tả và Phương pháp lặp lại
1 Sử dụng Java Iterator

Đây là danh sách tất cả các phương pháp với các ví dụ được cung cấp bởi giao diện Iterator và ListIterator.

Làm thế nào để sử dụng một so sánh?

Cả TreeSet và TreeMap đều lưu trữ các phần tử theo thứ tự được sắp xếp. Tuy nhiên, nó là bộ so sánh xác định chính xác thứ tự đã sắp xếp có nghĩa là gì.

Giao diện này cho phép chúng tôi sắp xếp một bộ sưu tập nhất định theo nhiều cách khác nhau. Ngoài ra, giao diện này có thể được sử dụng để sắp xếp bất kỳ trường hợp nào của bất kỳ lớp nào (ngay cả các lớp chúng ta không thể sửa đổi).

Sr.No. Mô tả và Phương pháp lặp lại
1 Sử dụng trình so sánh Java

Đây là danh sách tất cả các phương pháp với các ví dụ được cung cấp bởi Giao diện so sánh.

Tóm lược

Khung công tác bộ sưu tập Java cho phép lập trình viên truy cập vào các cấu trúc dữ liệu đóng gói sẵn cũng như các thuật toán để thao tác chúng.

Bộ sưu tập là một đối tượng có thể chứa các tham chiếu đến các đối tượng khác. Các giao diện bộ sưu tập khai báo các hoạt động có thể được thực hiện trên mỗi loại bộ sưu tập.

Các lớp và giao diện của khung công tác tập hợp nằm trong gói java.util.

Sẽ thật tuyệt nếu chúng ta có thể viết một phương thức sắp xếp duy nhất có thể sắp xếp các phần tử trong mảng Số nguyên, mảng Chuỗi hoặc một mảng thuộc bất kỳ kiểu nào hỗ trợ sắp xếp.

Java Generic các phương thức và các lớp chung cho phép người lập trình xác định, với một khai báo phương thức duy nhất, một tập các phương thức liên quan hoặc với một khai báo lớp đơn, một tập các kiểu liên quan, tương ứng.

Generics cũng cung cấp sự an toàn cho kiểu thời gian biên dịch cho phép người lập trình bắt các kiểu không hợp lệ tại thời điểm biên dịch.

Sử dụng khái niệm Java Generic, chúng ta có thể viết một phương thức chung để sắp xếp một mảng đối tượng, sau đó gọi phương thức chung với mảng Số nguyên, Mảng đôi, Mảng chuỗi, v.v. để sắp xếp các phần tử của mảng.

Phương pháp chung

Bạn có thể viết một khai báo phương thức chung duy nhất có thể được gọi với các đối số thuộc các kiểu khác nhau. Dựa trên các loại đối số được truyền cho phương thức chung, trình biên dịch xử lý từng lệnh gọi phương thức một cách thích hợp. Sau đây là các quy tắc để xác định các Phương thức Chung -

  • Tất cả các khai báo phương thức chung đều có phần tham số kiểu được phân cách bằng dấu ngoặc nhọn (<và>) đứng trước kiểu trả về của phương thức (<E> trong ví dụ tiếp theo).

  • Mỗi phần tham số kiểu chứa một hoặc nhiều tham số kiểu được phân tách bằng dấu phẩy. Tham số kiểu, còn được gọi là biến kiểu, là một số nhận dạng chỉ định tên kiểu chung.

  • Các tham số kiểu có thể được sử dụng để khai báo kiểu trả về và hoạt động như trình giữ chỗ cho các kiểu đối số được truyền cho phương thức chung, được gọi là đối số kiểu thực.

  • Phần thân của một phương thức chung được khai báo giống như của bất kỳ phương thức nào khác. Lưu ý rằng các tham số kiểu chỉ có thể đại diện cho các kiểu tham chiếu, không phải kiểu nguyên thủy (như int, double và char).

Thí dụ

Ví dụ sau minh họa cách chúng ta có thể in một mảng có kiểu khác nhau bằng một phương thức Chung duy nhất:

public class GenericMethodTest {
   // generic method printArray
   public static < E > void printArray( E[] inputArray ) {
      // Display array elements
      for(E element : inputArray) {
         System.out.printf("%s ", element);
      }
      System.out.println();
   }

   public static void main(String args[]) {
      // Create arrays of Integer, Double and Character
      Integer[] intArray = { 1, 2, 3, 4, 5 };
      Double[] doubleArray = { 1.1, 2.2, 3.3, 4.4 };
      Character[] charArray = { 'H', 'E', 'L', 'L', 'O' };

      System.out.println("Array integerArray contains:");
      printArray(intArray);   // pass an Integer array

      System.out.println("\nArray doubleArray contains:");
      printArray(doubleArray);   // pass a Double array

      System.out.println("\nArray characterArray contains:");
      printArray(charArray);   // pass a Character array
   }
}

Điều này sẽ tạo ra kết quả sau:

Đầu ra

Array integerArray contains:
1 2 3 4 5 

Array doubleArray contains:
1.1 2.2 3.3 4.4 

Array characterArray contains:
H E L L O

Các thông số kiểu giới hạn

Có thể có những lúc bạn muốn hạn chế các loại kiểu được phép chuyển cho tham số kiểu. Ví dụ, một phương thức hoạt động trên các số có thể chỉ muốn chấp nhận các thể hiện của Số hoặc các lớp con của nó. Đây là những gì các tham số kiểu bị giới hạn dành cho.

Để khai báo một tham số kiểu có giới hạn, hãy liệt kê tên của tham số kiểu, theo sau là từ khóa expand, tiếp theo là giới hạn trên của nó.

Thí dụ

Ví dụ sau minh họa cách dùng để mở rộng theo nghĩa chung là "mở rộng" (như trong các lớp) hoặc "thực hiện" (như trong các giao diện). Ví dụ này là phương thức Chung để trả về giá trị lớn nhất trong ba đối tượng có thể so sánh được -

public class MaximumTest {
   // determines the largest of three Comparable objects
   
   public static <T extends Comparable<T>> T maximum(T x, T y, T z) {
      T max = x;   // assume x is initially the largest
      
      if(y.compareTo(max) > 0) {
         max = y;   // y is the largest so far
      }
      
      if(z.compareTo(max) > 0) {
         max = z;   // z is the largest now                 
      }
      return max;   // returns the largest object   
   }
   
   public static void main(String args[]) {
      System.out.printf("Max of %d, %d and %d is %d\n\n", 
         3, 4, 5, maximum( 3, 4, 5 ));

      System.out.printf("Max of %.1f,%.1f and %.1f is %.1f\n\n",
         6.6, 8.8, 7.7, maximum( 6.6, 8.8, 7.7 ));

      System.out.printf("Max of %s, %s and %s is %s\n","pear",
         "apple", "orange", maximum("pear", "apple", "orange"));
   }
}

Điều này sẽ tạo ra kết quả sau:

Đầu ra

Max of 3, 4 and 5 is 5

Max of 6.6,8.8 and 7.7 is 8.8

Max of pear, apple and orange is pear

Các lớp chung

Một khai báo lớp chung trông giống như một khai báo lớp không chung chung, ngoại trừ việc tên lớp được theo sau bởi một phần tham số kiểu.

Như với các phương thức chung, phần tham số kiểu của một lớp chung có thể có một hoặc nhiều tham số kiểu được phân tách bằng dấu phẩy. Các lớp này được gọi là lớp được tham số hóa hoặc kiểu được tham số hóa vì chúng chấp nhận một hoặc nhiều tham số.

Thí dụ

Ví dụ sau minh họa cách chúng ta có thể định nghĩa một lớp chung:

public class Box<T> {
   private T t;

   public void add(T t) {
      this.t = t;
   }

   public T get() {
      return t;
   }

   public static void main(String[] args) {
      Box<Integer> integerBox = new Box<Integer>();
      Box<String> stringBox = new Box<String>();
    
      integerBox.add(new Integer(10));
      stringBox.add(new String("Hello World"));

      System.out.printf("Integer Value :%d\n\n", integerBox.get());
      System.out.printf("String Value :%s\n", stringBox.get());
   }
}

Điều này sẽ tạo ra kết quả sau:

Đầu ra

Integer Value :10
String Value :Hello World

Java cung cấp một cơ chế, được gọi là tuần tự hóa đối tượng trong đó một đối tượng có thể được biểu diễn dưới dạng một chuỗi byte bao gồm dữ liệu của đối tượng cũng như thông tin về kiểu của đối tượng và các kiểu dữ liệu được lưu trữ trong đối tượng.

Sau khi một đối tượng tuần tự hóa đã được ghi vào một tệp, nó có thể được đọc từ tệp và được giải mã hóa, thông tin kiểu và byte đại diện cho đối tượng và dữ liệu của nó có thể được sử dụng để tạo lại đối tượng trong bộ nhớ.

Ấn tượng nhất là toàn bộ quy trình là JVM độc lập, có nghĩa là một đối tượng có thể được tuần tự hóa trên một nền tảng và được giải mã trên một nền tảng hoàn toàn khác.

Các lớp học ObjectInputStreamObjectOutputStream là các luồng cấp cao chứa các phương thức tuần tự hóa và giải mã hóa một đối tượng.

Lớp ObjectOutputStream chứa nhiều phương thức ghi để ghi các kiểu dữ liệu khác nhau, nhưng một phương thức đặc biệt nổi bật:

public final void writeObject(Object x) throws IOException

Phương thức trên tuần tự hóa một Đối tượng và gửi nó đến luồng đầu ra. Tương tự, lớp ObjectInputStream chứa phương thức sau để giải mã hóa một đối tượng:

public final Object readObject() throws IOException, ClassNotFoundException

Phương thức này truy xuất Đối tượng tiếp theo ra khỏi luồng và giải mã hóa nó. Giá trị trả về là Đối tượng, vì vậy bạn sẽ cần truyền nó sang kiểu dữ liệu thích hợp.

Để chứng minh cách tuần tự hóa hoạt động trong Java, tôi sẽ sử dụng lớp Employee mà chúng ta đã thảo luận ở phần đầu của cuốn sách. Giả sử rằng chúng ta có lớp Nhân viên sau, lớp này triển khai giao diện Có thể nối tiếp -

Thí dụ

public class Employee implements java.io.Serializable {
   public String name;
   public String address;
   public transient int SSN;
   public int number;
   
   public void mailCheck() {
      System.out.println("Mailing a check to " + name + " " + address);
   }
}

Lưu ý rằng để một lớp được tuần tự hóa thành công, hai điều kiện phải được đáp ứng:

  • Lớp phải triển khai giao diện java.io.Serializable.

  • Tất cả các trường trong lớp phải có thể tuần tự hóa. Nếu một trường không thể tuần tự hóa, nó phải được đánh dấutransient.

Nếu bạn muốn biết liệu Lớp chuẩn Java có thể tuần tự hóa hay không, hãy kiểm tra tài liệu về lớp đó. Kiểm tra rất đơn giản: Nếu lớp thực thi java.io.Serializable, thì nó có thể tuần tự hóa; nếu không, nó không phải.

Sắp xếp thứ tự một đối tượng

Lớp ObjectOutputStream được sử dụng để tuần tự hóa một Đối tượng. Chương trình SerializeDemo sau đây khởi tạo một đối tượng Employee và tuần tự hóa nó thành một tệp.

Khi chương trình được thực thi xong, một tệp có tên là worker.ser được tạo. Chương trình không tạo ra bất kỳ đầu ra nào, nhưng hãy nghiên cứu mã và cố gắng xác định chương trình đang làm gì.

Note - Khi tuần tự hóa một đối tượng vào một tệp, quy ước tiêu chuẩn trong Java là cung cấp cho tệp .ser sự mở rộng.

Thí dụ

import java.io.*;
public class SerializeDemo {

   public static void main(String [] args) {
      Employee e = new Employee();
      e.name = "Reyan Ali";
      e.address = "Phokka Kuan, Ambehta Peer";
      e.SSN = 11122333;
      e.number = 101;
      
      try {
         FileOutputStream fileOut =
         new FileOutputStream("/tmp/employee.ser");
         ObjectOutputStream out = new ObjectOutputStream(fileOut);
         out.writeObject(e);
         out.close();
         fileOut.close();
         System.out.printf("Serialized data is saved in /tmp/employee.ser");
      } catch (IOException i) {
         i.printStackTrace();
      }
   }
}

Giải mã hóa một đối tượng

Chương trình DeserializeDemo sau đây giải mã hóa đối tượng Employee được tạo trong chương trình SerializeDemo. Nghiên cứu chương trình và cố gắng xác định đầu ra của nó -

Thí dụ

import java.io.*;
public class DeserializeDemo {

   public static void main(String [] args) {
      Employee e = null;
      try {
         FileInputStream fileIn = new FileInputStream("/tmp/employee.ser");
         ObjectInputStream in = new ObjectInputStream(fileIn);
         e = (Employee) in.readObject();
         in.close();
         fileIn.close();
      } catch (IOException i) {
         i.printStackTrace();
         return;
      } catch (ClassNotFoundException c) {
         System.out.println("Employee class not found");
         c.printStackTrace();
         return;
      }
      
      System.out.println("Deserialized Employee...");
      System.out.println("Name: " + e.name);
      System.out.println("Address: " + e.address);
      System.out.println("SSN: " + e.SSN);
      System.out.println("Number: " + e.number);
   }
}

Điều này sẽ tạo ra kết quả sau:

Đầu ra

Deserialized Employee...
Name: Reyan Ali
Address:Phokka Kuan, Ambehta Peer
SSN: 0
Number:101

Dưới đây là những điểm quan trọng cần lưu ý:

  • Khối try / catch cố gắng bắt một ClassNotFoundException, được khai báo bởi phương thức readObject (). Để một JVM có thể giải mã hóa một đối tượng, nó phải có khả năng tìm thấy mã bytecode cho lớp. Nếu JVM không thể tìm thấy một lớp trong quá trình giải mã hóa một đối tượng, nó sẽ ném ra một ClassNotFoundException.

  • Lưu ý rằng giá trị trả về của readObject () được chuyển thành tham chiếu Nhân viên.

  • Giá trị của trường SSN là 11122333 khi đối tượng được tuần tự hóa, nhưng vì trường là tạm thời, giá trị này không được gửi tới luồng đầu ra. Trường SSN của đối tượng Nhân viên được deserialized là 0.

Thuật ngữ lập trình mạng dùng để chỉ việc viết các chương trình thực thi trên nhiều thiết bị (máy tính), trong đó các thiết bị được kết nối với nhau bằng một mạng.

Gói java.net của các API J2SE chứa một tập hợp các lớp và giao diện cung cấp các chi tiết giao tiếp cấp thấp, cho phép bạn viết các chương trình tập trung vào giải quyết vấn đề trong tầm tay.

Gói java.net cung cấp hỗ trợ cho hai giao thức mạng phổ biến -

  • TCP- TCP là viết tắt của Transmission Control Protocol, cho phép giao tiếp đáng tin cậy giữa hai ứng dụng. TCP thường được sử dụng qua Giao thức Internet, được gọi là TCP / IP.

  • UDP - UDP là viết tắt của User Datagram Protocol, một giao thức không cần kết nối cho phép các gói dữ liệu được truyền giữa các ứng dụng.

Chương này giúp bạn hiểu rõ về hai chủ đề sau:

  • Socket Programming - Đây là khái niệm được sử dụng rộng rãi nhất trong Mạng và nó đã được giải thích rất chi tiết.

  • URL Processing- Điều này sẽ được đề cập riêng. Nhấp vào đây để tìm hiểu về Xử lý URL bằng ngôn ngữ Java.

Lập trình Socket

Sockets cung cấp cơ chế giao tiếp giữa hai máy tính sử dụng TCP. Một chương trình khách tạo một ổ cắm trên đầu giao tiếp của nó và cố gắng kết nối ổ cắm đó với một máy chủ.

Khi kết nối được thực hiện, máy chủ sẽ tạo một đối tượng socket trên phần cuối của giao tiếp. Máy khách và máy chủ hiện có thể giao tiếp bằng cách ghi và đọc từ ổ cắm.

Lớp java.net.Socket đại diện cho một socket và lớp java.net.ServerSocket cung cấp một cơ chế để chương trình máy chủ lắng nghe các máy khách và thiết lập kết nối với chúng.

Các bước sau xảy ra khi thiết lập kết nối TCP giữa hai máy tính sử dụng ổ cắm:

  • Máy chủ khởi tạo đối tượng ServerSocket, biểu thị giao tiếp số cổng nào sẽ xảy ra.

  • Máy chủ gọi phương thức accept () của lớp ServerSocket. Phương pháp này đợi cho đến khi một máy khách kết nối với máy chủ trên cổng nhất định.

  • Sau khi máy chủ chờ, một máy khách khởi tạo một đối tượng Socket, chỉ định tên máy chủ và số cổng để kết nối.

  • Hàm tạo của lớp Socket cố gắng kết nối máy khách với máy chủ được chỉ định và số cổng. Nếu giao tiếp được thiết lập, máy khách bây giờ có một đối tượng Socket có khả năng giao tiếp với máy chủ.

  • Ở phía máy chủ, phương thức accept () trả về một tham chiếu đến ổ cắm mới trên máy chủ được kết nối với ổ cắm của máy khách.

Sau khi các kết nối được thiết lập, giao tiếp có thể xảy ra bằng các luồng I / O. Mỗi socket có cả OutputStream và InputStream. OutputStream của máy khách được kết nối với InputStream của máy chủ và InputStream của máy khách được kết nối với OutputStream của máy chủ.

TCP là một giao thức truyền thông hai chiều, do đó dữ liệu có thể được gửi qua cả hai luồng cùng một lúc. Sau đây là các lớp hữu ích cung cấp tập hợp đầy đủ các phương thức để triển khai các socket.

Phương thức lớp ServerSocket

Các java.net.ServerSocket lớp được sử dụng bởi các ứng dụng máy chủ để lấy một cổng và lắng nghe các yêu cầu của máy khách.

Lớp ServerSocket có bốn hàm tạo:

Sr.No. Phương pháp & Mô tả
1

public ServerSocket(int port) throws IOException

Cố gắng tạo một ổ cắm máy chủ được liên kết với cổng được chỉ định. Một ngoại lệ xảy ra nếu cổng đã bị ràng buộc bởi một ứng dụng khác.

2

public ServerSocket(int port, int backlog) throws IOException

Tương tự như hàm tạo trước đó, tham số backlog chỉ định số lượng máy khách đến để lưu trữ trong hàng đợi.

3

public ServerSocket(int port, int backlog, InetAddress address) throws IOException

Tương tự như hàm tạo trước, tham số InetAddress chỉ định địa chỉ IP cục bộ để liên kết. InetAddress được sử dụng cho các máy chủ có thể có nhiều địa chỉ IP, cho phép máy chủ chỉ định địa chỉ IP nào của nó để chấp nhận các yêu cầu của máy khách.

4

public ServerSocket() throws IOException

Tạo một ổ cắm máy chủ không liên kết. Khi sử dụng hàm tạo này, hãy sử dụng phương thức bind () khi bạn đã sẵn sàng liên kết socket máy chủ.

Nếu phương thức khởi tạo ServerSocket không ném ra ngoại lệ, điều đó có nghĩa là ứng dụng của bạn đã liên kết thành công với cổng được chỉ định và sẵn sàng cho các yêu cầu của khách hàng.

Sau đây là một số phương thức phổ biến của lớp ServerSocket:

Sr.No. Phương pháp & Mô tả
1

public int getLocalPort()

Trả về cổng mà ổ cắm máy chủ đang nghe. Phương pháp này hữu ích nếu bạn đã chuyển 0 làm số cổng trong một hàm tạo và để máy chủ tìm cổng cho bạn.

2

public Socket accept() throws IOException

Chờ một khách hàng đến. Phương thức này chặn cho đến khi máy khách kết nối với máy chủ trên cổng được chỉ định hoặc ổ cắm hết thời gian chờ, giả sử rằng giá trị thời gian chờ đã được đặt bằng phương thức setSoTimeout (). Nếu không, phương thức này sẽ chặn vô thời hạn.

3

public void setSoTimeout(int timeout)

Đặt giá trị thời gian chờ cho khoảng thời gian ổ cắm máy chủ chờ máy khách trong quá trình chấp nhận ().

4

public void bind(SocketAddress host, int backlog)

Liên kết socket với máy chủ và cổng được chỉ định trong đối tượng SocketAddress. Sử dụng phương pháp này nếu bạn đã khởi tạo ServerSocket bằng cách sử dụng hàm tạo không đối số.

Khi ServerSocket gọi accept (), phương thức này sẽ không trả về cho đến khi máy khách kết nối. Sau khi một máy khách kết nối, ServerSocket tạo một Socket mới trên một cổng không xác định và trả về một tham chiếu đến Socket mới này. Một kết nối TCP hiện đã tồn tại giữa máy khách và máy chủ và quá trình giao tiếp có thể bắt đầu.

Phương thức lớp Socket

Các java.net.Socketlớp đại diện cho socket mà cả máy khách và máy chủ sử dụng để giao tiếp với nhau. Máy khách nhận được một đối tượng Socket bằng cách khởi tạo một đối tượng, trong khi máy chủ nhận được một đối tượng Socket từ giá trị trả về của phương thức accept ().

Lớp Socket có năm hàm tạo mà máy khách sử dụng để kết nối với máy chủ -

Sr.No. Phương pháp & Mô tả
1

public Socket(String host, int port) throws UnknownHostException, IOException.

Phương pháp này cố gắng kết nối với máy chủ được chỉ định tại cổng được chỉ định. Nếu hàm tạo này không ném ra một ngoại lệ, kết nối thành công và máy khách được kết nối với máy chủ.

2

public Socket(InetAddress host, int port) throws IOException

Phương thức này giống với phương thức khởi tạo trước đó, ngoại trừ máy chủ được ký hiệu bằng một đối tượng InetAddress.

3

public Socket(String host, int port, InetAddress localAddress, int localPort) throws IOException.

Kết nối với máy chủ và cổng được chỉ định, tạo một ổ cắm trên máy chủ cục bộ tại địa chỉ và cổng được chỉ định.

4

public Socket(InetAddress host, int port, InetAddress localAddress, int localPort) throws IOException.

Phương thức này giống với phương thức khởi tạo trước đó, ngoại trừ máy chủ được ký hiệu bằng một đối tượng InetAddress thay vì một chuỗi.

5

public Socket()

Tạo một ổ cắm không kết nối. Sử dụng phương thức connect () để kết nối ổ cắm này với máy chủ.

Khi phương thức khởi tạo Socket trả về, nó không chỉ khởi tạo một đối tượng Socket mà còn thực sự cố gắng kết nối với máy chủ và cổng được chỉ định.

Một số phương thức quan tâm trong lớp Socket được liệt kê ở đây. Lưu ý rằng cả máy khách và máy chủ đều có đối tượng Socket, vì vậy các phương thức này có thể được gọi bởi cả máy khách và máy chủ.

Sr.No. Phương pháp & Mô tả
1

public void connect(SocketAddress host, int timeout) throws IOException

Phương pháp này kết nối ổ cắm với máy chủ được chỉ định. Phương thức này chỉ cần thiết khi bạn khởi tạo Socket bằng cách sử dụng hàm tạo không đối số.

2

public InetAddress getInetAddress()

Phương thức này trả về địa chỉ của máy tính khác mà ổ cắm này được kết nối.

3

public int getPort()

Trả lại cổng mà ổ cắm được liên kết trên máy điều khiển từ xa.

4

public int getLocalPort()

Trả về cổng mà ổ cắm được liên kết trên máy cục bộ.

5

public SocketAddress getRemoteSocketAddress()

Trả về địa chỉ của ổ cắm từ xa.

6

public InputStream getInputStream() throws IOException

Trả về luồng đầu vào của ổ cắm. Luồng đầu vào được kết nối với luồng đầu ra của ổ cắm từ xa.

7

public OutputStream getOutputStream() throws IOException

Trả về luồng đầu ra của ổ cắm. Luồng đầu ra được kết nối với luồng đầu vào của ổ cắm từ xa.

số 8

public void close() throws IOException

Đóng socket, điều này làm cho đối tượng Socket này không còn khả năng kết nối lại với bất kỳ máy chủ nào.

Phương thức lớp InetAddress

Lớp này đại diện cho một địa chỉ Giao thức Internet (IP). Dưới đây là các phương pháp hữu ích mà bạn sẽ cần khi thực hiện lập trình socket -

Sr.No. Phương pháp & Mô tả
1

static InetAddress getByAddress(byte[] addr)

Trả về một đối tượng InetAddress được cung cấp địa chỉ IP thô.

2

static InetAddress getByAddress(String host, byte[] addr)

Tạo InetAddress dựa trên tên máy chủ và địa chỉ IP được cung cấp.

3

static InetAddress getByName(String host)

Xác định địa chỉ IP của máy chủ lưu trữ, với tên của máy chủ.

4

String getHostAddress()

Trả về chuỗi địa chỉ IP trong bản trình bày dạng văn bản.

5

String getHostName()

Lấy tên máy chủ cho địa chỉ IP này.

6

static InetAddress InetAddress getLocalHost()

Trả về máy chủ cục bộ.

7

String toString()

Chuyển đổi địa chỉ IP này thành một chuỗi.

Ví dụ về Socket Client

GreetingClient sau đây là chương trình khách kết nối với máy chủ bằng cách sử dụng ổ cắm và gửi lời chào, sau đó chờ phản hồi.

Thí dụ

// File Name GreetingClient.java
import java.net.*;
import java.io.*;

public class GreetingClient {

   public static void main(String [] args) {
      String serverName = args[0];
      int port = Integer.parseInt(args[1]);
      try {
         System.out.println("Connecting to " + serverName + " on port " + port);
         Socket client = new Socket(serverName, port);
         
         System.out.println("Just connected to " + client.getRemoteSocketAddress());
         OutputStream outToServer = client.getOutputStream();
         DataOutputStream out = new DataOutputStream(outToServer);
         
         out.writeUTF("Hello from " + client.getLocalSocketAddress());
         InputStream inFromServer = client.getInputStream();
         DataInputStream in = new DataInputStream(inFromServer);
         
         System.out.println("Server says " + in.readUTF());
         client.close();
      } catch (IOException e) {
         e.printStackTrace();
      }
   }
}

Ví dụ về Socket Server

Chương trình GreetingServer sau đây là một ví dụ về ứng dụng máy chủ sử dụng lớp Socket để lắng nghe máy khách trên số cổng được chỉ định bởi đối số dòng lệnh:

Thí dụ

// File Name GreetingServer.java
import java.net.*;
import java.io.*;

public class GreetingServer extends Thread {
   private ServerSocket serverSocket;
   
   public GreetingServer(int port) throws IOException {
      serverSocket = new ServerSocket(port);
      serverSocket.setSoTimeout(10000);
   }

   public void run() {
      while(true) {
         try {
            System.out.println("Waiting for client on port " + 
               serverSocket.getLocalPort() + "...");
            Socket server = serverSocket.accept();
            
            System.out.println("Just connected to " + server.getRemoteSocketAddress());
            DataInputStream in = new DataInputStream(server.getInputStream());
            
            System.out.println(in.readUTF());
            DataOutputStream out = new DataOutputStream(server.getOutputStream());
            out.writeUTF("Thank you for connecting to " + server.getLocalSocketAddress()
               + "\nGoodbye!");
            server.close();
            
         } catch (SocketTimeoutException s) {
            System.out.println("Socket timed out!");
            break;
         } catch (IOException e) {
            e.printStackTrace();
            break;
         }
      }
   }
   
   public static void main(String [] args) {
      int port = Integer.parseInt(args[0]);
      try {
         Thread t = new GreetingServer(port);
         t.start();
      } catch (IOException e) {
         e.printStackTrace();
      }
   }
}

Biên dịch máy khách và máy chủ rồi khởi động máy chủ như sau:

$ java GreetingServer 6066
Waiting for client on port 6066...

Kiểm tra chương trình khách hàng như sau:

Đầu ra

$ java GreetingClient localhost 6066
Connecting to localhost on port 6066
Just connected to localhost/127.0.0.1:6066
Server says Thank you for connecting to /127.0.0.1:6066
Goodbye!

Để gửi e-mail bằng Ứng dụng Java của bạn rất đơn giản nhưng để bắt đầu, bạn nên có JavaMail APIJava Activation Framework (JAF) được cài đặt trên máy của bạn.

  • Bạn có thể tải xuống phiên bản JavaMail mới nhất (Phiên bản 1.2) từ trang web chuẩn của Java.

  • Bạn có thể tải xuống phiên bản mới nhất của JAF (Phiên bản 1.1.1) từ trang web chuẩn của Java.

Tải xuống và giải nén các tệp này, trong thư mục cấp cao nhất mới được tạo, bạn sẽ tìm thấy một số tệp jar cho cả hai ứng dụng. Bạn cần phải thêmmail.jaractivation.jar các tệp trong CLASSPATH của bạn.

Gửi một e-mail đơn giản

Đây là một ví dụ để gửi một e-mail đơn giản từ máy của bạn. Người ta cho rằnglocalhost được kết nối với Internet và đủ khả năng để gửi e-mail.

Thí dụ

// File Name SendEmail.java

import java.util.*;
import javax.mail.*;
import javax.mail.internet.*;
import javax.activation.*;

public class SendEmail {

   public static void main(String [] args) {    
      // Recipient's email ID needs to be mentioned.
      String to = "[email protected]";

      // Sender's email ID needs to be mentioned
      String from = "[email protected]";

      // Assuming you are sending email from localhost
      String host = "localhost";

      // Get system properties
      Properties properties = System.getProperties();

      // Setup mail server
      properties.setProperty("mail.smtp.host", host);

      // Get the default Session object.
      Session session = Session.getDefaultInstance(properties);

      try {
         // Create a default MimeMessage object.
         MimeMessage message = new MimeMessage(session);

         // Set From: header field of the header.
         message.setFrom(new InternetAddress(from));

         // Set To: header field of the header.
         message.addRecipient(Message.RecipientType.TO, new InternetAddress(to));

         // Set Subject: header field
         message.setSubject("This is the Subject Line!");

         // Now set the actual message
         message.setText("This is actual message");

         // Send message
         Transport.send(message);
         System.out.println("Sent message successfully....");
      } catch (MessagingException mex) {
         mex.printStackTrace();
      }
   }
}

Biên dịch và chạy chương trình này để gửi một e-mail đơn giản -

Đầu ra

$ java SendEmail
Sent message successfully....

Nếu bạn muốn gửi e-mail đến nhiều người nhận thì các phương pháp sau sẽ được sử dụng để chỉ định nhiều ID e-mail:

void addRecipients(Message.RecipientType type, Address[] addresses)
   throws MessagingException

Đây là mô tả của các tham số -

  • type- Điều này sẽ được đặt thành TO, CC hoặc BCC. Ở đây CC đại diện cho Bản sao carbon và BCC đại diện cho Bản sao carbon đen. Ví dụ: Message.RecipientType.TO

  • addresses- Đây là một mảng ID e-mail. Bạn sẽ cần sử dụng phương thức InternetAddress () trong khi chỉ định các ID email.

Gửi e-mail HTML

Đây là một ví dụ để gửi một e-mail HTML từ máy của bạn. Ở đây nó được giả định rằnglocalhost được kết nối với Internet và đủ khả năng để gửi e-mail.

Ví dụ này rất giống với ví dụ trước, ngoại trừ ở đây chúng tôi đang sử dụng phương thức setContent () để đặt nội dung có đối số thứ hai là "text / html" để chỉ định rằng nội dung HTML được đưa vào thư.

Sử dụng ví dụ này, bạn có thể gửi nội dung HTML lớn như bạn muốn.

Thí dụ

// File Name SendHTMLEmail.java

import java.util.*;
import javax.mail.*;
import javax.mail.internet.*;
import javax.activation.*;

public class SendHTMLEmail {

   public static void main(String [] args) {
      // Recipient's email ID needs to be mentioned.
      String to = "[email protected]";

      // Sender's email ID needs to be mentioned
      String from = "[email protected]";

      // Assuming you are sending email from localhost
      String host = "localhost";

      // Get system properties
      Properties properties = System.getProperties();

      // Setup mail server
      properties.setProperty("mail.smtp.host", host);

      // Get the default Session object.
      Session session = Session.getDefaultInstance(properties);

      try {
         // Create a default MimeMessage object.
         MimeMessage message = new MimeMessage(session);

         // Set From: header field of the header.
         message.setFrom(new InternetAddress(from));

         // Set To: header field of the header.
         message.addRecipient(Message.RecipientType.TO, new InternetAddress(to));

         // Set Subject: header field
         message.setSubject("This is the Subject Line!");

         // Send the actual HTML message, as big as you like
         message.setContent("<h1>This is actual message</h1>", "text/html");

         // Send message
         Transport.send(message);
         System.out.println("Sent message successfully....");
      } catch (MessagingException mex) {
         mex.printStackTrace();
      }
   }
}

Biên dịch và chạy chương trình này để gửi e-mail HTML -

Đầu ra

$ java SendHTMLEmail
Sent message successfully....

Gửi tệp đính kèm trong e-mail

Đây là một ví dụ để gửi e-mail có tệp đính kèm từ máy của bạn. Ở đây nó được giả định rằnglocalhost được kết nối với internet và đủ khả năng để gửi e-mail.

Thí dụ

// File Name SendFileEmail.java

import java.util.*;
import javax.mail.*;
import javax.mail.internet.*;
import javax.activation.*;

public class SendFileEmail {

   public static void main(String [] args) {     
      // Recipient's email ID needs to be mentioned.
      String to = "[email protected]";

      // Sender's email ID needs to be mentioned
      String from = "[email protected]";

      // Assuming you are sending email from localhost
      String host = "localhost";

      // Get system properties
      Properties properties = System.getProperties();

      // Setup mail server
      properties.setProperty("mail.smtp.host", host);

      // Get the default Session object.
      Session session = Session.getDefaultInstance(properties);

      try {
         // Create a default MimeMessage object.
         MimeMessage message = new MimeMessage(session);

         // Set From: header field of the header.
         message.setFrom(new InternetAddress(from));

         // Set To: header field of the header.
         message.addRecipient(Message.RecipientType.TO,new InternetAddress(to));

         // Set Subject: header field
         message.setSubject("This is the Subject Line!");

         // Create the message part 
         BodyPart messageBodyPart = new MimeBodyPart();

         // Fill the message
         messageBodyPart.setText("This is message body");
         
         // Create a multipar message
         Multipart multipart = new MimeMultipart();

         // Set text message part
         multipart.addBodyPart(messageBodyPart);

         // Part two is attachment
         messageBodyPart = new MimeBodyPart();
         String filename = "file.txt";
         DataSource source = new FileDataSource(filename);
         messageBodyPart.setDataHandler(new DataHandler(source));
         messageBodyPart.setFileName(filename);
         multipart.addBodyPart(messageBodyPart);

         // Send the complete message parts
         message.setContent(multipart );

         // Send message
         Transport.send(message);
         System.out.println("Sent message successfully....");
      } catch (MessagingException mex) {
         mex.printStackTrace();
      }
   }
}

Biên dịch và chạy chương trình này để gửi e-mail HTML -

Đầu ra

$ java SendFileEmail
Sent message successfully....

Phần xác thực người dùng

Nếu bắt buộc phải cung cấp ID người dùng và Mật khẩu cho máy chủ e-mail cho mục đích xác thực, thì bạn có thể đặt các thuộc tính này như sau:

props.setProperty("mail.user", "myuser");
props.setProperty("mail.password", "mypwd");

Phần còn lại của cơ chế gửi e-mail sẽ vẫn như được giải thích ở trên.

Java là một ngôn ngữ lập trình đa luồng có nghĩa là chúng ta có thể phát triển chương trình đa luồng bằng Java. Một chương trình đa luồng chứa hai hoặc nhiều phần có thể chạy đồng thời và mỗi phần có thể xử lý một tác vụ khác nhau cùng lúc để sử dụng tối ưu các tài nguyên có sẵn, đặc biệt khi máy tính của bạn có nhiều CPU.

Theo định nghĩa, đa nhiệm là khi nhiều quy trình chia sẻ tài nguyên xử lý chung như CPU. Đa luồng mở rộng ý tưởng về đa nhiệm vào các ứng dụng nơi bạn có thể chia nhỏ các hoạt động cụ thể trong một ứng dụng thành các luồng riêng lẻ. Mỗi luồng có thể chạy song song. Hệ điều hành phân chia thời gian xử lý không chỉ giữa các ứng dụng khác nhau mà còn giữa từng luồng trong một ứng dụng.

Đa luồng cho phép bạn viết theo cách mà nhiều hoạt động có thể tiến hành đồng thời trong cùng một chương trình.

Vòng đời của một sợi chỉ

Một luồng trải qua nhiều giai đoạn khác nhau trong vòng đời của nó. Ví dụ, một luồng được sinh ra, bắt đầu, chạy và sau đó chết. Sơ đồ sau đây cho thấy toàn bộ vòng đời của một luồng.

Sau đây là các giai đoạn của vòng đời:

  • New- Một luồng mới bắt đầu vòng đời của nó ở trạng thái mới. Nó vẫn ở trạng thái này cho đến khi chương trình bắt đầu luồng. Nó cũng được gọi làborn thread.

  • Runnable- Sau khi một luồng mới sinh được bắt đầu, luồng đó có thể chạy được. Một luồng ở trạng thái này được coi là đang thực thi nhiệm vụ của nó.

  • Waiting- Đôi khi, một luồng chuyển sang trạng thái chờ trong khi luồng đó chờ một luồng khác thực hiện một tác vụ. Một luồng chỉ chuyển trở lại trạng thái chạy được khi một luồng khác báo hiệu luồng đang chờ tiếp tục thực thi.

  • Timed Waiting- Một luồng có thể chạy được có thể vào trạng thái chờ được hẹn giờ trong một khoảng thời gian nhất định. Một luồng ở trạng thái này chuyển trở lại trạng thái có thể chạy khi khoảng thời gian đó hết hạn hoặc khi sự kiện mà nó đang chờ xảy ra.

  • Terminated (Dead) - Một luồng có thể chạy đi vào trạng thái kết thúc khi nó hoàn thành nhiệm vụ của nó hoặc kết thúc bằng cách khác.

Ưu tiên chuỗi

Mỗi luồng Java đều có một mức độ ưu tiên giúp hệ điều hành xác định thứ tự mà các luồng được lập lịch.

Mức độ ưu tiên của luồng Java nằm trong phạm vi giữa MIN_PRIORITY (hằng số 1) và MAX_PRIORITY (hằng số 10). Theo mặc định, mọi luồng được ưu tiên NORM_PRIORITY (hằng số 5).

Các luồng có mức độ ưu tiên cao hơn quan trọng hơn đối với một chương trình và nên được phân bổ thời gian xử lý trước các luồng có mức độ ưu tiên thấp hơn. Tuy nhiên, các ưu tiên của luồng không thể đảm bảo thứ tự mà các luồng thực thi và phụ thuộc rất nhiều vào nền tảng.

Tạo một chuỗi bằng cách triển khai một giao diện có thể chạy được

Nếu lớp của bạn dự định được thực thi dưới dạng một luồng thì bạn có thể đạt được điều này bằng cách triển khai Runnablegiao diện. Bạn sẽ cần làm theo ba bước cơ bản -

Bước 1

Bước đầu tiên, bạn cần triển khai phương thức run () được cung cấp bởi Runnablegiao diện. Phương thức này cung cấp một điểm vào cho luồng và bạn sẽ đưa logic nghiệp vụ hoàn chỉnh của mình vào bên trong phương pháp này. Sau đây là một cú pháp đơn giản của phương thức run ():

public void run( )

Bước 2

Bước thứ hai, bạn sẽ khởi tạo Thread đối tượng sử dụng hàm tạo sau:

Thread(Runnable threadObj, String threadName);

Trong đó, threadObj là một thể hiện của một lớp thực hiệnRunnable giao diện và threadName là tên được đặt cho chủ đề mới.

Bước 3

Sau khi một đối tượng Thread được tạo, bạn có thể bắt đầu nó bằng cách gọi start()phương thức thực thi một cuộc gọi đến phương thức run (). Sau đây là một cú pháp đơn giản của phương thức start ():

void start();

Thí dụ

Đây là một ví dụ tạo một chuỗi mới và bắt đầu chạy nó -

class RunnableDemo implements Runnable {
   private Thread t;
   private String threadName;
   
   RunnableDemo( String name) {
      threadName = name;
      System.out.println("Creating " +  threadName );
   }
   
   public void run() {
      System.out.println("Running " +  threadName );
      try {
         for(int i = 4; i > 0; i--) {
            System.out.println("Thread: " + threadName + ", " + i);
            // Let the thread sleep for a while.
            Thread.sleep(50);
         }
      } catch (InterruptedException e) {
         System.out.println("Thread " +  threadName + " interrupted.");
      }
      System.out.println("Thread " +  threadName + " exiting.");
   }
   
   public void start () {
      System.out.println("Starting " +  threadName );
      if (t == null) {
         t = new Thread (this, threadName);
         t.start ();
      }
   }
}

public class TestThread {

   public static void main(String args[]) {
      RunnableDemo R1 = new RunnableDemo( "Thread-1");
      R1.start();
      
      RunnableDemo R2 = new RunnableDemo( "Thread-2");
      R2.start();
   }   
}

Điều này sẽ tạo ra kết quả sau:

Đầu ra

Creating Thread-1
Starting Thread-1
Creating Thread-2
Starting Thread-2
Running Thread-1
Thread: Thread-1, 4
Running Thread-2
Thread: Thread-2, 4
Thread: Thread-1, 3
Thread: Thread-2, 3
Thread: Thread-1, 2
Thread: Thread-2, 2
Thread: Thread-1, 1
Thread: Thread-2, 1
Thread Thread-1 exiting.
Thread Thread-2 exiting.

Tạo một chủ đề bằng cách mở rộng một lớp chủ đề

Cách thứ hai để tạo một luồng là tạo một lớp mới mở rộng Threadlớp bằng hai bước đơn giản sau. Cách tiếp cận này cung cấp sự linh hoạt hơn trong việc xử lý nhiều luồng được tạo bằng các phương thức có sẵn trong lớp Thread.

Bước 1

Bạn sẽ cần ghi đè run( )phương thức có sẵn trong lớp Thread. Phương thức này cung cấp một điểm vào cho luồng và bạn sẽ đưa logic nghiệp vụ hoàn chỉnh của mình vào bên trong phương pháp này. Sau đây là một cú pháp đơn giản của phương thức run ():

public void run( )

Bước 2

Sau khi đối tượng Thread được tạo, bạn có thể bắt đầu nó bằng cách gọi start()phương thức thực thi một cuộc gọi đến phương thức run (). Sau đây là một cú pháp đơn giản của phương thức start ():

void start( );

Thí dụ

Đây là chương trình trước đó được viết lại để mở rộng Chủ đề -

class ThreadDemo extends Thread {
   private Thread t;
   private String threadName;
   
   ThreadDemo( String name) {
      threadName = name;
      System.out.println("Creating " +  threadName );
   }
   
   public void run() {
      System.out.println("Running " +  threadName );
      try {
         for(int i = 4; i > 0; i--) {
            System.out.println("Thread: " + threadName + ", " + i);
            // Let the thread sleep for a while.
            Thread.sleep(50);
         }
      } catch (InterruptedException e) {
         System.out.println("Thread " +  threadName + " interrupted.");
      }
      System.out.println("Thread " +  threadName + " exiting.");
   }
   
   public void start () {
      System.out.println("Starting " +  threadName );
      if (t == null) {
         t = new Thread (this, threadName);
         t.start ();
      }
   }
}

public class TestThread {

   public static void main(String args[]) {
      ThreadDemo T1 = new ThreadDemo( "Thread-1");
      T1.start();
      
      ThreadDemo T2 = new ThreadDemo( "Thread-2");
      T2.start();
   }   
}

Điều này sẽ tạo ra kết quả sau:

Đầu ra

Creating Thread-1
Starting Thread-1
Creating Thread-2
Starting Thread-2
Running Thread-1
Thread: Thread-1, 4
Running Thread-2
Thread: Thread-2, 4
Thread: Thread-1, 3
Thread: Thread-2, 3
Thread: Thread-1, 2
Thread: Thread-2, 2
Thread: Thread-1, 1
Thread: Thread-2, 1
Thread Thread-1 exiting.
Thread Thread-2 exiting.

Phương thức chủ đề

Sau đây là danh sách các phương thức quan trọng có sẵn trong lớp Thread.

Sr.No. Phương pháp & Mô tả
1

public void start()

Bắt đầu luồng trong một đường dẫn thực thi riêng biệt, sau đó gọi phương thức run () trên đối tượng Luồng này.

2

public void run()

Nếu đối tượng Thread này được khởi tạo bằng cách sử dụng đích Runnable riêng, phương thức run () được gọi trên đối tượng Runnable đó.

3

public final void setName(String name)

Thay đổi tên của đối tượng Thread. Ngoài ra còn có một phương thức getName () để lấy tên.

4

public final void setPriority(int priority)

Đặt mức độ ưu tiên của đối tượng Thread này. Các giá trị có thể là từ 1 đến 10.

5

public final void setDaemon(boolean on)

Một tham số true biểu thị Luồng này là một luồng daemon.

6

public final void join(long millisec)

Luồng hiện tại gọi phương thức này trên luồng thứ hai, khiến luồng hiện tại bị chặn cho đến khi luồng thứ hai kết thúc hoặc hết số mili giây được chỉ định.

7

public void interrupt()

Làm gián đoạn chuỗi này, khiến nó tiếp tục thực thi nếu nó bị chặn vì bất kỳ lý do gì.

số 8

public final boolean isAlive()

Trả về true nếu luồng còn sống, bất kỳ thời điểm nào sau khi luồng được bắt đầu nhưng trước khi nó chạy đến khi hoàn thành.

Các phương thức trước đó được gọi trên một đối tượng Thread cụ thể. Các phương thức sau trong lớp Thread là tĩnh. Việc gọi một trong các phương thức tĩnh thực hiện thao tác trên luồng hiện đang chạy.

Sr.No. Phương pháp & Mô tả
1

public static void yield()

Làm cho luồng hiện đang chạy nhường cho bất kỳ luồng nào khác có cùng mức độ ưu tiên đang chờ được lên lịch.

2

public static void sleep(long millisec)

Làm cho chuỗi hiện đang chạy bị chặn trong ít nhất số mili giây được chỉ định.

3

public static boolean holdsLock(Object x)

Trả về true nếu luồng hiện tại giữ khóa trên Đối tượng đã cho.

4

public static Thread currentThread()

Trả về một tham chiếu đến luồng hiện đang chạy, là luồng gọi phương thức này.

5

public static void dumpStack()

In dấu vết ngăn xếp cho luồng hiện đang chạy, rất hữu ích khi gỡ lỗi một ứng dụng đa luồng.

Thí dụ

Chương trình ThreadClassDemo sau đây trình bày một số phương thức này của lớp Thread. Xem xét một lớp họcDisplayMessage cái nào thực hiện Runnable -

// File Name : DisplayMessage.java
// Create a thread to implement Runnable

public class DisplayMessage implements Runnable {
   private String message;
   
   public DisplayMessage(String message) {
      this.message = message;
   }
   
   public void run() {
      while(true) {
         System.out.println(message);
      }
   }
}

Sau đây là một lớp khác mở rộng lớp Thread:

// File Name : GuessANumber.java
// Create a thread to extentd Thread

public class GuessANumber extends Thread {
   private int number;
   public GuessANumber(int number) {
      this.number = number;
   }
   
   public void run() {
      int counter = 0;
      int guess = 0;
      do {
         guess = (int) (Math.random() * 100 + 1);
         System.out.println(this.getName() + " guesses " + guess);
         counter++;
      } while(guess != number);
      System.out.println("** Correct!" + this.getName() + "in" + counter + "guesses.**");
   }
}

Sau đây là chương trình chính, sử dụng các lớp được định nghĩa ở trên -

// File Name : ThreadClassDemo.java
public class ThreadClassDemo {

   public static void main(String [] args) {
      Runnable hello = new DisplayMessage("Hello");
      Thread thread1 = new Thread(hello);
      thread1.setDaemon(true);
      thread1.setName("hello");
      System.out.println("Starting hello thread...");
      thread1.start();
      
      Runnable bye = new DisplayMessage("Goodbye");
      Thread thread2 = new Thread(bye);
      thread2.setPriority(Thread.MIN_PRIORITY);
      thread2.setDaemon(true);
      System.out.println("Starting goodbye thread...");
      thread2.start();

      System.out.println("Starting thread3...");
      Thread thread3 = new GuessANumber(27);
      thread3.start();
      try {
         thread3.join();
      } catch (InterruptedException e) {
         System.out.println("Thread interrupted.");
      }
      System.out.println("Starting thread4...");
      Thread thread4 = new GuessANumber(75);
      
      thread4.start();
      System.out.println("main() is ending...");
   }
}

Điều này sẽ tạo ra kết quả sau. Bạn có thể thử lại ví dụ này và lần nào bạn cũng sẽ nhận được một kết quả khác.

Đầu ra

Starting hello thread...
Starting goodbye thread...
Hello
Hello
Hello
Hello
Hello
Hello
Goodbye
Goodbye
Goodbye
Goodbye
Goodbye
.......

Các khái niệm đa luồng chính của Java

Trong khi thực hiện lập trình Đa luồng trong Java, bạn sẽ cần có các khái niệm sau rất hữu ích:

  • Đồng bộ hóa luồng là gì?

  • Xử lý giao tiếp giữa các luồng

  • Xử lý bế tắc luồng

  • Các hoạt động chính của chuỗi

An appletlà một chương trình Java chạy trong trình duyệt Web. Một applet có thể là một ứng dụng Java đầy đủ chức năng bởi vì nó có toàn bộ Java API.

Có một số khác biệt quan trọng giữa một applet và một ứng dụng Java độc lập, bao gồm những điều sau:

  • Applet là một lớp Java mở rộng lớp java.applet.Applet.

  • Một phương thức main () không được gọi trên một applet và một lớp applet sẽ không định nghĩa main ().

  • Applet được thiết kế để nhúng trong một trang HTML.

  • Khi người dùng xem một trang HTML có chứa applet, mã của applet sẽ được tải xuống máy của người dùng.

  • Cần có JVM để xem một applet. JVM có thể là một trình cắm thêm của trình duyệt Web hoặc một môi trường thời gian chạy riêng biệt.

  • JVM trên máy của người dùng tạo ra một thể hiện của lớp applet và gọi các phương thức khác nhau trong thời gian tồn tại của applet.

  • Applet có các quy tắc bảo mật nghiêm ngặt được thực thi bởi trình duyệt Web. Bảo mật của một applet thường được gọi là bảo mật hộp cát, so sánh applet với một đứa trẻ đang chơi trong hộp cát với nhiều quy tắc khác nhau phải tuân theo.

  • Các lớp khác mà applet cần có thể được tải xuống trong một tệp Java Archive (JAR).

Vòng đời của một Applet

Bốn phương thức trong lớp Applet cung cấp cho bạn khung mà bạn xây dựng bất kỳ applet nghiêm túc nào -

  • init- Phương thức này dành cho bất kỳ quá trình khởi tạo nào cần thiết cho applet của bạn. Nó được gọi sau khi các thẻ param bên trong thẻ applet đã được xử lý.

  • start- Phương thức này được gọi tự động sau khi trình duyệt gọi phương thức init. Nó cũng được gọi bất cứ khi nào người dùng quay lại trang chứa applet sau khi đã chuyển sang các trang khác.

  • stop- Phương thức này tự động được gọi khi người dùng di chuyển khỏi trang mà applet nằm trên đó. Do đó, nó có thể được gọi nhiều lần trong cùng một applet.

  • destroy- Phương thức này chỉ được gọi khi trình duyệt tắt bình thường. Bởi vì các applet có nghĩa là tồn tại trên một trang HTML, thông thường bạn không nên bỏ lại tài nguyên sau khi người dùng rời khỏi trang chứa applet.

  • paint- Được gọi ngay sau phương thức start () và bất cứ lúc nào applet cần sơn lại chính nó trong trình duyệt. Phương thức paint () thực sự được kế thừa từ java.awt.

Applet "Xin chào, Thế giới"

Sau đây là một applet đơn giản có tên HelloWorldApplet.java -

import java.applet.*;
import java.awt.*;

public class HelloWorldApplet extends Applet {
   public void paint (Graphics g) {
      g.drawString ("Hello World", 25, 50);
   }
}

Các câu lệnh nhập này đưa các lớp vào phạm vi của lớp applet của chúng ta -

  • java.applet.Applet
  • java.awt.Graphics

Nếu không có các câu lệnh nhập đó, trình biên dịch Java sẽ không nhận ra các lớp Applet và Graphics, mà lớp applet đề cập đến.

Lớp Applet

Mỗi applet là một phần mở rộng của lớp java.applet.Applet . Lớp Applet cơ sở cung cấp các phương thức mà một lớp Applet dẫn xuất có thể gọi để lấy thông tin và dịch vụ từ ngữ cảnh trình duyệt.

Chúng bao gồm các phương pháp thực hiện như sau:

  • Nhận thông số applet
  • Lấy vị trí mạng của tệp HTML có chứa applet
  • Lấy vị trí mạng của thư mục lớp applet
  • In thông báo trạng thái trong trình duyệt
  • Tìm nạp hình ảnh
  • Tìm nạp một đoạn âm thanh
  • Phát một đoạn âm thanh
  • Thay đổi kích thước của applet

Ngoài ra, lớp Applet cung cấp một giao diện mà người xem hoặc trình duyệt lấy thông tin về applet và kiểm soát việc thực thi của applet. Người xem có thể -

  • Yêu cầu thông tin về tác giả, phiên bản và bản quyền của applet
  • Yêu cầu mô tả các tham số mà applet nhận dạng
  • Khởi tạo applet
  • Hủy applet
  • Bắt đầu thực thi applet
  • Dừng thực thi applet

Lớp Applet cung cấp các triển khai mặc định của mỗi phương thức này. Những triển khai đó có thể bị ghi đè khi cần thiết.

Applet "Xin chào, Thế giới" đã hoàn chỉnh. Phương pháp duy nhất được ghi đè là phương pháp sơn.

Gọi một Applet

Một applet có thể được gọi bằng cách nhúng các lệnh vào một tệp HTML và xem tệp đó thông qua trình xem applet hoặc trình duyệt hỗ trợ Java.

Thẻ <applet> là cơ sở để nhúng một applet vào tệp HTML. Sau đây là một ví dụ gọi applet "Hello, World" -

<html>
   <title>The Hello, World Applet</title>
   <hr>
   <applet code = "HelloWorldApplet.class" width = "320" height = "120">
      If your browser was Java-enabled, a "Hello, World"
      message would appear here.
   </applet>
   <hr>
</html>

Note- Bạn có thể tham khảo HTML Applet Tag để hiểu thêm về cách gọi applet từ HTML.

Thuộc tính mã của thẻ <applet> là bắt buộc. Nó chỉ định lớp Applet để chạy. Chiều rộng và chiều cao cũng được yêu cầu để chỉ định kích thước ban đầu của bảng điều khiển mà một applet chạy. Chỉ thị applet phải được đóng bằng thẻ </applet>.

Nếu một applet nhận tham số, các giá trị có thể được chuyển cho các tham số bằng cách thêm thẻ <param> vào giữa <applet> và </applet>. Trình duyệt bỏ qua văn bản và các thẻ khác giữa các thẻ applet.

Các trình duyệt không hỗ trợ Java không xử lý <applet> và </applet>. Do đó, bất kỳ thứ gì xuất hiện giữa các thẻ, không liên quan đến applet, đều có thể nhìn thấy trong các trình duyệt không hỗ trợ Java.

Trình xem hoặc trình duyệt tìm kiếm mã Java đã biên dịch tại vị trí của tài liệu. Để chỉ định khác, hãy sử dụng thuộc tính codebase của thẻ <applet> như minh họa -

<applet codebase = "https://amrood.com/applets" code = "HelloWorldApplet.class"
   width = "320" height = "120">

Nếu một applet nằm trong một gói khác với gói mặc định, thì gói giữ phải được chỉ định trong thuộc tính mã bằng cách sử dụng ký tự dấu chấm (.) Để phân tách các thành phần gói / lớp. Ví dụ -

<applet  = "mypackage.subpackage.TestApplet.class" 
   width = "320" height = "120">

Nhận thông số Applet

Ví dụ sau minh họa cách làm cho một applet phản hồi với các tham số thiết lập được chỉ định trong tài liệu. Applet này hiển thị một mẫu bàn cờ có màu đen và màu thứ hai.

Màu thứ hai và kích thước của mỗi hình vuông có thể được chỉ định làm tham số cho applet trong tài liệu.

CheckerApplet nhận các tham số của nó trong phương thức init (). Nó cũng có thể nhận các tham số của nó trong phương thức paint (). Tuy nhiên, việc nhận các giá trị và lưu các cài đặt một lần khi bắt đầu applet, thay vì mỗi lần làm mới, rất tiện lợi và hiệu quả.

Trình xem applet hoặc trình duyệt gọi phương thức init () của mỗi applet mà nó chạy. Người xem gọi init () một lần, ngay sau khi tải applet. (Applet.init () được triển khai để không làm gì cả.) Ghi đè triển khai mặc định để chèn mã khởi tạo tùy chỉnh.

Phương thức Applet.getParameter () tìm nạp một tham số được cung cấp bởi tên của tham số (giá trị của tham số luôn là một chuỗi). Nếu giá trị là số hoặc dữ liệu không phải ký tự khác, thì chuỗi phải được phân tích cú pháp.

Sau đây là khung của CheckerApplet.java:

import java.applet.*;
import java.awt.*;

public class CheckerApplet extends Applet {
   int squareSize = 50;   // initialized to default size
   public void init() {}
   private void parseSquareSize (String param) {}
   private Color parseColor (String param) {}
   public void paint (Graphics g) {}
}

Đây là phương thức init () và private parseSquareSize () của CheckerApplet -

public void init () {
   String squareSizeParam = getParameter ("squareSize");
   parseSquareSize (squareSizeParam);
   
   String colorParam = getParameter ("color");
   Color fg = parseColor (colorParam);
   
   setBackground (Color.black);
   setForeground (fg);
}

private void parseSquareSize (String param) {
   if (param == null) return;
   try {
      squareSize = Integer.parseInt (param);
   } catch (Exception e) {
      // Let default value remain
   }
}

Applet gọi parseSquareSize () để phân tích cú pháp tham số squareSize. parseSquareSize () gọi phương thức thư viện Integer.parseInt (), phân tích cú pháp một chuỗi và trả về một số nguyên. Integer.parseInt () ném một ngoại lệ bất cứ khi nào đối số của nó không hợp lệ.

Do đó, parseSquareSize () bắt các ngoại lệ, thay vì cho phép applet bị lỗi khi nhập sai.

Applet gọi parseColor () để phân tích cú pháp tham số màu thành giá trị Màu. parseColor () thực hiện một loạt các so sánh chuỗi để khớp giá trị tham số với tên của màu được xác định trước. Bạn cần triển khai các phương pháp này để làm cho applet này hoạt động.

Chỉ định tham số Applet

Sau đây là một ví dụ về tệp HTML với CheckerApplet được nhúng trong đó. Tệp HTML chỉ định cả hai tham số cho applet bằng thẻ <param>.

<html>
   <title>Checkerboard Applet</title>
   <hr>
   <applet code = "CheckerApplet.class" width = "480" height = "320">
      <param name = "color" value = "blue">
      <param name = "squaresize" value = "30">
   </applet>
   <hr>
</html>

Note - Tên tham số không phân biệt chữ hoa chữ thường.

Chuyển đổi ứng dụng sang Applet

Thật dễ dàng để chuyển đổi một ứng dụng Java đồ họa (tức là một ứng dụng sử dụng AWT và bạn có thể bắt đầu với trình khởi chạy chương trình Java) thành một applet mà bạn có thể nhúng vào một trang web.

Sau đây là các bước cụ thể để chuyển đổi một ứng dụng thành một applet.

  • Tạo một trang HTML với thẻ thích hợp để tải mã applet.

  • Cung cấp một lớp con của lớp JApplet. Đặt lớp này ở chế độ công khai. Nếu không, không thể tải applet.

  • Loại bỏ phương thức chính trong ứng dụng. Không xây dựng một cửa sổ khung cho ứng dụng. Ứng dụng của bạn sẽ được hiển thị bên trong trình duyệt.

  • Di chuyển bất kỳ mã khởi tạo nào từ phương thức khởi tạo cửa sổ khung sang phương thức init của applet. Bạn không cần phải xây dựng đối tượng applet một cách rõ ràng. Trình duyệt khởi tạo nó cho bạn và gọi phương thức init.

  • Xóa cuộc gọi đến setSize; đối với các applet, việc định cỡ được thực hiện với các tham số chiều rộng và chiều cao trong tệp HTML.

  • Loại bỏ lệnh gọi setDefaultCloseOperation. Không thể đóng một applet; nó chấm dứt khi trình duyệt thoát.

  • Nếu ứng dụng gọi setTitle, hãy loại bỏ lệnh gọi phương thức. Applet không được có thanh tiêu đề. (Tất nhiên, bạn có thể đặt tiêu đề cho chính trang web bằng cách sử dụng thẻ tiêu đề HTML.)

  • Đừng gọi setVible (true). Applet được hiển thị tự động.

Xử lý sự kiện

Applet kế thừa một nhóm các phương thức xử lý sự kiện từ lớp Container. Lớp Container định nghĩa một số phương thức, chẳng hạn như processKeyEvent và processMouseEvent, để xử lý các loại sự kiện cụ thể và sau đó là một phương thức tóm tắt được gọi là processEvent.

Để phản ứng với một sự kiện, một applet phải ghi đè lên phương thức dành riêng cho sự kiện thích hợp.

import java.awt.event.MouseListener;
import java.awt.event.MouseEvent;
import java.applet.Applet;
import java.awt.Graphics;

public class ExampleEventHandling extends Applet implements MouseListener {
   StringBuffer strBuffer;

   public void init() {
      addMouseListener(this);
      strBuffer = new StringBuffer();
      addItem("initializing the apple ");
   }

   public void start() {
      addItem("starting the applet ");
   }

   public void stop() {
      addItem("stopping the applet ");
   }

   public void destroy() {
      addItem("unloading the applet");
   }

   void addItem(String word) {
      System.out.println(word);
      strBuffer.append(word);
      repaint();
   }

   public void paint(Graphics g) {
      // Draw a Rectangle around the applet's display area.
      g.drawRect(0, 0, 
      getWidth() - 1,
      getHeight() - 1);

      // display the string inside the rectangle.
      g.drawString(strBuffer.toString(), 10, 20);
   }

   
   public void mouseEntered(MouseEvent event) {
   }
   public void mouseExited(MouseEvent event) {
   }
   public void mousePressed(MouseEvent event) {
   }
   public void mouseReleased(MouseEvent event) {
   }
   public void mouseClicked(MouseEvent event) {
      addItem("mouse clicked! ");
   }
}

Bây giờ, chúng ta hãy gọi applet này như sau:

<html>
   <title>Event Handling</title>
   <hr>
   <applet code = "ExampleEventHandling.class" 
      width = "300" height = "300">
   </applet>
   <hr>
</html>

Ban đầu, applet sẽ hiển thị "đang khởi tạo applet. Đang khởi động applet." Sau đó, một khi bạn nhấp vào bên trong hình chữ nhật, "đã nhấp chuột" cũng sẽ được hiển thị.

Hiển thị hình ảnh

Một applet có thể hiển thị hình ảnh có định dạng GIF, JPEG, BMP và các định dạng khác. Để hiển thị hình ảnh trong applet, bạn sử dụng phương thức drawImage () có trong lớp java.awt.Graphics.

Sau đây là một ví dụ minh họa tất cả các bước để hiển thị hình ảnh -

import java.applet.*;
import java.awt.*;
import java.net.*;

public class ImageDemo extends Applet {
   private Image image;
   private AppletContext context;
   
   public void init() {
      context = this.getAppletContext();
      String imageURL = this.getParameter("image");
      if(imageURL == null) {
         imageURL = "java.jpg";
      }
      try {
         URL url = new URL(this.getDocumentBase(), imageURL);
         image = context.getImage(url);
      } catch (MalformedURLException e) {
         e.printStackTrace();
         // Display in browser status bar
         context.showStatus("Could not load image!");
      }
   }
   
   public void paint(Graphics g) {
      context.showStatus("Displaying image");
      g.drawImage(image, 0, 0, 200, 84, null);
      g.drawString("www.javalicense.com", 35, 100);
   }  
}

Bây giờ, chúng ta hãy gọi applet này như sau:

<html>
   <title>The ImageDemo applet</title>
   <hr>
   <applet code = "ImageDemo.class" width = "300" height = "200">
      <param name = "image" value = "java.jpg">
   </applet>
   <hr>
</html>

Phát âm thanh

Một applet có thể phát một tệp âm thanh được đại diện bởi giao diện AudioClip trong gói java.applet. Giao diện AudioClip có ba phương pháp, bao gồm:

  • public void play() - Phát đoạn âm thanh một lần, từ đầu.

  • public void loop() - Khiến đoạn âm thanh phát lại liên tục.

  • public void stop() - Dừng phát đoạn âm thanh.

Để lấy một đối tượng AudioClip, bạn phải gọi phương thức getAudioClip () của lớp Applet. Phương thức getAudioClip () trả về ngay lập tức, cho dù URL có phân giải thành tệp âm thanh thực hay không. Tệp âm thanh không được tải xuống cho đến khi cố gắng phát đoạn âm thanh.

Sau đây là ví dụ minh họa tất cả các bước để phát âm thanh -

import java.applet.*;
import java.awt.*;
import java.net.*;

public class AudioDemo extends Applet {
   private AudioClip clip;
   private AppletContext context;
   
   public void init() {
      context = this.getAppletContext();
      String audioURL = this.getParameter("audio");
      if(audioURL == null) {
         audioURL = "default.au";
      }
      try {
         URL url = new URL(this.getDocumentBase(), audioURL);
         clip = context.getAudioClip(url);
      } catch (MalformedURLException e) {
         e.printStackTrace();
         context.showStatus("Could not load audio file!");
      }
   }
   
   public void start() {
      if(clip != null) {
         clip.loop();
      }
   }
   
   public void stop() {
      if(clip != null) {
         clip.stop();
      }
   }
}

Bây giờ, chúng ta hãy gọi applet này như sau:

<html>
   <title>The ImageDemo applet</title>
   <hr>
   <applet code = "ImageDemo.class" width = "0" height = "0">
      <param name = "audio" value = "test.wav">
   </applet>
   <hr>
</html>

Bạn có thể sử dụng test.wav trên PC của mình để kiểm tra ví dụ trên.

Ngôn ngữ Java hỗ trợ ba loại nhận xét:

Sr.No. Nhận xét & Mô tả
1

/* text */

Trình biên dịch bỏ qua mọi thứ từ / * đến * /.

2

//text

Trình biên dịch bỏ qua mọi thứ từ // đến cuối dòng.

3

/** documentation */

Đây là một nhận xét tài liệu và nói chung nó được gọi là doc comment. CácJDK javadoccông cụ sử dụng chú thích tài liệu khi chuẩn bị tài liệu được tạo tự động.

Chương này là tất cả về giải thích Javadoc. Chúng ta sẽ xem cách chúng ta có thể sử dụng Javadoc để tạo tài liệu hữu ích cho mã Java.

Javadoc là gì?

Javadoc là một công cụ đi kèm với JDK và nó được sử dụng để tạo tài liệu mã Java ở định dạng HTML từ mã nguồn Java, công cụ này yêu cầu tài liệu ở định dạng được xác định trước.

Sau đây là một ví dụ đơn giản trong đó các dòng bên trong /*….*/ là các chú thích nhiều dòng của Java. Tương tự, dòng đứng trước // là chú thích một dòng của Java.

Thí dụ

/**
* The HelloWorld program implements an application that
* simply displays "Hello World!" to the standard output.
*
* @author  Zara Ali
* @version 1.0
* @since   2014-03-31 
*/
public class HelloWorld {

   public static void main(String[] args) {
      // Prints Hello, World! on standard output.
      System.out.println("Hello World!");
   }
}

Bạn có thể bao gồm các thẻ HTML bắt buộc bên trong phần mô tả. Ví dụ: ví dụ sau sử dụng <h1> .... </h1> cho tiêu đề và <p> được sử dụng để tạo ngắt đoạn -

Thí dụ

/**
* <h1>Hello, World!</h1>
* The HelloWorld program implements an application that
* simply displays "Hello World!" to the standard output.
* <p>
* Giving proper comments in your program makes it more
* user friendly and it is assumed as a high quality code.
* 
*
* @author  Zara Ali
* @version 1.0
* @since   2014-03-31 
*/
public class HelloWorld {

   public static void main(String[] args) {
      // Prints Hello, World! on standard output.
      System.out.println("Hello World!");
   }
}

Các thẻ javadoc

Công cụ javadoc nhận dạng các thẻ sau:

Nhãn Sự miêu tả Cú pháp
@author Thêm tác giả của một lớp. @author name-text
{@code} Hiển thị văn bản trong phông chữ mã mà không hiểu văn bản dưới dạng đánh dấu HTML hoặc các thẻ javadoc lồng nhau. {@code text}
{@docRoot} Đại diện cho đường dẫn liên quan đến thư mục gốc của tài liệu được tạo từ bất kỳ trang nào được tạo. {@docRoot}
@deprecated Thêm nhận xét cho biết rằng API này không nên được sử dụng nữa. @deprecated không được dùng nữa
@ngoại lệ Thêm một Throws tiêu đề phụ của tài liệu đã tạo, với tên lớp và văn bản mô tả. @exception class-name description
{@inheritDoc} Kế thừa một nhận xét từ nearest lớp kế thừa hoặc giao diện có thể triển khai. Kế thừa nhận xét từ lớp thay thế ngay lập tức.
{@link} Chèn một liên kết nội dòng với nhãn văn bản hiển thị trỏ đến tài liệu cho gói, lớp hoặc tên thành viên được chỉ định của một lớp được tham chiếu. {@link package.class # member label}
{@linkplain} Giống hệt với {@link}, ngoại trừ nhãn của liên kết được hiển thị bằng văn bản thuần túy hơn là phông chữ mã. {@linkplain package.class # member label}
@param Thêm một tham số với tên tham số được chỉ định, theo sau là mô tả được chỉ định vào phần "Tham số". @param tham số-tên mô tả
@trở về Thêm phần "Trả lại" với văn bản mô tả. @return mô tả
@xem Thêm tiêu đề "Xem thêm" với một liên kết hoặc mục nhập văn bản trỏ đến tham chiếu. @see tham khảo
@serial Được sử dụng trong nhận xét tài liệu cho trường có thể tuần tự hóa mặc định. @serial field-description | bao gồm | loại trừ
@serialData Ghi lại dữ liệu được ghi bởi phương thức writeObject () hoặc writeExternal (). @serialData data-description
@serialField Tài liệu một thành phần ObjectStreamField. @serialField trường-tên trường-loại trường-mô tả
@từ Thêm tiêu đề "Kể từ" với văn bản kể từ được chỉ định vào tài liệu được tạo. @since phát hành
@throws Các thẻ @throws và @exception là các từ đồng nghĩa. @throws class-name description
{@giá trị} Khi {@value} được sử dụng trong nhận xét tài liệu của một trường tĩnh, nó sẽ hiển thị giá trị của hằng số đó. {@value package.class # field}
@phiên bản Thêm tiêu đề phụ "Phiên bản" với văn bản phiên bản được chỉ định vào tài liệu đã tạo khi tùy chọn -version được sử dụng. @version version-text

Thí dụ

Chương trình sau sử dụng một số thẻ quan trọng có sẵn cho các nhận xét tài liệu. Bạn có thể sử dụng các thẻ khác dựa trên yêu cầu của mình.

Tài liệu về lớp AddNum sẽ được tạo trong tệp HTML AddNum.html nhưng đồng thời tệp chính có tên index.html cũng sẽ được tạo.

import java.io.*;

/**
* <h1>Add Two Numbers!</h1>
* The AddNum program implements an application that
* simply adds two given integer numbers and Prints
* the output on the screen.
* <p>
* <b>Note:</b> Giving proper comments in your program makes it more
* user friendly and it is assumed as a high quality code.
*
* @author  Zara Ali
* @version 1.0
* @since   2014-03-31
*/
public class AddNum {
   /**
   * This method is used to add two integers. This is
   * a the simplest form of a class method, just to
   * show the usage of various javadoc Tags.
   * @param numA This is the first paramter to addNum method
   * @param numB  This is the second parameter to addNum method
   * @return int This returns sum of numA and numB.
   */
   public int addNum(int numA, int numB) {
      return numA + numB;
   }

   /**
   * This is the main method which makes use of addNum method.
   * @param args Unused.
   * @return Nothing.
   * @exception IOException On input error.
   * @see IOException
   */

   public static void main(String args[]) throws IOException {
      AddNum obj = new AddNum();
      int sum = obj.addNum(10, 20);

      System.out.println("Sum of 10 and 20 is :" + sum);
   }
}

Bây giờ, xử lý tệp AddNum.java ở trên bằng tiện ích javadoc như sau:

$ javadoc AddNum.java
Loading source file AddNum.java...
Constructing Javadoc information...
Standard Doclet version 1.7.0_51
Building tree for all the packages and classes...
Generating /AddNum.html...
AddNum.java:36: warning - @return tag cannot be used in method with void return type.
Generating /package-frame.html...
Generating /package-summary.html...
Generating /package-tree.html...
Generating /constant-values.html...
Building index for all the packages and classes...
Generating /overview-tree.html...
Generating /index-all.html...
Generating /deprecated-list.html...
Building index for all classes...
Generating /allclasses-frame.html...
Generating /allclasses-noframe.html...
Generating /index.html...
Generating /help-doc.html...
1 warning
$

Bạn có thể kiểm tra tất cả các tài liệu đã tạo ở đây - AddNum . Nếu bạn đang sử dụng JDK 1.7 thì javadoc không tạo ra mộtstylesheet.css, vì vậy chúng tôi khuyên bạn nên tải xuống và sử dụng biểu định kiểu chuẩn từ https://docs.oracle.com/javase/7/docs/api/stylesheet.css