Groovy - Hướng dẫn nhanh

Groovy là một ngôn ngữ hướng đối tượng dựa trên nền tảng Java. Groovy 1.0 được phát hành vào ngày 2 tháng 1 năm 2007 với Groovy 2.4 là phiên bản chính hiện tại. Groovy được phân phối thông qua Giấy phép Apache v 2.0.

Đặc điểm của Groovy

Groovy có các tính năng sau:

  • Hỗ trợ cả gõ tĩnh và động.
  • Hỗ trợ người vận hành quá tải.
  • Cú pháp riêng cho danh sách và mảng kết hợp.
  • Hỗ trợ riêng cho cụm từ thông dụng.
  • Hỗ trợ riêng cho các ngôn ngữ đánh dấu khác nhau như XML và HTML.
  • Groovy rất đơn giản đối với các nhà phát triển Java vì cú pháp của Java và Groovy rất giống nhau.
  • Bạn có thể sử dụng các thư viện Java hiện có.
  • Groovy mở rộng java.lang.Object.

Trang web chính thức của Groovy là http://www.groovy-lang.org/

Có nhiều cách khác nhau để thiết lập môi trường Groovy.

Binary download and installation- Vào đường dẫn www.groovy-lang.org/download.html để lấy phần Windows Installer. Nhấp vào tùy chọn này để bắt đầu tải xuống trình cài đặt Groovy.

Sau khi bạn khởi chạy trình cài đặt, hãy làm theo các bước dưới đây để hoàn tất cài đặt.

Step 1 - Chọn trình cài đặt ngôn ngữ.

Step 2 - Nhấp vào nút Tiếp theo trong màn hình tiếp theo.

Step 3 - Nhấp vào nút 'Tôi Đồng ý'.

Step 4 - Chấp nhận các thành phần mặc định và nhấp vào nút Tiếp theo.

Step 5 - Chọn thư mục đích thích hợp và sau đó nhấp vào nút Tiếp theo.

Step 6 - Nhấn vào nút Install để bắt đầu cài đặt.

Step 7 - Sau khi cài đặt xong, nhấp vào nút Tiếp theo để bắt đầu cấu hình.

Step 8 - Chọn các tùy chọn mặc định và nhấp vào nút Tiếp theo.

Step 9 - Chấp nhận các liên kết tệp mặc định và nhấp vào nút Tiếp theo.

Step 10 - Nhấn nút Finish để hoàn tất cài đặt.

Sau khi các bước trên được thực hiện, sau đó bạn có thể khởi động Groovy shell là một phần của cài đặt Groovy giúp kiểm tra các khía cạnh khác nhau của ngôn ngữ Groovy mà không cần phải có một môi trường phát triển tích hợp chính thức cho Groovy. Điều này có thể được thực hiện bằng cách chạy lệnh groovysh từ dấu nhắc lệnh.

Nếu bạn muốn bao gồm các mã nhị phân Groovy như một phần của bản dựng maven hoặc gradle, bạn có thể thêm các dòng sau

Gradle

'org.codehaus.groovy:groovy:2.4.5'

Maven

<groupId>org.codehaus.groovy</groupId> 
<artifactId>groovy</artifactId>  
<version>2.4.5</version>

Để hiểu cú pháp cơ bản của Groovy, trước tiên chúng ta hãy xem một chương trình Hello World đơn giản.

Tạo chương trình Hello World đầu tiên của bạn

Tạo chương trình hello world đầu tiên của bạn rất đơn giản chỉ cần nhập dòng mã sau:

class Example {
   static void main(String[] args) {
      // Using a simple println statement to print output to the console
      println('Hello World');
   }
}

Khi chúng ta chạy chương trình trên, chúng ta sẽ nhận được kết quả sau:

Hello World

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

Câu lệnh nhập có thể được sử dụng để nhập chức năng của các thư viện khác có thể được sử dụng trong mã của bạn. Điều này được thực hiện bằng cách sử dụngimport từ khóa.

Ví dụ sau đây cho thấy cách sử dụng một cách nhập đơn giản của lớp MarkupBuilder, đây có lẽ là một trong những lớp được sử dụng nhiều nhất để tạo đánh dấu HTML hoặc XML.

import groovy.xml.MarkupBuilder 
def xml = new MarkupBuilder()

Theo mặc định, Groovy bao gồm các thư viện sau trong mã của bạn, vì vậy bạn không cần phải nhập chúng một cách rõ ràng.

import java.lang.* 
import java.util.* 
import java.io.* 
import java.net.* 

import groovy.lang.* 
import groovy.util.* 

import java.math.BigInteger 
import java.math.BigDecimal

Token ở Groovy

Mã thông báo là một từ khóa, một mã định danh, một hằng số, một chuỗi ký tự hoặc một ký hiệu.

println(“Hello World”);

Trong dòng mã trên, có hai mã thông báo, đầu tiên là từ khóa println và tiếp theo là chuỗi ký tự của “Hello World”.

Nhận xét trong Groovy

Nhận xét được sử dụng để ghi lại mã của bạn. Nhận xét trong Groovy có thể là một dòng hoặc nhiều dòng.

Nhận xét dòng đơn được xác định bằng cách sử dụng // tại bất kỳ vị trí nào trong dòng. Một ví dụ được hiển thị bên dưới -

class Example {
   static void main(String[] args) {
      // Using a simple println statement to print output to the console
      println('Hello World');
   }
}

Nhận xét nhiều dòng được xác định bằng / * ở đầu và * / để xác định phần cuối của nhận xét nhiều dòng.

class Example {
   static void main(String[] args) {
      /* This program is the first program
      This program shows how to display hello world */
      println('Hello World');
   }
}

Dấu chấm phẩy

Không giống như ngôn ngữ lập trình Java, không bắt buộc phải có dấu chấm phẩy sau cuối mỗi câu lệnh, Nó là tùy chọn.

class Example {
   static void main(String[] args) {
      def x = 5
      println('Hello World');  
   }
}

Nếu bạn thực hiện chương trình trên, cả hai câu lệnh trong phương thức chính không tạo ra bất kỳ lỗi nào.

Định danh

Định danh được sử dụng để xác định các biến, hàm hoặc các biến do người dùng xác định khác. Số nhận dạng bắt đầu bằng một chữ cái, một đô la hoặc một dấu gạch dưới. Chúng không thể bắt đầu bằng một số. Dưới đây là một số ví dụ về số nhận dạng hợp lệ -

def employeename 
def student1 
def student_name

Ở đâu def là một từ khóa được sử dụng trong Groovy để xác định mã định danh.

Đây là một ví dụ mã về cách một số nhận dạng có thể được sử dụng trong chương trình Hello World của chúng tôi.

class Example {
   static void main(String[] args) {
      // One can see the use of a semi-colon after each statement
      def x = 5;
      println('Hello World'); 
   }
}

Trong ví dụ trên, biến x được sử dụng như một định danh.

Từ khóa

Các từ khóa như tên gợi ý là các từ đặc biệt được dành riêng trong ngôn ngữ Lập trình Groovy. Bảng sau đây liệt kê các từ khóa được định nghĩa trong Groovy.

như khẳng định phá vỡ trường hợp
nắm lấy lớp học hăng sô tiếp tục
phản đối mặc định làm khác
enum kéo dài sai Cuối cùng
cho đi đến nếu dụng cụ
nhập khẩu trong ví dụ giao diện
Mới kéo gói hàng trở về
siêu công tắc điện điều này phi
ném đặc điểm thật thử
trong khi

Khoảng trắng

Khoảng trắng là thuật ngữ được sử dụng trong ngôn ngữ lập trình như Java và Groovy để mô tả khoảng trống, tab, ký tự dòng mới và nhận xét. Khoảng trắng phân tách một phần của một câu lệnh với phần khác và cho phép trình biên dịch xác định vị trí của một phần tử trong một câu lệnh.

Ví dụ: trong ví dụ mã sau, có một khoảng trắng giữa từ khóa defvà biến x. Điều này để trình biên dịch biết rằngdef là từ khóa cần được sử dụng và x phải là tên biến cần được xác định.

def x = 5;

Chữ viết

Chữ là một ký hiệu để biểu thị một giá trị cố định trong groovy. Ngôn ngữ groovy có các ký hiệu cho số nguyên, số dấu phẩy động, ký tự và chuỗi. Dưới đây là một số ví dụ về các ký tự trong ngôn ngữ lập trình Groovy -

12 
1.45 
‘a’ 
“aa”

Trong bất kỳ ngôn ngữ lập trình nào, bạn cần sử dụng các biến khác nhau để lưu trữ các loại thông tin. 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ớ để lưu giá trị được liên kết với biến.

Bạn có thể muốn lưu trữ thông tin của nhiều kiểu dữ liệu khác nhau như chuỗi, ký tự, ký tự rộng, số nguyên, dấu phẩy động, Boolean, v.v. Dựa trên kiểu dữ liệu của một biến, hệ điều hành phân bổ bộ nhớ và quyết định những gì có thể được lưu trữ trong ký ức.

Các loại dữ liệu tích hợp

Groovy cung cấp nhiều loại dữ liệu tích hợp sẵn. Sau đây là danh sách các kiểu dữ liệu được định nghĩa trong Groovy:

  • byte- Điều này được sử dụng để biểu diễn một giá trị byte. Một ví dụ là 2.

  • short- Điều này được sử dụng để biểu diễn một số ngắn. Một ví dụ là 10.

  • int- Điều này được sử dụng để biểu diễn các số nguyên. Một ví dụ là 1234.

  • long- Điều này được sử dụng để biểu thị một số dài. Một ví dụ là 10000090.

  • float- Điều này được sử dụng để biểu diễn số dấu phẩy động 32-bit. Một ví dụ là 12,34.

  • double- Điều này được sử dụng để biểu diễn số dấu phẩy động 64-bit, là biểu diễn số thập phân dài hơn có thể được yêu cầu đôi khi. Một ví dụ là 12.3456565.

  • char- Điều này xác định một ký tự đơn lẻ. Một ví dụ là 'a'.

  • Boolean - Giá trị này đại diện cho một giá trị Boolean có thể đúng hoặc sai.

  • String - Đây là các ký tự văn bản được biểu diễn bằng the formcủa chuỗi ký tự. Ví dụ: “Hello World”.

Giá trị ràng buộc

Bảng sau đây cho thấy các giá trị tối đa được phép cho các chữ số và chữ số thập phân.

byte -128 đến 127
ngắn -32,768 đến 32,767
int -2.147.483.648 đến 2.147.483.647
Dài -9,223,372,036,854,775,808 đến +9,223,372,036,854,775,807
Phao nổi 1,40129846432481707e-45 đến 3,40282346638528860e + 38
gấp đôi 4.94065645841246544e-324ngày đến 1.79769313486231570e + 308ngày

Class Numeric

Các kiểu Ngoài các kiểu nguyên thủy, các kiểu đối tượng sau đây (đôi khi được gọi là kiểu trình bao bọc) được phép:

  • java.lang.Byte
  • java.lang.Short
  • java.lang.Integer
  • java.lang.Long
  • java.lang.Float
  • java.lang.Double

Ngoài ra, các lớp sau có thể được sử dụng để hỗ trợ số học chính xác tùy ý:

Tên Sự miêu tả Thí dụ
java.math.BigInteger Số tích phân có dấu chính xác tùy ý bất biến 30g
java.math.BigDecimal Số thập phân có dấu chính xác tùy ý bất biến 3,5g

Ví dụ mã sau đây cho thấy cách sử dụng các kiểu dữ liệu tích hợp sẵn khác nhau:

class Example { 
   static void main(String[] args) { 
      //Example of a int datatype 
      int x = 5; 
		
      //Example of a long datatype 
      long y = 100L; 
		
      //Example of a floating point datatype 
      float a = 10.56f; 
		
      //Example of a double datatype 
      double b = 10.5e40; 
		
      //Example of a BigInteger datatype 
      BigInteger bi = 30g; 
		
      //Example of a BigDecimal datatype 
      BigDecimal bd = 3.5g; 
		
      println(x); 
      println(y); 
      println(a); 
      println(b); 
      println(bi); 
      println(bd); 
   } 
}

Khi chúng ta chạy chương trình trên, chúng ta sẽ nhận được kết quả sau:

5 
100 
10.56 
1.05E41 
30 
3.5

Các biến trong Groovy có thể được định nghĩa theo hai cách - sử dụng native syntax cho loại dữ liệu hoặc tiếp theo là by using the def keyword. Đối với các định nghĩa biến, bắt buộc phải cung cấp tên kiểu một cách rõ ràng hoặc sử dụng "def" để thay thế. Điều này được yêu cầu bởi trình phân tích cú pháp Groovy.

Có các loại biến cơ bản sau trong Groovy như được giải thích trong chương trước:

  • byte- Điều này được sử dụng để biểu diễn một giá trị byte. Một ví dụ là 2.

  • short- Điều này được sử dụng để biểu diễn một số ngắn. Một ví dụ là 10.

  • int- Điều này được sử dụng để biểu diễn các số nguyên. Một ví dụ là 1234.

  • long- Điều này được sử dụng để biểu thị một số dài. Một ví dụ là 10000090.

  • float- Điều này được sử dụng để biểu diễn số dấu phẩy động 32-bit. Một ví dụ là 12,34.

  • double- Điều này được sử dụng để biểu diễn số dấu phẩy động 64-bit, là biểu diễn số thập phân dài hơn có thể được yêu cầu đôi khi. Một ví dụ là 12.3456565.

  • char- Điều này xác định một ký tự đơn lẻ. Một ví dụ là 'a'.

  • Boolean - Giá trị này đại diện cho một giá trị Boolean có thể đúng hoặc sai.

  • String - Đây là các ký tự văn bản được biểu diễn bằng the formcủa chuỗi ký tự. Ví dụ: “Hello World”.

Groovy cũng cho phép các loại biến bổ sung như mảng, cấu trúc và lớp mà chúng ta sẽ thấy trong các chương tiếp theo.

Khai báo biến

Một khai báo biến cho trình biên dịch biết vị trí và dung lượng để tạo bộ lưu trữ cho biến.

Sau đây là một ví dụ về khai báo biến:

class Example { 
   static void main(String[] args) { 
      // x is defined as a variable 
      String x = "Hello";
		
      // The value of the variable is printed to the console 
      println(x);
   }
}

Khi chúng ta chạy chương trình trên, chúng ta sẽ nhận được kết quả sau:

Hello

Đặt tên biến

Tên của một biến có thể bao gồm các chữ cái, chữ số và ký tự gạch dưới. Nó phải bắt đầu bằng một chữ cái hoặc một dấu gạch dưới. Chữ hoa và chữ thường khác nhau vì Groovy, giống như Java là một ngôn ngữ lập trình phân biệt chữ hoa chữ thường.

class Example { 
   static void main(String[] args) { 
      // Defining a variable in lowercase  
      int x = 5;
	  
      // Defining a variable in uppercase  
      int X = 6; 
	  
      // Defining a variable with the underscore in it's name 
      def _Name = "Joe"; 
		
      println(x); 
      println(X); 
      println(_Name); 
   } 
}

Khi chúng ta chạy chương trình trên, chúng ta sẽ nhận được kết quả sau:

5 
6 
Joe

Chúng tôi có thể thấy điều đó xX là hai biến khác nhau vì phân biệt chữ hoa chữ thường và trong trường hợp thứ ba, chúng ta có thể thấy rằng _Name bắt đầu bằng dấu gạch dưới.

In các biến

Bạn có thể in giá trị hiện tại của một biến bằng hàm println. Ví dụ sau đây cho thấy điều này có thể đạt được như thế nào.

class Example { 
   static void main(String[] args) { 
      //Initializing 2 variables 
      int x = 5; 
      int X = 6; 
	  
      //Printing the value of the variables to the console 
      println("The value of x is " + x + "The value of X is " + X);  
   }
}

Khi chúng ta chạy chương trình trên, chúng ta sẽ nhận được kết quả sau:

The value of x is 5 The value of X is 6

Một toán tử là một ký hiệu yêu cầu trình biên dịch thực hiện các thao tác toán học hoặc logic cụ thể.

Groovy có các loại toán tử sau:

  • Toán tử số học
  • Toán tử quan hệ
  • Toán tử logic
  • Toán tử bitwise
  • Toán tử chuyển nhượng

Toán tử số học

Ngôn ngữ Groovy hỗ trợ các toán tử Số học bình thường như bất kỳ ngôn ngữ nào. Sau đây là các toán tử Số học có sẵn trong Groovy:

Hiển thị ví dụ

Nhà điều hành Sự miêu tả Thí dụ
+ Phép cộng hai toán hạng 1 + 2 sẽ cho 3
- Trừ toán hạng thứ hai với toán hạng đầu tiên 2 - 1 sẽ cho 1
* Phép nhân của cả hai toán hạng 2 * 2 sẽ cho 4
/ Chia tử số cho mẫu số 2/3 sẽ cho 1,5
% Toán tử mô đun và phần còn lại của sau một phép chia số nguyên / float 3% 2 sẽ cho 1
++ Toán tử tăng dần được sử dụng để tăng giá trị của một toán hạng lên 1

int x = 5;

x ++;

x sẽ cho 6

- Toán tử tăng dần được sử dụng để giảm giá trị của một toán hạng đi 1

int x = 5;

x--;

x sẽ cho 4

Toán tử quan hệ

Toán tử quan hệ cho phép so sánh các đối tượng. Sau đây là các toán tử quan hệ có sẵn trong Groovy:

Hiển thị ví dụ

Nhà điều hành Sự miêu tả Thí dụ
== Kiểm tra sự bằng nhau giữa hai đối tượng 2 == 2 sẽ cho đúng
! = Kiểm tra sự khác biệt giữa hai đối tượng 3! = 2 sẽ cho đúng
< Kiểm tra xem các đối tượng bên trái có nhỏ hơn toán hạng bên phải hay không. 2 <3 sẽ cho đúng
<= Kiểm tra xem các đối tượng bên trái nhỏ hơn hoặc bằng toán hạng bên phải hay không. 2 <= 3 sẽ cho đúng
> Kiểm tra xem các đối tượng bên trái có lớn hơn toán hạng bên phải hay không. 3> 2 sẽ cho đúng
> = Kiểm tra xem các đối tượng bên trái có lớn hơn hoặc bằng toán hạng bên phải hay không. 3> = 2 sẽ cho đúng

Toán tử logic

Các toán tử logic được sử dụng để đánh giá các biểu thức Boolean. Sau đây là các toán tử logic có sẵn trong Groovy:

Hiển thị ví dụ

Nhà điều hành Sự miêu tả Thí dụ
&& Đây là toán tử logic "và" true && true sẽ cho đúng
|| Đây là toán tử logic "hoặc" sự thật || đúng sẽ cho đúng
! Đây là toán tử logic "không phải" ! false sẽ cho true

Toán tử Bitwise

Groovy cung cấp bốn toán tử bitwise. Sau đây là các toán tử bitwise có sẵn trong Groovy:

Hiển thị ví dụ

Sr.No Nhà điều hành & Mô tả
1

&

Đây là toán tử "và" theo bitwise

2

|

Đây là toán tử "hoặc" theo bitwise

3

^

Đây là bitwise "xor" hoặc Exclusive hoặc toán tử

4

~

Đây là toán tử phủ định theo bit

Đây là bảng sự thật hiển thị các toán tử này.

p q p & q p | q p ^ q
0 0 0 0 0
0 1 0 1 1
1 1 1 1 0
1 0 0 1 1

Toán tử chuyển nhượng

Ngôn ngữ Groovy cũng cung cấp các toán tử gán. Sau đây là các toán tử gán có sẵn trong Groovy:

Hiển thị ví dụ

Nhà điều hành Sự miêu tả Thí dụ
+ = Điều này 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.

def A = 5

A + = 3

Đầu ra sẽ là 8

- = Điều này 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

def A = 5

A- = 3

Đầu ra sẽ là 2

* = Điều này 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

def A = 5

A * = 3

Đầu ra sẽ là 15

/ = Điều này 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

def A = 6

A / = 3

Đầu ra sẽ là 2

% = Điều này có mô-đun sử dụng hai toán hạng và gán kết quả cho toán hạng bên trái

def A = 5

A% = 3

Đầu ra sẽ là 2

Toán tử phạm vi

Groovy ủng hộ khái niệm phạm vi và cung cấp ký hiệu của các toán tử phạm vi với sự trợ giúp của ký hiệu ... Dưới đây là một ví dụ đơn giản về toán tử phạm vi.

def range = 0..5

Điều này chỉ xác định một phạm vi số nguyên đơn giản, được lưu trữ trong một biến cục bộ được gọi là phạm vi với giới hạn dưới là 0 và giới hạn trên là 5.

Đoạn mã sau đây cho thấy cách sử dụng các toán tử khác nhau.

class Example { 
   static void main(String[] args) { 
      def range = 5..10; 
      println(range); 
      println(range.get(2)); 
   } 
}

Khi chúng ta chạy chương trình trên, chúng ta sẽ nhận được kết quả sau:

Từ println , bạn có thể thấy rằng toàn bộ phạm vi số được xác định trong câu lệnh phạm vi được hiển thị.

Câu lệnh get được sử dụng để lấy một đối tượng từ phạm vi được xác định có giá trị chỉ mục làm tham số.

[5, 6, 7, 8, 9, 10] 
7

ưu tiên điều hành

Bảng sau đây liệt kê tất cả các toán tử linh hoạt theo thứ tự ưu tiên.

Sr.No Nhà điều hành & Tên
1

++ -- + -

tăng / giảm trước, cộng một bậc, trừ một bậc

2

* / %

nhân, div, modulo

3

+ -

cộng, trừ

4

== != <=>

bằng, không bằng, so sánh với

5

&

nhị phân / bitwise và

6

^

nhị phân / bitwise xor

7

|

nhị phân / bitwise hoặc

số 8

&&

logic và

9

||

logic hoặc

10

= **= *= /= %= += -= <<= >>= >>>= &= ^= |=

Các toán tử gán khác nhau

Cho đến nay, chúng ta đã thấy các câu lệnh được thực hiện lần lượt theo cách tuần tự. Ngoài ra, các câu lệnh được cung cấp trong Groovy để thay đổi luồng điều khiển trong logic của chương trình. Sau đó, chúng được phân loại thành luồng báo cáo kiểm soát mà chúng ta sẽ xem chi tiết.

Không. Tuyên bố & Mô tả
1 Tuyên bố While

Câu lệnh while được thực hiện trước tiên bằng cách đánh giá biểu thức điều kiện (một giá trị Boolean), và nếu kết quả là true, thì các câu lệnh trong vòng lặp while sẽ được thực thi.

2 cho Tuyên bố

Câu lệnh for được sử dụng để lặp qua một tập giá trị.

3 Tuyên bố for-in

Câu lệnh for-in được sử dụng để lặp qua một tập giá trị.

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

Không. Tuyên bố & Mô tả
1 Tuyên bố ngắt

Câu lệnh break được sử dụng để thay đổi luồng điều khiển bên trong các vòng lặp và câu lệnh switch.

2 Tiếp tục Tuyên bố

Câu lệnh continue bổ sung cho câu lệnh break. Việc sử dụng nó bị hạn chế đối với vòng lặp while và for.

Cấu trúc ra quyết định yêu cầu người lập trình chỉ định 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 thi nếu điều kiện đó được xác định là truevà tùy chọn, các câu lệnh khác sẽ được thực thi nếu điều kiện được xác định là false.

Sr.No. Tuyên bố & Mô tả
1 nếu Tuyên bố

Hoạt động chung của câu lệnh này là đầu tiên một điều kiện được đánh giá trong câu lệnh if. Nếu điều kiện là đúng, nó sẽ thực hiện các câu lệnh.

2 Câu lệnh if / else

Hoạt động chung của câu lệnh này là đầu tiên một điều kiện được đánh giá trong câu lệnh if. Nếu điều kiện đúng thì nó thực hiện các câu lệnh sau đó và dừng trước điều kiện khác và thoát ra khỏi vòng lặp. Nếu điều kiện là false thì nó sẽ thực thi các câu lệnh trong khối câu lệnh else và sau đó thoát khỏi vòng lặp.

3 Câu lệnh If lồng nhau

Đôi khi có một yêu cầu phải có nhiều câu lệnh if được nhúng bên trong nhau.

4 Chuyển đổi Tuyên bố

Đôi khi, câu lệnh if-else lồng nhau rất phổ biến và được sử dụng thường xuyên đến mức một câu lệnh dễ hơn được thiết kế gọi là câu lệnh switch.

5 Tuyên bố chuyển đổi lồng nhau

Cũng có thể có một tập hợp các câu lệnh switch lồng nhau.

Một phương thức trong Groovy được định nghĩa với kiểu trả về hoặc với deftừ khóa. Các phương thức có thể nhận bất kỳ số lượng đối số nào. Không cần thiết phải xác định rõ các kiểu khi xác định các đối số. Các bổ ngữ như public, private và protected có thể được thêm vào. Theo mặc định, nếu không có công cụ sửa đổi khả năng hiển thị nào được cung cấp, thì phương thức là công khai.

Loại đơn giản nhất của một phương thức là một phương thức không có tham số như hình bên dưới -

def methodName() { 
   //Method code 
}

Sau đây là một ví dụ về phương pháp đơn giản

class Example {
   static def DisplayName() {
      println("This is how methods work in groovy");
      println("This is an example of a simple method");
   } 
	
   static void main(String[] args) {
      DisplayName();
   } 
}

Trong ví dụ trên, DisplayName là một phương thức đơn giản bao gồm hai câu lệnh println được sử dụng để xuất một số văn bản ra bảng điều khiển. Trong phương thức main static của chúng tôi, chúng tôi chỉ gọi phương thức DisplayName. Kết quả của phương thức trên sẽ là:

This is how methods work in groovy 
This is an example of a simple method

Tham số phương pháp

Một phương thức thường hữu ích hơn nếu hành vi của nó được xác định bởi giá trị của một hoặc nhiều tham số. Chúng ta có thể chuyển các giá trị cho phương thức được gọi bằng cách sử dụng các tham số phương thức. Lưu ý rằng tên tham số phải khác nhau.

Loại đơn giản nhất của một phương thức với các tham số như hình dưới đây -

def methodName(parameter1, parameter2, parameter3) { 
   // Method code goes here 
}

Sau đây là một ví dụ về phương thức đơn giản với các tham số

class Example {
   static void sum(int a,int b) {
      int c = a+b;
      println(c);
   }  
	
   static void main(String[] args) {
      sum(10,5);
   } 
}

Trong ví dụ này, chúng tôi đang tạo một phương thức tổng với 2 tham số, ab. Cả hai tham số đều thuộc loạiint. Sau đó, chúng tôi đang gọi phương thức sum từ phương thức chính của chúng tôi và chuyển các giá trị cho các biếnab.

Đầu ra của phương thức trên sẽ là giá trị 15.

Tham số mặc định

Cũng có một điều khoản trong Groovy để chỉ định các giá trị mặc định cho các tham số trong các phương thức. Nếu không có giá trị nào được chuyển đến phương thức cho các tham số, thì các giá trị mặc định sẽ được sử dụng. Nếu cả hai tham số nondefault và default đều được sử dụng, thì phải lưu ý rằng các tham số mặc định phải được xác định ở cuối danh sách tham số.

Sau đây là một ví dụ về phương thức đơn giản với các tham số:

def someMethod(parameter1, parameter2 = 0, parameter3 = 0) { 
   // Method code goes here 
}

Hãy xem xét cùng một ví dụ mà chúng ta đã xem xét trước đây để cộng hai số và tạo một phương thức có một tham số mặc định và một tham số không mặc định khác -

class Example { 
   static void sum(int a,int b = 5) { 
      int c = a+b; 
      println(c); 
   } 
	
   static void main(String[] args) {
      sum(6); 
   } 
}

Trong ví dụ này, chúng tôi đang tạo một phương thức tính tổng với hai tham số, ab. Cả hai tham số đều có kiểu int. Sự khác biệt giữa ví dụ này và ví dụ trước là trong trường hợp này, chúng tôi đang chỉ định một giá trị mặc định chob là 5. Vì vậy, khi chúng ta gọi phương thức sum từ phương thức chính của mình, chúng ta có tùy chọn chỉ truyền một giá trị là 6 và giá trị này sẽ được gán cho tham số a trong sum phương pháp.

Đầu ra của phương thức trên sẽ là giá trị 11.

class Example {
   static void sum(int a,int b = 5) {
      int c = a+b;
      println(c);
   } 
	
   static void main(String[] args) {
      sum(6,6);
   } 
}

Chúng ta cũng có thể gọi phương thức sum bằng cách chuyển 2 giá trị, trong ví dụ của chúng ta ở trên, chúng ta đang chuyển 2 giá trị là 6. Giá trị thứ hai của 6 sẽ thực sự thay thế giá trị mặc định được gán cho tham số b.

Đầu ra của phương thức trên sẽ là giá trị 12.

Giá trị trả về phương pháp

Các phương thức cũng có thể trả về các giá trị cho chương trình đang gọi. Điều này được yêu cầu trong ngôn ngữ lập trình hiện đại, trong đó một phương thức thực hiện một số loại tính toán và sau đó trả về giá trị mong muốn cho phương thức gọi.

Sau đây là một ví dụ về phương thức đơn giản với giá trị trả về.

class Example {
   static int sum(int a,int b = 5) {
      int c = a+b;
      return c;
   } 
	
   static void main(String[] args) {
      println(sum(6));
   } 
}

Trong ví dụ trên của chúng tôi, hãy lưu ý rằng lần này chúng tôi đang chỉ định một kiểu trả về cho tổng phương thức của chúng tôi là kiểu int. Trong phương thức, chúng ta đang sử dụng câu lệnh return để gửi giá trị tổng đến chương trình chính đang gọi. Vì giá trị của phương thức hiện có sẵn cho phương thức chính, chúng tôi đang sử dụngprintln chức năng hiển thị giá trị trong giao diện điều khiển.

Đầu ra của phương thức trên sẽ là giá trị 11.

Phương pháp phiên bản

Các phương thức thường được triển khai bên trong các lớp bên trong Groovy giống như ngôn ngữ Java. Một lớp không là gì ngoài một bản thiết kế hoặc một khuôn mẫu để tạo các đối tượng khác nhau, định nghĩa các thuộc tính và hành vi của nó. Các đối tượng của lớp thể hiện các thuộc tính và hành vi được định nghĩa bởi lớp của nó. Vì vậy, các hành vi được xác định bằng cách tạo các phương thức bên trong lớp.

Chúng ta sẽ xem các lớp chi tiết hơn trong chương sau nhưng Sau đây là một ví dụ về việc triển khai phương thức trong một lớp. Trong các ví dụ trước, chúng tôi đã định nghĩa phương thức của mình là các phương thức tĩnh, nghĩa là chúng ta có thể truy cập các phương thức đó trực tiếp từ lớp. Ví dụ tiếp theo về các phương thức là các phương thức thể hiện trong đó các phương thức được truy cập bằng cách tạo các đối tượng của lớp. Một lần nữa chúng ta sẽ thấy các lớp trong chương sau, bây giờ chúng ta sẽ trình bày cách sử dụng các phương thức.

Sau đây là một ví dụ về cách các phương pháp có thể được thực hiện.

class Example { 
   int x; 
	
   public int getX() { 
      return x; 
   } 
	
   public void setX(int pX) { 
      x = pX; 
   } 
	
   static void main(String[] args) { 
      Example ex = new Example(); 
      ex.setX(100); 
      println(ex.getX()); 
   } 
}

Trong ví dụ trên của chúng tôi, lưu ý rằng lần này chúng tôi đang chỉ định không có thuộc tính tĩnh nào cho các phương thức lớp của chúng tôi. Trong hàm chính của chúng ta, chúng ta thực sự đang tạo một thể hiện của lớp Ví dụ và sau đó gọi phương thức của đối tượng 'ex'.

Đầu ra của phương thức trên sẽ là giá trị 100.

Tên tham số cục bộ và bên ngoài

Groovy cung cấp cơ sở giống như java để có các tham số cục bộ và toàn cục. Trong ví dụ sau,lx là một tham số cục bộ có phạm vi chỉ trong chức năng của getX()xlà một thuộc tính toàn cục có thể được truy cập bên trong toàn bộ lớp Ví dụ. Nếu chúng tôi cố gắng truy cập vào biếnlx bên ngoài getX() , chúng ta sẽ gặp lỗi.

class Example { 
   static int x = 100; 
	
   public static int getX() { 
      int lx = 200; 
      println(lx); 
      return x; 
   } 
	
   static void main(String[] args) { 
      println(getX()); 
   }  
}

Khi chạy chương trình trên, chúng ta sẽ nhận được kết quả như sau.

200 
100

phương pháp này cho Thuộc tính

Cũng giống như trong Java, groovy có thể truy cập các thành viên phiên bản của nó bằng cách sử dụng thistừ khóa. Ví dụ sau cho thấy cách chúng ta sử dụng câu lệnhthis.x, nó tham chiếu đến phiên bản của nó và đặt giá trị của x cho phù hợp.

class Example { 
   int x = 100; 
	
   public int getX() { 
      this.x = 200; 
      return x; 
   } 
	
   static void main(String[] args) {
      Example ex = new Example(); 
      println(ex.getX());
   }
}

Khi chạy chương trình trên, chúng ta sẽ nhận được kết quả là 200 được in trên console.

Groovy cung cấp một số phương thức trợ giúp khi làm việc với I / O. Groovy cung cấp các lớp dễ dàng hơn để cung cấp các chức năng sau cho tệp.

  • Đọc tệp
  • Ghi vào tệp
  • Duyệt cây tệp
  • Đọc và ghi các đối tượng dữ liệu vào tệp

Ngoài ra, bạn luôn có thể sử dụng các lớp Java bình thường được liệt kê bên dưới cho các hoạt động vào / ra tệp.

  • java.io.File
  • java.io.InputStream
  • java.io.OutputStream
  • java.io.Reader
  • java.io.Writer

Đọc tệp

Ví dụ sau sẽ xuất tất cả các dòng của tệp văn bản trong Groovy. Phương phápeachLine được tích hợp sẵn trong lớp Tệp trong Groovy với mục đích đảm bảo rằng mỗi dòng của tệp văn bản đều được đọc.

import java.io.File 
class Example { 
   static void main(String[] args) { 
      new File("E:/Example.txt").eachLine {  
         line -> println "line : $line"; 
      } 
   } 
}

Lớp Tệp được sử dụng để khởi tạo một đối tượng mới lấy tên tệp làm tham số. Sau đó, nó lấy chức năng của eachLine, đặt nó vào một biến được gọi là dòng và in ra tương ứng.

Nếu tệp chứa các dòng sau, chúng sẽ được in.

line : Example1
line : Example2

Đọc nội dung của tệp dưới dạng toàn bộ chuỗi

Nếu bạn muốn lấy toàn bộ nội dung của tệp dưới dạng chuỗi, bạn có thể sử dụng thuộc tính văn bản của lớp tệp. Ví dụ sau đây cho thấy cách này có thể được thực hiện.

class Example { 
   static void main(String[] args) { 
      File file = new File("E:/Example.txt") 
      println file.text 
   } 
}

Nếu tệp chứa các dòng sau, chúng sẽ được in.

line : Example1 
line : Example2

Ghi vào tệp

Nếu bạn muốn ghi vào tệp, bạn cần sử dụng lớp nhà văn để xuất văn bản ra tệp. Ví dụ sau đây cho thấy cách này có thể được thực hiện.

import java.io.File 
class Example { 
   static void main(String[] args) { 
      new File('E:/','Example.txt').withWriter('utf-8') { 
         writer -> writer.writeLine 'Hello World' 
      }  
   } 
}

Nếu bạn mở tệp Example.txt, bạn sẽ thấy dòng chữ “Hello World” được in trong tệp.

Nhận kích thước của tệp

Nếu bạn muốn lấy kích thước của tệp, người ta có thể sử dụng thuộc tính length của lớp tệp để lấy kích thước của tệp. Ví dụ sau đây cho thấy cách này có thể được thực hiện.

class Example {
   static void main(String[] args) {
      File file = new File("E:/Example.txt")
      println "The file ${file.absolutePath} has ${file.length()} bytes"
   } 
}

Đoạn mã trên sẽ hiển thị kích thước của tệp tính bằng byte.

Kiểm tra xem tệp có phải là thư mục không

Nếu bạn muốn xem đường dẫn là tệp hay thư mục, người ta có thể sử dụng isFileisDirectorytùy chọn của lớp Tệp. Ví dụ sau đây cho thấy cách này có thể được thực hiện.

class Example { 
   static void main(String[] args) { 
      def file = new File('E:/') 
      println "File? ${file.isFile()}" 
      println "Directory? ${file.isDirectory()}" 
   } 
}

Đoạn mã trên sẽ hiển thị kết quả sau:

File? false 
Directory? True

Tạo một thư mục

Nếu bạn muốn tạo một thư mục mới, bạn có thể sử dụng mkdirchức năng của lớp Tệp. Ví dụ sau đây cho thấy cách này có thể được thực hiện.

class Example {
   static void main(String[] args) {
      def file = new File('E:/Directory')
      file.mkdir()
   } 
}

Thư mục E: \ Directory sẽ được tạo nếu nó không tồn tại.

Xóa tệp

Nếu bạn muốn xóa một tệp, bạn có thể sử dụng chức năng xóa của lớp Tệp. Ví dụ sau đây cho thấy cách này có thể được thực hiện.

class Example {
   static void main(String[] args) {
      def file = new File('E:/Example.txt')
      file.delete()
   } 
}

Tệp sẽ bị xóa nếu nó tồn tại.

Sao chép các tập tin

Groovy cũng cung cấp chức năng sao chép nội dung từ tệp này sang tệp khác. Ví dụ sau đây cho thấy cách này có thể được thực hiện.

class Example {
   static void main(String[] args) {
      def src = new File("E:/Example.txt")
      def dst = new File("E:/Example1.txt")
      dst << src.text
   } 
}

Tệp Example1.txt sẽ được tạo và tất cả nội dung của tệp Example.txt sẽ được sao chép vào tệp này.

Lấy nội dung thư mục

Groovy cũng cung cấp chức năng liệt kê các ổ đĩa và tệp trong một ổ đĩa.

Ví dụ sau cho thấy cách các ổ đĩa trên máy có thể được hiển thị bằng cách sử dụng listRoots chức năng của lớp Tệp.

class Example { 
   static void main(String[] args) { 
      def rootFiles = new File("test").listRoots() 
      rootFiles.each { 
         file -> println file.absolutePath 
      }
   }
}

Tùy thuộc vào ổ đĩa có sẵn trên máy của bạn, đầu ra có thể khác nhau. Trên máy tiêu chuẩn, đầu ra sẽ tương tự như sau:

C:\ 
D:\

Ví dụ sau đây cho thấy cách liệt kê các tệp trong một thư mục cụ thể bằng cách sử dụng eachFile chức năng của lớp Tệp.

class Example {
   static void main(String[] args) {
      new File("E:/Temp").eachFile() {  
         file->println file.getAbsolutePath()
      }
   } 
}

Đầu ra sẽ hiển thị tất cả các tệp trong thư mục E: \ Temp

Nếu bạn muốn hiển thị đệ quy tất cả các tệp trong một thư mục và các thư mục con của nó, thì bạn sẽ sử dụng eachFileRecursechức năng của lớp Tệp. Ví dụ sau đây cho thấy cách này có thể được thực hiện.

class Example { 
   static void main(String[] args) {
      new File("E:/temp").eachFileRecurse() {
         file -> println file.getAbsolutePath()
      }
   }
}

Đầu ra sẽ hiển thị tất cả các tệp trong thư mục E: \ Temp và trong các thư mục con của nó nếu chúng tồn tại.

Groovy là một ngôn ngữ được gõ "tùy chọn" và sự phân biệt đó là một điều quan trọng khi hiểu các nguyên tắc cơ bản của ngôn ngữ. Khi so sánh với Java, là một ngôn ngữ được đánh máy “mạnh mẽ”, theo đó trình biên dịch biết tất cả các kiểu cho mọi biến và có thể hiểu và tuân theo các hợp đồng tại thời điểm biên dịch. Điều này có nghĩa là các cuộc gọi phương thức có thể được xác định tại thời điểm biên dịch.

Khi viết mã trong Groovy, các nhà phát triển có thể linh hoạt cung cấp một loại hoặc không. Điều này có thể cung cấp một số đơn giản trong việc triển khai và, khi được tận dụng đúng cách, có thể phục vụ ứng dụng của bạn một cách mạnh mẽ và năng động.

Trong Groovy, việc nhập tùy chọn được thực hiện thông qua từ khóa 'def'. Sau đây là một ví dụ về việc sử dụngdef phương pháp -

class Example { 
   static void main(String[] args) { 
      // Example of an Integer using def 
      def a = 100; 
      println(a); 
		
      // Example of an float using def 
      def b = 100.10; 
      println(b); 
		
      // Example of an Double using def 
      def c = 100.101; 
      println(c);
		
      // Example of an String using def 
      def d = "HelloWorld"; 
      println(d); 
   } 
}

Từ chương trình trên, chúng ta có thể thấy rằng chúng ta đã không khai báo các biến riêng lẻ là Integer, float, double, hoặc string mặc dù chúng chứa các loại giá trị này.

Khi chúng ta chạy chương trình trên, chúng ta sẽ nhận được kết quả sau:

100 
100.10 
100.101
HelloWorld

Nhập tùy chọn có thể là một tiện ích mạnh mẽ trong quá trình phát triển, nhưng có thể dẫn đến các vấn đề về khả năng bảo trì trong giai đoạn phát triển sau này khi mã trở nên quá rộng và phức tạp.

Để nắm được cách bạn có thể sử dụng tính năng nhập tùy chọn trong Groovy mà không khiến cơ sở mã của bạn rơi vào một mớ hỗn độn không thể giải thích được, tốt nhất là bạn nên nắm lấy triết lý “gõ vịt” trong ứng dụng của mình.

Nếu chúng ta viết lại đoạn mã trên bằng cách sử dụng kiểu gõ vịt, nó sẽ giống như đoạn mã được đưa ra bên dưới. Các tên biến là những tên thường giống với loại mà chúng đại diện hơn, điều này làm cho mã dễ hiểu hơn.

class Example { 
   static void main(String[] args) { 
      // Example of an Integer using def 
      def aint = 100; 
      println(aint); 
		
      // Example of an float using def 
      def bfloat = 100.10; 
      println(bfloat); 
		
      // Example of an Double using def 
      def cDouble = 100.101; 
      println(cDouble);
		
      // Example of an String using def 
      def dString = "HelloWorld"; 
      println(dString); 
   } 
}

Trong Groovy, Numbers thực sự được biểu diễn dưới dạng đối tượng, tất cả chúng đều là một thể hiện của lớp Integer. Để thực hiện một đối tượng nào đó, chúng ta cần gọi một trong các phương thức được khai báo trong lớp của nó.

Groovy hỗ trợ số nguyên và số dấu phẩy động.

  • Một số nguyên là một giá trị không bao gồm một phân số.
  • Số dấu phẩy động là một giá trị thập phân bao gồm một phân số thập phân.

Ví dụ về các số trong Groovy được hiển thị bên dưới:

Integer x = 5; 
Float y = 1.25;

Ở đâu x thuộc loại Số nguyên và y là cái phao.

Lý do tại sao các số trong groovy được định nghĩa là các đối tượng nói chung là vì có các yêu cầu để thực hiện các phép toán trên các số. Khái niệm cung cấp một lớp trên các kiểu nguyên thủy được gọi là các lớp trình bao bọc.

Theo mặc định, các lớp trình bao bọc sau được cung cấp trong Groovy.

Đố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ó. Quá trình chuyển đổi một 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. Quá trình chuyển đổi đối tượng trở lại kiểu nguyên thủy tương ứng của nó được gọi là unboxing.

Thí dụ

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

class Example { 
   static void main(String[] args) {
      Integer x = 5,y = 10,z = 0; 
		
      // The the values of 5,10 and 0 are boxed into Integer types 
      // The values of x and y are unboxed and the addition is performed 
      z = x+y; 
      println(z);
   }
}

Đầu ra của chương trình trên sẽ là 15. Trong ví dụ trên, các giá trị của 5, 10 và 0 lần đầu tiên được đóng hộp vào các biến Số nguyên x, y và z tương ứng. Và sau đó khi phép cộng x và y được thực hiện, các giá trị sẽ được mở hộp khỏi các loại Số nguyên của chúng.

Phương pháp số

Vì các Số trong Groovy được biểu diễn dưới dạng các lớp, sau đây là danh sách các phương thức có sẵn.

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

Phương thức này nhận Number làm tham số và trả về kiểu nguyên thủy dựa trên phương thức được gọi.

2 so với()

Phương pháp CompareTo là sử dụng so sánh một số với một số khác. Điều này rất hữu ích nếu bạn muốn so sánh giá trị của các số.

3 bằng ()

Phương thức xác định xem đối tượng Number gọi phương thức có bằng đối tượng được truyền dưới dạng đối số hay không.

4 giá trị của()

Phương thức valueOf trả về Đối tượng Số có liên quan giữ giá trị của đối số được truyền vào.

5 toString ()

Phương thức được sử dụng để lấy một đối tượng Chuỗi đại diện cho giá trị của Đối tượng Số.

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 đó. parseXxx () là một phương thức tĩnh và có thể có một hoặc hai đối số.

7 abs ()

Phương thức cung cấp giá trị tuyệt đối của đối số. Đối số có thể là int, float, long, double, short, byte.

số 8 ceil ()

Phương thức ceil cho số nguyên nhỏ nhất lớn hơn hoặc bằng đối số.

9 sàn nhà()

Tầng phương thức cho số nguyên lớn nhất nhỏ hơn hoặc bằng đối số.

10 rint ()

Phương thức rint trả về số nguyên có giá trị gần nhất với đối số.

11 tròn()

Vòng phương thức trả về long hoặc int gần nhất, như được cung cấp bởi kiểu trả về của phương thức.

12 min ()

Phương thức cho giá trị nhỏ hơn trong hai đối số. Đối số có thể là int, float, long, double.

13 max ()

Phương thức này cung cấp tối đa hai đối số. Đối số có thể là int, float, long, double.

14 exp ()

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

15 log ()

Phương thức này trả về lôgarit tự nhiên của đối số.

16 pow ()

Phương thức 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 ()

Phương thức trả về căn bậc hai của đối số.

18 tội()

Phương thức trả về sin của giá trị kép được chỉ định.

19 cos ()

Phương thức trả về cosine của giá trị kép được chỉ định.

20 tan ()

Phương thức trả về tiếp tuyến của giá trị kép được chỉ định.

21 asin ()

Phương thức trả về arcsine của giá trị kép được chỉ định.

22 acos ()

Phương thức trả về arccosine của giá trị kép được chỉ định.

23 atan ()

Phương thức trả về arctangent của giá trị kép được chỉ định.

24 atan2 ()

Phương thức 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 ()

Phương thức chuyển đổi giá trị đối số thành độ.

26 radian ()

Phương thức chuyển đổi giá trị đối số thành radian.

27 ngẫu nhiên ()

Phương pháp này được sử dụng để tạo ra một số ngẫu nhiên từ 0,0 đến 1,0. Phạm vi là: 0.0 = <Math.random <1.0. Các phạm vi khác nhau có thể đạt được bằng cách sử dụng số học.

Một chuỗi ký tự được xây dựng trong Groovy bằng cách đặt văn bản chuỗi trong dấu ngoặc kép.

Groovy cung cấp nhiều cách khác nhau để biểu thị một chuỗi ký tự. Các chuỗi trong Groovy có thể được đặt trong dấu ngoặc kép ('), dấu ngoặc kép (“) hoặc dấu ngoặc kép (“ ””). Hơn nữa, một Chuỗi Groovy được bao bởi ba dấu ngoặc kép có thể kéo dài nhiều dòng.

Sau đây là một ví dụ về cách sử dụng chuỗi trong Groovy:

class Example { 
   static void main(String[] args) { 
      String a = 'Hello Single'; 
      String b = "Hello Double"; 
      String c = "'Hello Triple" + "Multiple lines'";
		
      println(a); 
      println(b); 
      println(c); 
   } 
}

Khi chúng ta chạy chương trình trên, chúng ta sẽ nhận được kết quả sau:

Hello Single 
Hello Double 
'Hello TripleMultiple lines'

Lập chỉ mục chuỗi

Các chuỗi trong Groovy là một chuỗi các ký tự có thứ tự. Ký tự riêng lẻ trong một chuỗi có thể được truy cập theo vị trí của nó. Điều này được đưa ra bởi một vị trí chỉ mục.

Các chỉ số chuỗi bắt đầu từ 0 và kết thúc ở một nhỏ hơn độ dài của chuỗi. Groovy cũng cho phép các chỉ số âm đếm ngược từ cuối chuỗi.

Sau đây là một ví dụ về việc sử dụng lập chỉ mục chuỗi trong Groovy:

class Example { 
   static void main(String[] args) { 
      String sample = "Hello world"; 
      println(sample[4]); // Print the 5 character in the string
		
      //Print the 1st character in the string starting from the back 
      println(sample[-1]); 
      println(sample[1..2]);//Prints a string starting from Index 1 to 2 
      println(sample[4..2]);//Prints a string starting from Index 4 back to 2 
      
   } 
}

Khi chúng ta chạy chương trình trên, chúng ta sẽ nhận được kết quả sau:

o 
d 
el 
oll

Hoạt động chuỗi cơ bản

Đầu tiên chúng ta hãy tìm hiểu các phép toán chuỗi cơ bản trong groovy. Chúng được đưa ra dưới đây.

Không. Hoạt động và mô tả chuỗi
1 Kết nối của hai chuỗi

Việc nối các chuỗi có thể được thực hiện bằng toán tử '+' đơn giản.

2 Lặp lại chuỗi

Việc lặp lại các chuỗi có thể được thực hiện bằng toán tử '*' đơn giản.

3 Chiều dài chuỗi

Độ dài của chuỗi được xác định bởi phương thức length () của chuỗi.

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.

Không. Phương pháp & Mô tả
1 trung tâm()

Trả về một Chuỗi có độ dài numberOfChars mới bao gồm người nhận được đệm ở bên trái và bên phải bằng các ký tự khoảng trắng.

2 so sánhToIgnoreCase ()

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.

3 concat ()

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

4 eachMatch ()

Xử lý từng nhóm regex (xem phần tiếp theo) chuỗi con phù hợp của Chuỗi đã cho.

5 endWith ()

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

6 equalsIgnoreCase ()

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.

7 nhận được ở()

Nó trả về giá trị chuỗi ở vị trí chỉ mục

số 8 Chỉ số()

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.

9 diêm()

Nó xuất ra liệu một Chuỗi có khớp với biểu thức chính quy đã cho hay không.

10 dấu trừ()

Loại bỏ phần giá trị của chuỗi.

11 kế tiếp()

Phương thức này được gọi bởi toán tử ++ cho lớp String. Nó tăng ký tự cuối cùng trong Chuỗi đã cho.

12 padLeft ()

Đặt chuỗi bằng các khoảng trắng được nối vào bên trái.

13 padRight ()

Đặt chuỗi bằng các khoảng trắng được nối vào bên phải.

14 thêm()

Thêm một chuỗi

15 Trước()

Phương thức này được gọi bởi toán tử - cho CharSequence.

16 thay thế tất cả()

Thay thế tất cả các lần xuất hiện của một nhóm bị bắt bằng kết quả của việc đóng trên văn bản đó.

17 đảo ngược()

Tạo một Chuỗi mới, ngược lại với Chuỗi này.

18 tách ()

Tách Chuỗi này xung quanh các trận đấu của biểu thức chính quy đã cho.

19 chuỗi con ()

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

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

Chuyển đổi tất cả các ký tự trong Chuỗi này thành chữ hoa.

21 toLowerCase ()

Chuyển đổi tất cả các ký tự trong Chuỗi này thành chữ thường.

Một phạm vi là viết tắt để chỉ định một chuỗi giá trị. Phạm vi được biểu thị bằng giá trị đầu tiên và giá trị cuối cùng trong chuỗi và Phạm vi có thể bao gồm hoặc loại trừ. Một Phạm vi bao gồm bao gồm tất cả các giá trị từ giá trị đầu tiên đến cuối cùng, trong khi Phạm vi độc quyền bao gồm tất cả các giá trị ngoại trừ giá trị cuối cùng. Dưới đây là một số ví dụ về các ký tự của Range -

  • 1..10 - Ví dụ về Phạm vi bao gồm
  • 1 .. <10 - Ví dụ về Phạm vi độc quyền
  • 'a' .. 'x' - Dải ô cũng có thể bao gồm các ký tự
  • 10..1 - Các phạm vi cũng có thể theo thứ tự giảm dần
  • 'x' .. 'a' - Các dải ô cũng có thể bao gồm các ký tự và theo thứ tự giảm dần.

Sau đây là các phương pháp khác nhau có sẵn cho phạm vi.

Sr.No. Phương pháp & Mô tả
1 chứa đựng()

Kiểm tra xem một phạm vi có chứa một giá trị cụ thể hay không

2 được()

Trả về phần tử ở vị trí được chỉ định trong Phạm vi này.

3 nhận được từ()

Nhận giá trị thấp hơn của Phạm vi này.

4 getTo ()

Nhận giá trị trên của Phạm vi này.

5 isReverse ()

Đây có phải là một Phạm vi đã đảo ngược, lặp lại

6 kích thước()

Trả về số phần tử trong Phạm vi này.

7 subList ()

Trả về chế độ xem phần của Phạm vi này giữa fromIndex được chỉ định, bao gồm và toIndex, loại trừ

Danh sách là một cấu trúc được sử dụng để lưu trữ một tập hợp các mục dữ liệu. Trong Groovy, Danh sách chứa một chuỗi các tham chiếu đối tượng. Các tham chiếu đối tượng trong một Danh sách chiếm một vị trí trong chuỗi và được phân biệt bằng một chỉ số nguyên. Một ký tự Danh sách được trình bày dưới dạng một loạt các đối tượng được phân tách bằng dấu phẩy và được đặt trong dấu ngoặc vuông.

Để xử lý dữ liệu trong một danh sách, chúng ta phải có thể truy cập các phần tử riêng lẻ. Groovy Danh sách được lập chỉ mục bằng cách sử dụng toán tử lập chỉ mục []. Danh sách các chỉ mục bắt đầu từ 0, tham chiếu đến phần tử đầu tiên.

Sau đây là một số ví dụ về danh sách -

  • [11, 12, 13, 14] - Danh sách các giá trị nguyên
  • ['Angular', 'Groovy', 'Java'] - Danh sách các chuỗi
  • [1, 2, [3, 4], 5] - Danh sách lồng nhau
  • ['Groovy', 21, 2.11] - Danh sách tham chiếu đối tượng không đồng nhất
  • [] - Một danh sách trống

Trong chương này, chúng ta sẽ thảo luận về các phương pháp danh sách có sẵn trong Groovy.

Sr.No. Phương pháp & Mô tả
1 thêm vào()

Nối giá trị mới vào cuối Danh sách này.

2 chứa đựng()

Trả về true nếu Danh sách này chứa giá trị được chỉ định.

3 được()

Trả về phần tử ở vị trí đã chỉ định trong Danh sách này.

4 isEmpty ()

Trả về true nếu Danh sách này không chứa phần tử

5 dấu trừ()

Tạo Danh sách mới bao gồm các phần tử của bản gốc mà không có những phần tử được chỉ định trong bộ sưu tập.

6 thêm()

Tạo Danh sách mới bao gồm các phần tử của bản gốc cùng với các phần tử được chỉ định trong bộ sưu tập.

7 pop ()

Xóa mục cuối cùng khỏi Danh sách này

số 8 tẩy()

Loại bỏ phần tử ở vị trí được chỉ định trong Danh sách này.

9 đảo ngược()

Tạo một Danh sách mới đảo ngược các phần tử của Danh sách ban đầu

10 kích thước()

Lấy số phần tử trong Danh sách này.

11 sắp xếp ()

Trả về bản sao đã sắp xếp của Danh sách ban đầu.

Bản đồ (còn được gọi là mảng kết hợp, từ điển, bảng và băm) là một tập hợp các tham chiếu đối tượng không có thứ tự. Các phần tử trong tập hợp Bản đồ được truy cập bằng một giá trị khóa. Các khóa được sử dụng trong Bản đồ có thể thuộc bất kỳ lớp nào. Khi chúng tôi chèn vào bộ sưu tập Bản đồ, hai giá trị được yêu cầu: khóa và giá trị.

Sau đây là một số ví dụ về bản đồ -

  • ['Tên chủ đề': 'Danh sách', 'Tên chủ đề': 'Bản đồ'] - Tập hợp các cặp giá trị khóa có Tên chủ đề làm khóa và các giá trị tương ứng của chúng.

  • [:] - Bản đồ trống.

Trong chương này, chúng ta sẽ thảo luận về các phương pháp bản đồ có sẵn trong Groovy.

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

Bản đồ này có chứa khóa này không?

2 được()

Tra cứu khóa trong Bản đồ này và trả về giá trị tương ứng. Nếu không có mục nhập nào trong Bản đồ này cho khóa, thì trả về null.

3 bộ chìa khoá()

Nhận Bộ chìa khóa trong Bản đồ này.

4 đặt()

Liên kết giá trị được chỉ định với khóa được chỉ định trong Bản đồ này. Nếu Bản đồ này trước đó chứa một ánh xạ cho khóa này, giá trị cũ sẽ được thay thế bằng giá trị được chỉ định.

5 kích thước()

Trả về số lượng ánh xạ khóa-giá trị trong Bản đồ này.

6 giá trị ()

Trả về chế độ xem tập hợp của các giá trị có trong Bản đồ này.

Lớp Date đại diện cho một thời điểm cụ thể trong thời gian, với độ chính xác mili giây. Lớp Date có hai hàm tạo như hình dưới đây.

Ngày()

Cú pháp

public Date()

Parameters - Không.

Return Value

Phân bổ một đối tượng Date và khởi tạo nó để nó đại diện cho thời gian mà nó được phân bổ, được đo chính xác đến từng mili giây.

Thí dụ

Sau đây là một ví dụ về việc sử dụng phương pháp này:

class Example { 
   static void main(String[] args) { 
      Date date = new Date(); 
      
      // display time and date using toString() 
      System.out.println(date.toString()); 
   } 
}

Khi chạy chương trình trên, chúng ta sẽ nhận được kết quả như sau. Kết quả sau sẽ cung cấp cho bạn ngày và giờ hiện tại -

Thu Dec 10 21:31:15 GST 2015

Ngày (mili giây dài)

Cú pháp

public Date(long millisec)

Parameters

Millisec - Số mili giây cần chỉ định kể từ thời gian gốc tiêu chuẩn.

Return Value - Phân bổ a Date và khởi tạo nó để đại diện cho số mili giây được chỉ định kể từ thời gian gốc chuẩn được gọi là "kỷ nguyên", cụ thể là ngày 1 tháng 1 năm 1970, 00:00:00 GMT.

Thí dụ

Sau đây là một ví dụ về việc sử dụng phương pháp này:

class Example {
   static void main(String[] args) {
      Date date = new Date(100);
      
      // display time and date using toString()
      System.out.println(date.toString());
   } 
}

Khi chúng ta chạy chương trình trên, chúng ta sẽ nhận được kết quả sau:

Thu Jan 01 04:00:00 GST 1970

Sau đây là các phương thức đã cho của lớp Date. Trong tất cả các phương thức của lớp Date chấp nhận hoặc trả về các giá trị năm, tháng, ngày, giờ, phút và giây, các biểu diễn sau được sử dụng:

  • Một năm y được biểu thị bằng số nguyên y - 1900.

  • Một tháng được biểu thị bằng một số nguyên từ 0 đến 11; 0 là tháng Giêng, 1 là tháng Hai, v.v.; do đó 11 là tháng mười hai.

  • Ngày (ngày trong tháng) được biểu diễn bằng một số nguyên từ 1 đến 31 theo cách thông thường.

  • Một giờ được biểu diễn bằng một số nguyên từ 0 đến 23. Như vậy, giờ từ nửa đêm đến 1 giờ sáng là giờ 0, và giờ từ trưa đến 1 giờ chiều là giờ 12.

  • Một phút được biểu diễn bằng một số nguyên từ 0 đến 59 theo cách thông thường.

  • Một giây được biểu diễn bằng một số nguyên từ 0 đến 61.

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

Kiểm tra xem ngày này có sau ngày được chỉ định không.

2 bằng ()

So sánh hai ngày cho bằng nhau. Kết quả là true nếu và chỉ khi đối số không rỗng và là một đối tượng Date đại diện cho cùng một thời điểm, tính đến phần nghìn giây, như đối tượng này.

3 so với()

So sánh hai Ngày đặt hàng.

4 toString ()

Chuyển đổi đối tượng Ngày này thành Chuỗi

5 trước()

Kiểm tra xem ngày này có trước ngày được chỉ định hay không.

6 dành thời gian()

Trả về số mili giây kể từ ngày 1 tháng 1 năm 1970, 00:00:00 GMT được đại diện bởi đối tượng Ngày này.

7 cài đặt thời gian()

Đặt đối tượng Ngày này để đại diện cho một điểm theo thời gian là mili giây sau ngày 1 tháng 1 năm 1970 00:00:00 GMT.

Biểu thức chính quy là một mẫu được sử dụng để tìm các chuỗi con trong văn bản. Groovy hỗ trợ biểu thức chính quy nguyên bản bằng cách sử dụng biểu thức ~ ”regex”. Văn bản kèm theo trong phần trích dẫn thể hiện biểu thức để so sánh.

Ví dụ, chúng ta có thể tạo một đối tượng biểu thức chính quy như hình dưới đây:

def regex = ~'Groovy'

Khi toán tử Groovy = ~ xuất hiện dưới dạng một vị từ (biểu thức trả về một Boolean) trong ifwhile(xem Chương 8), toán hạng chuỗi ở bên trái được so khớp với toán hạng biểu thức chính quy ở bên phải. Do đó, mỗi điều sau đây mang lại giá trị true.

Khi xác định biểu thức chính quy, các ký tự đặc biệt sau có thể được sử dụng:

  • Có hai ký tự vị trí đặc biệt được sử dụng để biểu thị đầu và cuối dòng: dấu mũ (∧) và dấu đô la ($).

  • Biểu thức chính quy cũng có thể bao gồm các bộ định lượng. Dấu cộng (+) đại diện cho một hoặc nhiều lần, được áp dụng cho phần tử đứng trước của biểu thức. Dấu hoa thị (*) được sử dụng để thể hiện không hoặc nhiều lần xuất hiện. Dấu chấm hỏi (?) Biểu thị không hoặc một lần.

  • Siêu ký tự {và} được sử dụng để đối sánh với một số trường hợp cụ thể của ký tự đứng trước.

  • Trong biểu thức chính quy, ký hiệu dấu chấm (.) Có thể đại diện cho bất kỳ ký tự nào. Đây được mô tả là ký tự đại diện.

  • Một biểu thức chính quy có thể bao gồm các lớp ký tự. Một tập hợp các ký tự có thể được cung cấp dưới dạng một chuỗi ký tự đơn giản được bao quanh trong siêu ký tự [và] như trong [aeiou]. Đối với phạm vi chữ cái hoặc số, bạn có thể sử dụng dấu gạch ngang như trong [a – z] hoặc [a – mA – M]. Phần bổ sung của một lớp ký tự được biểu thị bằng dấu mũ đứng đầu trong dấu ngoặc vuông như trong [∧a – z] và đại diện cho tất cả các ký tự khác với những ký tự được chỉ định. Dưới đây là một số ví dụ về Biểu thức chính quy

'Groovy' =~ 'Groovy' 
'Groovy' =~ 'oo' 
'Groovy' ==~ 'Groovy' 
'Groovy' ==~ 'oo' 
'Groovy' =~ '∧G' 
‘Groovy' =~ 'G$' 
‘Groovy' =~ 'Gro*vy' 'Groovy' =~ 'Gro{2}vy'

Xử lý ngoại lệ được yêu cầu trong bất kỳ ngôn ngữ lập trình nào để xử lý các lỗi thời gian chạy để có thể duy trì luồng ứng dụng bình thường.

Exception thường làm gián đoạn luồng thông thường của ứng dụng, đó là lý do tại sao chúng ta cần sử dụng xử lý Exception trong ứng dụng của mình.

Các trường hợp ngoại lệ được phân loại rộng rãi thành các loại sau:

  • Checked Exception - Các lớp mở rộng lớp Throwable ngoại trừ RuntimeException và Error được gọi là các ngoại lệ đã kiểm tra, ví dụ :IOException, SQLException, v.v. Các ngoại lệ đã kiểm tra được kiểm tra tại thời điểm biên dịch.

Một trường hợp cổ điển là FileNotFoundException. Giả sử bạn có đoạn mã sau trong ứng dụng của mình, mã này đọc từ một tệp trong ổ E.

class Example {
   static void main(String[] args) {
      File file = new File("E://file.txt");
      FileReader fr = new FileReader(file);
   } 
}

nếu Tệp (file.txt) không có trong ổ E thì ngoại lệ sau sẽ được đưa ra.

Caught: java.io.FileNotFoundException: E: \ file.txt (Hệ thống không thể tìm thấy tệp được chỉ định).

java.io.FileNotFoundException: E: \ file.txt (Hệ thống không thể tìm thấy tệp được chỉ định).

  • Unchecked Exception - Các lớp mở rộng RuntimeException được gọi là các ngoại lệ không được kiểm tra, ví dụ: ArithmeticException, NullPointerException, ArrayIndexOutOfBoundsException, v.v. Các ngoại lệ không được kiểm tra không được kiểm tra tại thời gian biên dịch thay vì chúng được kiểm tra trong thời gian chạy.

Một trường hợp cổ điển là ArrayIndexOutOfBoundsException xảy ra khi bạn cố gắng truy cập vào chỉ mục của một mảng lớn hơn độ dài của mảng. Sau đây là một ví dụ điển hình của loại sai lầm này.

class Example {
   static void main(String[] args) {
      def arr = new int[3];
      arr[5] = 5;
   } 
}

Khi đoạn mã trên được thực thi, ngoại lệ sau sẽ được đưa ra.

Bắt: java.lang.ArrayIndexOutOfBoundsException: 5

java.lang.ArrayIndexOutOfBoundsException: 5

  • Error - Lỗi không thể khôi phục được ví dụ OutOfMemoryError, VirtualMachineError, AssertionError, v.v.

Đây là những lỗi mà chương trình không bao giờ có thể khôi phục được và sẽ khiến chương trình bị sập.

Sơ đồ sau đây cho thấy cách tổ chức phân cấp các ngoại lệ trong Groovy. Tất cả đều dựa trên hệ thống phân cấp được định nghĩa trong Java.

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ệ.

try { 
   //Protected code 
} catch(ExceptionName e1) {
   //Catch block 
}

Tất cả mã của bạn có thể tạo ra một ngoại lệ được đặt trong khối mã được bảo vệ.

Trong khối bắt, bạn có thể viết mã tùy chỉnh để xử lý ngoại lệ của mình để ứng dụng có thể khôi phục từ ngoại lệ.

Hãy xem một ví dụ về đoạn mã tương tự mà chúng ta đã thấy ở trên để truy cập vào một mảng có giá trị chỉ mục lớn hơn kích thước của mảng. Nhưng lần này hãy gói mã của chúng ta trong một khối try / catch.

class Example {
   static void main(String[] args) {
      try {
         def arr = new int[3];
         arr[5] = 5;
      } catch(Exception ex) {
         println("Catching the exception");
      }
		
      println("Let's move on after the exception");
   }
}

Khi chúng ta chạy chương trình trên, chúng ta sẽ nhận được kết quả sau:

Catching the exception 
Let's move on after the exception

Từ mã trên, chúng tôi bọc mã bị lỗi trong khối thử. Trong khối bắt, chúng tôi chỉ bắt ngoại lệ của chúng tôi và xuất ra một thông báo rằng một ngoại lệ đã xảy ra.

Nhiều khối bắt

Người ta có thể có nhiều khối bắt để xử lý nhiều loại ngoại lệ. Đối với mỗi khối bắt, tùy thuộc vào loại ngoại lệ được nêu ra, bạn sẽ viết mã để xử lý nó cho phù hợp.

Hãy sửa đổi mã ở trên của chúng tôi để bắt ArrayIndexOutOfBoundsException cụ thể. Sau đây là đoạn mã.

class Example {
   static void main(String[] args) {
      try {
         def arr = new int[3];
         arr[5] = 5;
      }catch(ArrayIndexOutOfBoundsException ex) {
         println("Catching the Array out of Bounds exception");
      }catch(Exception ex) {
         println("Catching the exception");
      }
		
      println("Let's move on after the exception");
   } 
}

Khi chúng ta chạy chương trình trên, chúng ta sẽ nhận được kết quả sau:

Catching the Aray out of Bounds exception 
Let's move on after the exception

Từ đoạn mã trên, bạn có thể thấy rằng khối bắt ArrayIndexOutOfBoundsException được bắt trước vì nó có nghĩa là tiêu chí của ngoại lệ.

Cuối cùng là Chặn

Các finallykhối theo sau khối try hoặc khối catch. 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ệ. Cú pháp cho khối này được đưa ra dưới đây.

try { 
   //Protected code 
} catch(ExceptionType1 e1) { 
   //Catch block 
} catch(ExceptionType2 e2) { 
   //Catch block 
} catch(ExceptionType3 e3) { 
   //Catch block 
} finally {
   //The finally block always executes. 
}

Hãy sửa đổi mã ở trên của chúng tôi và thêm khối mã cuối cùng. Sau đây là đoạn mã.

class Example {
   static void main(String[] args) {
      try {
         def arr = new int[3];
         arr[5] = 5;
      } catch(ArrayIndexOutOfBoundsException ex) {
         println("Catching the Array out of Bounds exception");
      }catch(Exception ex) {
         println("Catching the exception");
      } finally {
         println("The final block");
      }
		
      println("Let's move on after the exception");
   } 
}

Khi chúng ta chạy chương trình trên, chúng ta sẽ nhận được kết quả sau:

Catching the Array out of Bounds exception 
The final block 
Let's move on after the exception

Sau đây là các phương pháp Ngoại lệ có sẵn trong Groovy:

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.

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.

public String toString ()

Trả về tên của lớp được nối với kết quả của getMessage ()

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.

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.

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.

Thí dụ

Sau đây là ví dụ mã sử dụng một số phương pháp được đưa ra ở trên:

class Example {
   static void main(String[] args) {
      try {
         def arr = new int[3];
         arr[5] = 5;
      }catch(ArrayIndexOutOfBoundsException ex) {
         println(ex.toString());
         println(ex.getMessage());
         println(ex.getStackTrace());  
      } catch(Exception ex) {
         println("Catching the exception");
      }finally {
         println("The final block");
      }
		
      println("Let's move on after the exception");
   } 
}

Khi chúng ta chạy chương trình trên, chúng ta sẽ nhận được kết quả sau:

java.lang.ArrayIndexOutOfBoundsException: 5 
5 
[org.codehaus.groovy.runtime.dgmimpl.arrays.IntegerArrayPutAtMetaMethod$MyPojoMetaMet 
hodSite.call(IntegerArrayPutAtMetaMethod.java:75), 
org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:48) ,
org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:113) ,
org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:133) ,
Example.main(Sample:8), sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method),
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57),
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ,
java.lang.reflect.Method.invoke(Method.java:606),
org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:93),
groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:325),
groovy.lang.MetaClassImpl.invokeStaticMethod(MetaClassImpl.java:1443),
org.codehaus.groovy.runtime.InvokerHelper.invokeMethod(InvokerHelper.java:893),
groovy.lang.GroovyShell.runScriptOrMainOrTestOrRunnable(GroovyShell.java:287),
groovy.lang.GroovyShell.run(GroovyShell.java:524),
groovy.lang.GroovyShell.run(GroovyShell.java:513),
groovy.ui.GroovyMain.processOnce(GroovyMain.java:652),
groovy.ui.GroovyMain.run(GroovyMain.java:384),
groovy.ui.GroovyMain.process(GroovyMain.java:370),
groovy.ui.GroovyMain.processArgs(GroovyMain.java:129),
groovy.ui.GroovyMain.main(GroovyMain.java:109),
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method),
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57),
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ,
java.lang.reflect.Method.invoke(Method.java:606),
org.codehaus.groovy.tools.GroovyStarter.rootLoader(GroovyStarter.java:109),
org.codehaus.groovy.tools.GroovyStarter.main(GroovyStarter.java:131),
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method),
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57),
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ,
java.lang.reflect.Method.invoke(Method.java:606),
com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)]
 
The final block 
Let's move on after the exception

Trong Groovy, cũng như trong bất kỳ ngôn ngữ hướng đối tượng nào khác, có khái niệm về các lớp và đối tượng để thể hiện bản chất hướng đối tượng của ngôn ngữ lập trình. Lớp Groovy là một tập hợp dữ liệu và các phương thức hoạt động trên dữ liệu đó. Cùng nhau, dữ liệu và phương thức của một lớp được sử dụng để biểu diễn một số đối tượng thế giới thực từ miền vấn đề.

Một lớp trong Groovy khai báo trạng thái (dữ liệu) và hành vi của các đối tượng được định nghĩa bởi lớp đó. Do đó, một lớp Groovy mô tả cả các trường cá thể và các phương thức cho lớp đó.

Sau đây là một ví dụ về một lớp học ở Groovy. Tên của lớp là Sinh viên có hai trường:StudentIDStudentName. Trong hàm main, chúng ta đang tạo một đối tượng của lớp này và gán giá trị choStudentIDStudentName của đối tượng.

class Student {
   int StudentID;
   String StudentName;
	
   static void main(String[] args) {
      Student st = new Student();
      st.StudentID = 1;
      st.StudentName = "Joe"     
   } 
}

Phương thức getter và setter

Trong bất kỳ ngôn ngữ lập trình nào, việc ẩn các thành viên cá thể bằng từ khóa private và thay vào đó là cung cấp các phương thức getter và setter để thiết lập và nhận các giá trị của các biến cá thể tương ứng. Ví dụ sau đây cho thấy cách này có thể được thực hiện.

class Student {
   private int StudentID;
   private String StudentName;
	
   void setStudentID(int pID) {
      StudentID = pID;
   }
	
   void setStudentName(String pName) {
      StudentName = pName;
   }
	
   int getStudentID() {
      return this.StudentID;
   }
	
   String getStudentName() {
      return this.StudentName;
   }
	
   static void main(String[] args) {
      Student st = new Student();
      st.setStudentID(1);
      st.setStudentName("Joe");
		
      println(st.getStudentID());
      println(st.getStudentName());
   } 
}

Khi chúng ta chạy chương trình trên, chúng ta sẽ nhận được kết quả sau:

1 
Joe

Lưu ý những điểm chính sau đây về chương trình trên -

  • Trong lớp, cả studentID và studentName đều được đánh dấu là riêng tư, nghĩa là không thể truy cập chúng từ bên ngoài lớp.

  • Mỗi thành viên thể hiện có phương thức getter và setter riêng. Phương thức getter trả về giá trị của biến cá thể, ví dụ: phương thức int getStudentID () và phương thức setter đặt giá trị của ID cá thể, ví dụ phương thức - void setStudentName (String pName)

Phương pháp phiên bản

Thông thường, việc bao gồm nhiều phương thức hơn bên trong lớp thực sự thực hiện một số chức năng cho lớp. Trong ví dụ sinh viên của chúng tôi, hãy thêm các thành viên cá thể của Marks1, Marks2 và Marks3 để biểu thị điểm của sinh viên trong 3 môn học. Sau đó, chúng tôi sẽ thêm một phương thức thể hiện mới để tính tổng điểm của học sinh. Sau đây là cách mã sẽ trông như thế nào.

Trong ví dụ sau, phương thức Total là một phương thức Instance bổ sung có một số logic được tích hợp sẵn.

class Student {
   int StudentID;
   String StudentName;
	
   int Marks1;
   int Marks2;
   int Marks3;
	
   int Total() {
      return Marks1+Marks2+Marks3;
   }
	
   static void main(String[] args) {
      Student st = new Student();
      st.StudentID = 1;
      st.StudentName="Joe";
		
      st.Marks1 = 10;
      st.Marks2 = 20;
      st.Marks3 = 30;
		
      println(st.Total());
   }
}

Khi chúng ta chạy chương trình trên, chúng ta sẽ nhận được kết quả sau:

60

Tạo nhiều đối tượng

Người ta cũng có thể tạo nhiều đối tượng của một lớp. Sau đây là ví dụ về cách có thể đạt được điều này. Ở đây, chúng ta đang tạo 3 đối tượng (st, st1 và st2) và gọi các thành viên thể hiện và phương thức thể hiện của chúng tương ứng.

class Student {
   int StudentID;
   String StudentName;
	
   int Marks1;
   int Marks2;
   int Marks3;
	
   int Total() { 
      return Marks1+Marks2+Marks3;
   } 
	
   static void main(String[] args) {
      Student st = new Student();
      st.StudentID = 1;
      st.StudentName = "Joe";
		
      st.Marks1 = 10;
      st.Marks2 = 20;
      st.Marks3 = 30;
		
      println(st.Total()); 
   
      Student st1 = new Student();
      st.StudentID = 1;
      st.StudentName = "Joe";
		
      st.Marks1 = 10;
      st.Marks2 = 20;
      st.Marks3 = 40;
		
      println(st.Total());  
        
      Student st3 = new Student();
      st.StudentID = 1;
      st.StudentName = "Joe";
		
      st.Marks1 = 10; 
      st.Marks2 = 20;
      st.Marks3 = 50;
		
      println(st.Total());
   } 
}

Khi chúng ta chạy chương trình trên, chúng ta sẽ nhận được kết quả sau:

60 
70 
80

Di sản

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

extendslà từ khóa dùng để kế thừa các thuộc tính của một lớp. Dưới đây là cú pháp của từ khóa kéo dài. Trong ví dụ sau, chúng tôi đang làm những điều sau:

  • Tạo một lớp có tên là Person. Lớp này có một thành viên thể hiện được gọi là tên.

  • Tạo một lớp được gọi là Sinh viên mở rộng từ lớp Người. Lưu ý rằng thành viên thể hiện tên được định nghĩa trong lớp Người sẽ được kế thừa trong lớp Sinh viên.

  • Trong hàm tạo lớp Sinh viên, chúng ta đang gọi hàm tạo lớp cơ sở.

  • Trong lớp Sinh viên của chúng tôi, chúng tôi đang thêm 2 thành viên phiên bản bổ sung của StudentID và Marks1.

class Example {
   static void main(String[] args) {
      Student st = new Student();
      st.StudentID = 1;
		
      st.Marks1 = 10;
      st.name = "Joe";
		
      println(st.name);
   }
} 

class Person {
   public String name;
   public Person() {}  
} 

class Student extends Person {
   int StudentID
   int Marks1;
	
   public Student() {
      super();
   } 
}

Khi chúng ta chạy chương trình trên, chúng ta sẽ nhận được kết quả sau:

Joe

Lớp bên trong

Các lớp bên trong được định nghĩa bên trong các lớp khác. Lớp bao quanh có thể sử dụng lớp bên trong như bình thường. Mặt khác, một lớp bên trong có thể truy cập các thành viên của lớp bao quanh nó, ngay cả khi chúng là riêng tư. Các lớp khác với lớp bao quanh không được phép truy cập các lớp bên trong.

Sau đây là một ví dụ về lớp Bên ngoài và Bên trong. Trong ví dụ sau, chúng tôi đang làm những điều sau:

  • Tạo một lớp có tên là Outer sẽ là lớp bên ngoài của chúng ta.
  • Định nghĩa một chuỗi được gọi là tên trong lớp Outer của chúng tôi.
  • Tạo một lớp Bên trong hoặc lớp lồng nhau bên trong lớp Bên ngoài của chúng ta.
  • Lưu ý rằng trong lớp bên trong, chúng ta có thể truy cập thành viên thể hiện tên được định nghĩa trong lớp Bên ngoài.
class Example { 
   static void main(String[] args) { 
      Outer outobj = new Outer(); 
      outobj.name = "Joe"; 
      outobj.callInnerMethod() 
   } 
} 

class Outer { 
   String name;
	
   def callInnerMethod() { 
      new Inner().methodA() 
   } 
	
   class Inner {
      def methodA() { 
         println(name); 
      } 
   } 
	
}

Khi chúng ta chạy chương trình trên, chúng ta sẽ nhận được kết quả sau:

Joe

Các lớp trừu tượng

Các lớp trừu tượng đại diện cho các khái niệm chung, do đó, chúng không thể được khởi tạo, được tạo ra để trở thành lớp con. Các thành viên của chúng bao gồm các trường / thuộc tính và các phương thức trừu tượng hoặc cụ thể. Các phương thức trừu tượng không có thực thi và phải được thực hiện bởi các lớp con cụ thể. Các lớp trừu tượng phải được khai báo bằng từ khóa trừu tượng. Các phương thức trừu tượng cũng phải được khai báo với từ khóa trừu tượng.

Trong ví dụ sau, lưu ý rằng lớp Person bây giờ được tạo thành một lớp trừu tượng và không thể được khởi tạo. Cũng lưu ý rằng có một phương thức trừu tượng được gọi là DisplayMarks trong lớp trừu tượng mà không có chi tiết triển khai. Trong lớp sinh viên, bắt buộc phải thêm các chi tiết thực hiện.

class Example { 
   static void main(String[] args) { 
      Student st = new Student(); 
      st.StudentID = 1;
		
      st.Marks1 = 10; 
      st.name="Joe"; 
		
      println(st.name); 
      println(st.DisplayMarks()); 
   } 
} 

abstract class Person { 
   public String name; 
   public Person() { } 
   abstract void DisplayMarks();
}
 
class Student extends Person { 
   int StudentID 
   int Marks1; 
	
   public Student() { 
      super(); 
   } 
	
   void DisplayMarks() { 
      println(Marks1); 
   }  
}

Khi chúng ta chạy chương trình trên, chúng ta sẽ nhận được kết quả sau:

Joe 
10 
null

Giao diện

Một giao diện xác định một hợp đồng mà một lớp cần tuân theo. Một giao diện chỉ xác định danh sách các phương thức cần được triển khai, nhưng không xác định việc triển khai các phương thức. Một giao diện cần được khai báo bằng từ khóa interface. Một giao diện chỉ xác định các chữ ký của phương thức. Các phương thức của một giao diện luônpublic. Đó là một lỗi khi sử dụng các phương thức được bảo vệ hoặc riêng tư trong các giao diện.

Sau đây là một ví dụ về giao diện trong Groovy. Trong ví dụ sau, chúng tôi đang làm những điều sau:

  • Tạo một giao diện gọi là Marks và tạo một phương thức giao diện gọi là DisplayMarks.

  • Trong định nghĩa lớp, chúng ta đang sử dụng từ khóa triển khai để triển khai giao diện.

  • Bởi vì chúng tôi đang triển khai giao diện, chúng tôi phải cung cấp triển khai cho phương thức DisplayMarks.

class Example {
   static void main(String[] args) {
      Student st = new Student();
      st.StudentID = 1;
      st.Marks1 = 10;
      println(st.DisplayMarks());
   } 
} 

interface Marks { 
   void DisplayMarks(); 
} 

class Student implements Marks {
   int StudentID
   int Marks1;
	
   void DisplayMarks() {
      println(Marks1);
   }
}

Khi chúng ta chạy chương trình trên, chúng ta sẽ nhận được kết quả sau:

10
null

Generics cho phép các kiểu (lớp và giao diện) trở thành tham số khi định nghĩa các lớp, giao diện và phương thức. Giống như các tham số hình thức quen thuộc hơn được sử dụng trong khai báo phương thức, tham số kiểu cung cấp một cách để bạn sử dụng lại cùng một mã với các đầu vào khác nhau. Sự khác biệt là đầu vào cho tham số chính thức là giá trị, trong khi đầu vào cho tham số kiểu là kiểu.

Chung cho Bộ sưu tập

Các lớp bộ sưu tập như lớp Danh sách có thể được tổng quát hóa để chỉ những bộ sưu tập thuộc loại đó được chấp nhận trong ứng dụng. Dưới đây là một ví dụ về ArrayList tổng quát. Những gì câu lệnh sau đây thực hiện là nó chỉ chấp nhận các mục danh sách có kiểu chuỗi:

List<String> list = new ArrayList<String>();

Trong ví dụ mã sau, chúng tôi đang làm như sau:

  • Tạo một bộ sưu tập ArrayList tổng quát sẽ chỉ chứa các Chuỗi.
  • Thêm 3 chuỗi vào danh sách.
  • Đối với mỗi mục trong danh sách, in giá trị của các chuỗi.
class Example {
   static void main(String[] args) {
      // Creating a generic List collection
      List<String> list = new ArrayList<String>();
      list.add("First String");
      list.add("Second String");
      list.add("Third String");
		
      for(String str : list) {
         println(str);
      }
   } 
}

Đầu ra của chương trình trên sẽ là:

First String 
Second String 
Third String

Các lớp tổng quát

Toàn bộ lớp cũng có thể được khái quát hóa. Điều này làm cho lớp linh hoạt hơn trong việc chấp nhận bất kỳ loại nào và làm việc phù hợp với các loại đó. Hãy xem một ví dụ về cách chúng ta có thể thực hiện điều này.

Trong chương trình sau, chúng tôi đang thực hiện các bước sau:

  • Chúng tôi đang tạo một lớp có tên là ListType. Lưu ý các từ khóa <T> được đặt trước định nghĩa lớp. Điều này cho trình biên dịch biết rằng lớp này có thể chấp nhận bất kỳ kiểu nào. Vì vậy, khi chúng ta khai báo một đối tượng của lớp này, chúng ta có thể chỉ định một kiểu trong khi khai báo và kiểu đó sẽ được thay thế trong trình giữ chỗ <T>

  • Lớp chung có các phương thức getter và setter đơn giản để làm việc với biến thành viên được định nghĩa trong lớp.

  • Trong chương trình chính, lưu ý rằng chúng ta có thể khai báo các đối tượng của lớp ListType, nhưng thuộc các kiểu khác nhau. Cái đầu tiên thuộc loại Integer và cái thứ hai thuộc loại String.

class Example {
   static void main(String[] args) {
      // Creating a generic List collection 
      ListType<String> lststr = new ListType<>();
      lststr.set("First String");
      println(lststr.get()); 
		
      ListType<Integer> lstint = new ListType<>();
      lstint.set(1);
      println(lstint.get());
   }
} 

public class ListType<T> {
   private T localt;
	
   public T get() {
      return this.localt;
   }
	
   public void set(T plocal) {
      this.localt = plocal;
   } 
}

Đầu ra của chương trình trên sẽ là:

First String 
1

Đặc điểm là một cấu trúc cấu trúc của ngôn ngữ cho phép -

  • Thành phần của các hành vi.
  • Thực thi thời gian chạy của các giao diện.
  • Khả năng tương thích với kiểm tra / biên dịch kiểu tĩnh

Chúng có thể được coi là giao diện mang cả trạng thái và triển khai mặc định. Một đặc điểm được xác định bằng cách sử dụng từ khóa đặc điểm.

Dưới đây là một ví dụ về đặc điểm:

trait Marks {
   void DisplayMarks() {
      println("Display Marks");
   } 
}

Sau đó, người ta có thể sử dụng từ khóa triển khai để triển khai đặc điểm theo cách tương tự như các giao diện.

class Example {
   static void main(String[] args) {
      Student st = new Student();
      st.StudentID = 1;
      st.Marks1 = 10; 
      println(st.DisplayMarks());
   } 
} 

trait Marks { 
   void DisplayMarks() {
      println("Display Marks");
   } 
} 

class Student implements Marks { 
   int StudentID
   int Marks1;
}

Triển khai giao diện

Các đặc điểm có thể triển khai các giao diện, trong trường hợp này, các giao diện được khai báo bằng cách sử dụng từ khóa triển khai.

An example of a trait implementing an interface is given below. In the following example the following key points can be noted.

  • An interface Total is defined with the method DisplayTotal.

  • The trait Marks implements the Total interface and hence needs to provide an implementation for the DisplayTotal method.

class Example {
   static void main(String[] args) {
      Student st = new Student();
      st.StudentID = 1;
      st.Marks1 = 10;
		
      println(st.DisplayMarks());
      println(st.DisplayTotal());
   } 
} 

interface Total {
   void DisplayTotal() 
} 

trait Marks implements Total {
   void DisplayMarks() {
      println("Display Marks");
   }
	
   void DisplayTotal() {
      println("Display Total"); 
   } 
} 

class Student implements Marks { 
   int StudentID
   int Marks1;  
}

The output of the above program would be −

Display Marks 
Display Total

Properties

A trait may define properties. An example of a trait with a property is given below.

In the following example, the Marks1 of type integer is a property.

class Example {
   static void main(String[] args) {
      Student st = new Student();
      st.StudentID = 1;
		
      println(st.DisplayMarks());
      println(st.DisplayTotal());
   } 
	
   interface Total {
      void DisplayTotal() 
   } 
	
   trait Marks implements Total {
      int Marks1;
		
      void DisplayMarks() {
         this.Marks1 = 10;
         println(this.Marks1);
      }
		
      void DisplayTotal() {
         println("Display Total");
      } 
   } 
	
   class Student implements Marks {
      int StudentID 
   }
}

The output of the above program would be −

10 
Display Total

Composition of Behaviors

Traits can be used to implement multiple inheritance in a controlled way, avoiding the diamond issue. In the following code example, we have defined two traits – Marks and Total. Our Student class implements both traits. Since the student class extends both traits, it is able to access the both of the methods – DisplayMarks and DisplayTotal.

class Example {
   static void main(String[] args) {
      Student st = new Student();
      st.StudentID = 1;
		
      println(st.DisplayMarks());
      println(st.DisplayTotal()); 
   } 
} 

trait Marks {
   void DisplayMarks() {
      println("Marks1");
   } 
} 

trait Total {
   void DisplayTotal() { 
      println("Total");
   } 
}  

class Student implements Marks,Total {
   int StudentID 
}

The output of the above program would be −

Total 
Marks1

Extending Traits

Traits may extend another trait, in which case you must use the extends keyword. In the following code example, we are extending the Total trait with the Marks trait.

class Example {
   static void main(String[] args) {
      Student st = new Student();
      st.StudentID = 1;
      println(st.DisplayMarks());
   } 
} 

trait Marks {
   void DisplayMarks() {
      println("Marks1");
   } 
} 

trait Total extends Marks {
   void DisplayMarks() {
      println("Total");
   } 
}  

class Student implements Total {
   int StudentID 
}

The output of the above program would be −

Total

A closure is a short anonymous block of code. It just normally spans a few lines of code. A method can even take the block of code as a parameter. They are anonymous in nature.

Following is an example of a simple closure and what it looks like.

class Example {
   static void main(String[] args) {
      def clos = {println "Hello World"};
      clos.call();
   } 
}

In the above example, the code line - {println "Hello World"} is known as a closure. The code block referenced by this identifier can be executed with the call statement.

When we run the above program, we will get the following result −

Hello World

Formal parameters in closures

Closures can also contain formal parameters to make them more useful just like methods in Groovy.

class Example {
   static void main(String[] args) {
      def clos = {param->println "Hello ${param}"};
      clos.call("World");
   } 
}

Trong ví dụ mã ở trên, hãy lưu ý việc sử dụng $ {param} khiến đóng cửa nhận một tham số. Khi gọi bao đóng thông qua câu lệnh close.call, bây giờ chúng ta có tùy chọn để truyền một tham số cho bao đóng.

Khi chúng ta chạy chương trình trên, chúng ta sẽ nhận được kết quả sau:

Hello World

Hình minh họa tiếp theo lặp lại ví dụ trước đó và tạo ra kết quả tương tự, nhưng cho thấy rằng một tham số tiềm ẩn đơn lẻ được gọi là nó có thể được sử dụng. Đây là một từ khóa trong Groovy.

class Example {
   static void main(String[] args) {
      def clos = {println "Hello ${it}"};
      clos.call("World");
   } 
}

Khi chúng ta chạy chương trình trên, chúng ta sẽ nhận được kết quả sau:

Hello World

Đóng cửa và các biến

Chính thức hơn, bao đóng có thể tham chiếu đến các biến tại thời điểm đóng được định nghĩa. Sau đây là một ví dụ về cách có thể đạt được điều này.

class Example {     
   static void main(String[] args) {
      def str1 = "Hello";
      def clos = {param -> println "${str1} ${param}"}
      clos.call("World");
		
      // We are now changing the value of the String str1 which is referenced in the closure
      str1 = "Welcome";
      clos.call("World");
   } 
}

Trong ví dụ trên, ngoài việc truyền một tham số cho bao đóng, chúng ta cũng định nghĩa một biến có tên là str1. Việc đóng cũng nhận biến cùng với tham số.

Khi chúng ta chạy chương trình trên, chúng ta sẽ nhận được kết quả sau:

Hello World 
Welcome World

Sử dụng các phương pháp đóng cửa

Closures cũng có thể được sử dụng làm tham số cho các phương thức. Trong Groovy, rất nhiều phương thức có sẵn cho kiểu dữ liệu như Danh sách và bộ sưu tập có các bao đóng như một kiểu tham số.

Ví dụ sau đây cho thấy cách một bao đóng có thể được gửi đến một phương thức dưới dạng một tham số.

class Example { 
   def static Display(clo) {
      // This time the $param parameter gets replaced by the string "Inner"         
      clo.call("Inner");
   } 
	
   static void main(String[] args) {
      def str1 = "Hello";
      def clos = { param -> println "${str1} ${param}" }
      clos.call("World");
		
      // We are now changing the value of the String str1 which is referenced in the closure
      str1 = "Welcome";
      clos.call("World");
		
      // Passing our closure to a method
      Example.Display(clos);
   } 
}

Trong ví dụ trên,

  • Chúng tôi đang định nghĩa một phương thức tĩnh có tên là Display, phương thức này nhận một hàm đóng làm đối số.

  • Sau đó, chúng tôi đang xác định một bao đóng trong phương thức chính của chúng tôi và chuyển nó đến phương thức Hiển thị của chúng tôi dưới dạng một tham số.

Khi chúng ta chạy chương trình trên, chúng ta sẽ nhận được kết quả sau:

Hello World 
Welcome World 
Welcome Inner

Đóng trong Bộ sưu tập và Chuỗi

Một số phương thức List, Map và String chấp nhận một bao đóng làm đối số. Hãy xem ví dụ về cách các bao đóng có thể được sử dụng trong các kiểu dữ liệu này.

Sử dụng Đóng với Danh sách

Ví dụ sau đây cho thấy cách các bao đóng có thể được sử dụng với Danh sách. Trong ví dụ sau, trước tiên chúng ta định nghĩa một danh sách các giá trị đơn giản. Sau đó, kiểu tập hợp danh sách xác định một hàm được gọi.each. Hàm này nhận bao đóng làm tham số và áp dụng bao đóng cho mỗi phần tử của danh sách.

class Example {
   static void main(String[] args) {
      def lst = [11, 12, 13, 14];
      lst.each {println it}
   } 
}

Khi chúng ta chạy chương trình trên, chúng ta sẽ nhận được kết quả sau:

11 
12 
13 
14

Sử dụng Closures với Bản đồ

Ví dụ sau đây cho thấy cách sử dụng các điểm đóng cửa với Maps. Trong ví dụ sau, chúng tôi đầu tiên định nghĩa một Bản đồ đơn giản của các mục giá trị quan trọng. Sau đó, kiểu tập hợp bản đồ xác định một hàm được gọi là .each. Hàm này nhận bao đóng làm tham số và áp dụng bao đóng cho từng cặp khóa-giá trị của bản đồ.

class Example {
   static void main(String[] args) {
      def mp = ["TopicName" : "Maps", "TopicDescription" : "Methods in Maps"]             
      mp.each {println it}
      mp.each {println "${it.key} maps to: ${it.value}"}
   } 
}

Khi chúng ta chạy chương trình trên, chúng ta sẽ nhận được kết quả sau:

TopicName = Maps 
TopicDescription = Methods in Maps 
TopicName maps to: Maps 
TopicDescription maps to: Methods in Maps

Thông thường, chúng ta có thể muốn lặp lại qua các thành viên của một tập hợp và chỉ áp dụng một số logic khi phần tử đáp ứng một số tiêu chí. Điều này dễ dàng được xử lý với một câu lệnh điều kiện trong bao đóng.

class Example {
   static void main(String[] args) {
      def lst = [1,2,3,4];
      lst.each {println it}
      println("The list will only display those numbers which are divisible by 2")
      lst.each{num -> if(num % 2 == 0) println num}
   } 
}

Ví dụ trên cho thấy biểu thức if (num% 2 == 0) có điều kiện đang được sử dụng trong bao đóng được sử dụng để kiểm tra xem mỗi mục trong danh sách có chia hết cho 2 hay không.

Khi chúng ta chạy chương trình trên, chúng ta sẽ nhận được kết quả sau:

1 
2 
3 
4 
The list will only display those numbers which are divisible by 2.
2 
4

Các phương pháp sử dụng với Closures

Việc đóng cửa tự cung cấp một số phương pháp.

Sr.No. Phương pháp & Mô tả
1 tìm thấy()

Phương thức find tìm giá trị đầu tiên trong tập hợp phù hợp với một số tiêu chí.

2 findAll ()

Nó tìm tất cả các giá trị trong đối tượng nhận phù hợp với điều kiện đóng.

3 any () & every ()

Phương thức bất kỳ lặp lại qua từng phần tử của tập hợp để kiểm tra xem một vị từ Boolean có hợp lệ cho ít nhất một phần tử hay không.

4 sưu tầm()

Phương pháp thu thập lặp lại thông qua một bộ sưu tập, chuyển đổi mỗi phần tử thành một giá trị mới bằng cách sử dụng đóng làm máy biến áp.

Chú thích là một dạng siêu dữ liệu trong đó chúng cung cấp dữ liệu về một chương trình không phải là một phần của chính chương trình đó. Chú thích không có ảnh hưởng trực tiếp đến hoạt động của mã mà chúng chú thích.

Chú thích chủ yếu được sử dụng vì những lý do sau:

  • Information for the compiler - Trình biên dịch có thể sử dụng các chú thích để phát hiện lỗi hoặc ngăn chặn các cảnh báo.

  • Compile-time and deployment-time processing - Các công cụ phần mềm có thể xử lý thông tin chú thích để tạo mã, tệp XML, v.v.

  • Runtime processing - Một số chú thích có sẵn để được kiểm tra trong thời gian chạy.

Trong Groovy, một chú thích cơ bản trông như sau:

@interface - Ký tự dấu tại (@) cho trình biên dịch biết rằng những gì sau đây là một chú thích.

Chú thích có thể xác định các thành viên trong the form của các phương thức không có phần thân và một giá trị mặc định tùy chọn.

Chú thích có thể được áp dụng cho các loại sau:

Loại chuỗi

Dưới đây là một ví dụ về Chú thích cho một chuỗi:

@interface Simple { 
   String str1() default "HelloWorld"; 
}

Loại enum

enum DayOfWeek { mon, tue, wed, thu, fri, sat, sun } 
@interface Scheduled {
   DayOfWeek dayOfWeek() 
}

Loại lớp

@interface Simple {} 
@Simple 
class User {
   String username
   int age
}
 
def user = new User(username: "Joe",age:1); 
println(user.age); 
println(user.username);

Giá trị thành viên chú thích

Khi một chú thích được sử dụng, cần phải đặt ít nhất tất cả các thành viên không có giá trị mặc định. Một ví dụ được đưa ra dưới đây. Khi Ví dụ chú thích được sử dụng sau khi được định nghĩa, nó cần phải có một giá trị được gán cho nó.

@interface Example {
   int status() 
}

@Example(status = 1)

Thông số chú thích đóng cửa

Một tính năng tốt của chú thích trong Groovy là bạn cũng có thể sử dụng bao đóng làm giá trị chú thích. Do đó, chú thích có thể được sử dụng với nhiều cách diễn đạt.

Một ví dụ được đưa ra dưới đây về điều này. Chú thích Onlyif được tạo dựa trên một giá trị lớp. Sau đó, chú thích được áp dụng cho hai phương thức đăng các thông báo khác nhau lên biến kết quả dựa trên giá trị của biến số.

@interface OnlyIf {
   Class value() 
}  

@OnlyIf({ number<=6 }) 
void Version6() {
   result << 'Number greater than 6' 
} 

@OnlyIf({ number>=6 }) 
void Version7() {
   result << 'Number greater than 6' 
}

Chú thích meta

Đây là một tính năng khá hữu ích của chú thích trong groovy. Đôi khi, bạn có thể có nhiều chú thích cho một phương thức như hình minh họa bên dưới. Đôi khi điều này có thể trở nên lộn xộn khi có nhiều chú thích.

@Procedure 
@Master class 
MyMasterProcedure {}

Trong trường hợp này, bạn có thể xác định một meta-annotation mà kết hợp nhiều chú thích lại với nhau và áp dụng meta annotation cho phương pháp. Vì vậy, đối với ví dụ trên, bạn có thể xác định tập hợp các chú thích bằng AnnotationCollector.

import groovy.transform.AnnotationCollector
  
@Procedure 
@Master 
@AnnotationCollector

Khi điều này được thực hiện, bạn có thể áp dụng siêu chú thích sau cho phương pháp:

import groovy.transform.AnnotationCollector
  
@Procedure 
@Master 
@AnnotationCollector
  
@MasterProcedure 
class MyMasterProcedure {}

XML là một ngôn ngữ mã nguồn mở, di động cho phép các lập trình viên phát triển các ứng dụng mà các ứng dụng khác có thể đọc được, bất kể hệ điều hành và / hoặc ngôn ngữ phát triển. Đây là một trong những ngôn ngữ phổ biến nhất được sử dụng để trao đổi dữ liệu giữa các ứng dụng.

XML là gì?

Ngôn ngữ đánh dấu mở rộng XML là một ngôn ngữ đánh dấu giống như HTML hoặc SGML. Điều này được khuyến nghị bởi World Wide Web Consortium và có sẵn như một tiêu chuẩn mở. XML cực kỳ hữu ích để theo dõi lượng dữ liệu vừa và nhỏ mà không yêu cầu xương sống dựa trên SQL.

Hỗ trợ XML trong Groovy

Ngôn ngữ Groovy cũng cung cấp sự hỗ trợ phong phú cho ngôn ngữ XML. Hai lớp XML cơ bản nhất được sử dụng là:

  • XML Markup Builder- Groovy hỗ trợ trình tạo đánh dấu dựa trên cây, BuilderSupport, có thể được phân lớp để tạo ra nhiều dạng biểu diễn đối tượng có cấu trúc cây. Thông thường, các trình xây dựng này được sử dụng để biểu diễn đánh dấu XML, đánh dấu HTML. Trình tạo đánh dấu của Groovy bắt các lệnh gọi đến các điểm giả và chuyển đổi chúng thành các phần tử hoặc nút của cấu trúc cây. Các tham số của các nút giả này được coi là thuộc tính của các nút. Các đóng như một phần của lệnh gọi phương thức được coi là nội dung con lồng nhau cho nút cây kết quả.

  • XML Parser- Lớp Groovy XmlParser sử dụng một mô hình đơn giản để phân tích cú pháp một tài liệu XML thành một cây các thể hiện Node. Mỗi Node có tên của phần tử XML, các thuộc tính của phần tử và các tham chiếu đến bất kỳ Node con nào. Mô hình này là đủ để xử lý XML đơn giản nhất.

Đối với tất cả các ví dụ về mã XML của chúng tôi, hãy sử dụng tệp XML phim.xml đơn giản sau để xây dựng tệp XML và đọc tệp sau đó.

<collection shelf = "New Arrivals"> 

   <movie title = "Enemy Behind"> 
      <type>War, Thriller</type> 
      <format>DVD</format> 
      <year>2003</year> 
      <rating>PG</rating> 
      <stars>10</stars> 
      <description>Talk about a US-Japan war</description> 
   </movie> 
	
   <movie title = "Transformers"> 
      <type>Anime, Science Fiction</type>
      <format>DVD</format> 
      <year>1989</year> 
      <rating>R</rating> 
      <stars>8</stars> 
      <description>A schientific fiction</description> 
   </movie> 
	
   <movie title = "Trigun"> 
      <type>Anime, Action</type> 
      <format>DVD</format> 
      <year>1986</year> 
      <rating>PG</rating> 
      <stars>10</stars> 
      <description>Vash the Stam pede!</description> 
   </movie> 
	
   <movie title = "Ishtar"> 
      <type>Comedy</type> 
      <format>VHS</format> 
      <year>1987</year> 
      <rating>PG</rating> 
      <stars>2</stars> 
      <description>Viewable boredom </description> 
   </movie> 
	
</collection>

Trình tạo đánh dấu XML

Cú pháp

public MarkupBuilder()

MarkupBuilder được sử dụng để xây dựng toàn bộ tài liệu XML. Tài liệu XML được tạo bằng cách đầu tiên tạo một đối tượng của lớp tài liệu XML. Khi đối tượng được tạo, một phương pháp giả có thể được gọi để tạo các phần tử khác nhau của tài liệu XML.

Hãy xem một ví dụ về cách tạo một khối, tức là một phần tử phim từ tài liệu XML ở trên -

import groovy.xml.MarkupBuilder 

class Example {
   static void main(String[] args) {
      def mB = new MarkupBuilder()
		
      // Compose the builder
      mB.collection(shelf : 'New Arrivals') {
         movie(title : 'Enemy Behind')
         type('War, Thriller')
         format('DVD')
         year('2003')
         rating('PG')
         stars(10)
         description('Talk about a US-Japan war') 
      }
   } 
}

Trong ví dụ trên, cần lưu ý những điều sau:

  • mB.collection() - Đây là trình tạo đánh dấu tạo thẻ XML đầu của <collection> </collection>

  • movie(title : 'Enemy Behind')- Các pseudomethods này tạo các thẻ con bằng phương pháp này tạo thẻ có giá trị. Bằng cách chỉ định một giá trị được gọi là tiêu đề, điều này thực sự chỉ ra rằng một thuộc tính cần được tạo cho phần tử.

  • Một bao đóng được cung cấp cho phương pháp giả để tạo các phần tử còn lại của tài liệu XML.

  • Hàm tạo mặc định cho lớp MarkupBuilder được khởi tạo để XML được tạo ra được cấp cho luồng đầu ra tiêu chuẩn

Khi chúng ta chạy chương trình trên, chúng ta sẽ nhận được kết quả sau:

<collection shelf = 'New Arrivals'> 
   <movie title = 'Enemy Behind' /> 
      <type>War, Thriller</type> 
      <format>DVD</format> 
      <year>2003</year> 
      <rating>PG</rating> 
      <stars>10</stars> 
      <description>Talk about a US-Japan war</description> 
   </movie> 
</collection>

Để tạo toàn bộ tài liệu XML, cần thực hiện những việc sau.

  • Một mục bản đồ cần được tạo để lưu trữ các giá trị khác nhau của các phần tử.
  • Đối với mỗi phần tử của bản đồ, chúng tôi đang gán giá trị cho mỗi phần tử.
import groovy.xml.MarkupBuilder 

class Example {
   static void main(String[] args) {
      def mp = [1 : ['Enemy Behind', 'War, Thriller','DVD','2003', 
         'PG', '10','Talk about a US-Japan war'],
         2 : ['Transformers','Anime, Science Fiction','DVD','1989', 
         'R', '8','A scientific fiction'],
         3 : ['Trigun','Anime, Action','DVD','1986', 
         'PG', '10','Vash the Stam pede'],
         4 : ['Ishtar','Comedy','VHS','1987', 'PG', 
         '2','Viewable boredom ']] 
			
      def mB = new MarkupBuilder()  
		
      // Compose the builder
      def MOVIEDB = mB.collection('shelf': 'New Arrivals') {
         mp.each {
            sd -> 
            mB.movie('title': sd.value[0]) {  
               type(sd.value[1])
               format(sd.value[2])
               year(sd.value[3]) 
               rating(sd.value[4])
               stars(sd.value[4]) 
               description(sd.value[5]) 
            }
         }
      }
   } 
}

Khi chúng ta chạy chương trình trên, chúng ta sẽ nhận được kết quả sau:

<collection shelf = 'New Arrivals'> 
   <movie title = 'Enemy Behind'> 
      <type>War, Thriller</type> 
      <format>DVD</format> 
      <year>2003</year> 
      <rating>PG</rating> 
      <stars>PG</stars> 
      <description>10</description> 
   </movie> 
   <movie title = 'Transformers'> 
      <type>Anime, Science Fiction</type> 
      <format>DVD</format> 
      <year>1989</year>
	  <rating>R</rating> 
      <stars>R</stars> 
      <description>8</description> 
   </movie> 
   <movie title = 'Trigun'> 
      <type>Anime, Action</type> 
      <format>DVD</format> 
      <year>1986</year> 
      <rating>PG</rating> 
      <stars>PG</stars> 
      <description>10</description> 
   </movie> 
   <movie title = 'Ishtar'> 
      <type>Comedy</type> 
      <format>VHS</format> 
      <year>1987</year> 
      <rating>PG</rating> 
      <stars>PG</stars> 
      <description>2</description> 
   </movie> 
</collection>

Phân tích cú pháp XML

Lớp Groovy XmlParser sử dụng một mô hình đơn giản để phân tích cú pháp một tài liệu XML thành một cây các thể hiện Node. Mỗi Node có tên của phần tử XML, các thuộc tính của phần tử và các tham chiếu đến bất kỳ Node con nào. Mô hình này là đủ để xử lý XML đơn giản nhất.

Cú pháp

public XmlParser() 
   throws ParserConfigurationException, 
      SAXException

Đoạn mã sau đây trình bày một ví dụ về cách có thể sử dụng trình phân tích cú pháp XML để đọc một tài liệu XML.

Giả sử chúng ta có cùng một tài liệu tên là Movies.xml và chúng ta muốn phân tích cú pháp tài liệu XML và hiển thị đầu ra thích hợp cho người dùng. Đoạn mã sau là đoạn mã về cách chúng tôi có thể xem qua toàn bộ nội dung của tài liệu XML và hiển thị phản hồi thích hợp cho người dùng.

import groovy.xml.MarkupBuilder 
import groovy.util.*

class Example {

   static void main(String[] args) { 
	
      def parser = new XmlParser()
      def doc = parser.parse("D:\\Movies.xml");
		
      doc.movie.each{
         bk->
         print("Movie Name:")
         println "${bk['@title']}" print("Movie Type:") println "${bk.type[0].text()}"
			
         print("Movie Format:")
         println "${bk.format[0].text()}" print("Movie year:") println "${bk.year[0].text()}"
			
         print("Movie rating:")
         println "${bk.rating[0].text()}" print("Movie stars:") println "${bk.stars[0].text()}"
			
         print("Movie description:")
         println "${bk.description[0].text()}"
         println("*******************************")
      }
   }
}

Khi chúng ta chạy chương trình trên, chúng ta sẽ nhận được kết quả sau:

Movie Name:Enemy Behind 
Movie Type:War, Thriller 
Movie Format:DVD 
Movie year:2003 
Movie rating:PG 
Movie stars:10 
Movie description:Talk about a US-Japan war 
******************************* 
Movie Name:Transformers 
Movie Type:Anime, Science Fiction 
Movie Format:DVD 
Movie year:1989 
Movie rating:R 
Movie stars:8 
Movie description:A schientific fiction 
******************************* 
Movie Name:Trigun 
Movie Type:Anime, Action
Movie Format:DVD 
Movie year:1986 
Movie rating:PG 
Movie stars:10 
Movie description:Vash the Stam pede! 
******************************* 
Movie Name:Ishtar 
Movie Type:Comedy 
Movie Format:VHS 
Movie year:1987 
Movie rating:PG 
Movie stars:2 
Movie description:Viewable boredom

Những điều quan trọng cần lưu ý về mã trên.

  • Một đối tượng của lớp XmlParser đang được hình thành để nó có thể được sử dụng để phân tích cú pháp tài liệu XML.

  • Trình phân tích cú pháp được cung cấp vị trí của tệp XML.

  • Đối với mỗi phần tử phim, chúng tôi đang sử dụng một bao đóng để duyệt qua từng nút con và hiển thị thông tin liên quan.

Đối với bản thân phần tử phim, chúng tôi đang sử dụng ký hiệu @ để hiển thị thuộc tính tiêu đề được đính kèm với phần tử phim.

JMX là tiêu chuẩn defacto được sử dụng để giám sát tất cả các ứng dụng có liên quan đến môi trường virual của Java. Cho rằng Groovy nằm ngay trên Java, Groovy có thể tận dụng khối lượng công việc khổng lồ đã được thực hiện cho JMX với Java.

Giám sát JVM

Người ta có thể sử dụng các lớp tiêu chuẩn có sẵn trong java.lang.management để thực hiện việc giám sát JVM. Ví dụ mã sau đây cho thấy cách này có thể được thực hiện.

import java.lang.management.*

def os = ManagementFactory.operatingSystemMXBean 
println """OPERATING SYSTEM: 
\tOS architecture = $os.arch 
\tOS name = $os.name \tOS version = $os.version 
\tOS processors = $os.availableProcessors """ def rt = ManagementFactory.runtimeMXBean println """RUNTIME: \tRuntime name = $rt.name 
   \tRuntime spec name = $rt.specName \tRuntime vendor = $rt.specVendor 
   \tRuntime spec version = $rt.specVersion \tRuntime management spec version = $rt.managementSpecVersion 
   """ 

def mem = ManagementFactory.memoryMXBean 
def heapUsage = mem.heapMemoryUsage 
def nonHeapUsage = mem.nonHeapMemoryUsage 

println """MEMORY: 
   HEAP STORAGE: 
      \tMemory committed = $heapUsage.committed \tMemory init = $heapUsage.init 
      \tMemory max = $heapUsage.max \tMemory used = $heapUsage.used NON-HEAP STORAGE: 
      \tNon-heap memory committed = $nonHeapUsage.committed \tNon-heap memory init = $nonHeapUsage.init 
      \tNon-heap memory max = $nonHeapUsage.max \tNon-heap memory used = $nonHeapUsage.used 
   """
  
println "GARBAGE COLLECTION:" 
ManagementFactory.garbageCollectorMXBeans.each { gc ->
   println "\tname = $gc.name" println "\t\tcollection count = $gc.collectionCount"
   println "\t\tcollection time = $gc.collectionTime" String[] mpoolNames = gc.memoryPoolNames mpoolNames.each { mpoolName -> println "\t\tmpool name = $mpoolName"
   } 
}

Khi mã được thực thi, kết quả đầu ra sẽ khác nhau tùy thuộc vào hệ thống mà mã được chạy. Dưới đây là một ví dụ về kết quả đầu ra.

OPERATING SYSTEM: 
   OS architecture = x86 
   OS name = Windows 7 
   OS version = 6.1 
   OS processors = 4
   
RUNTIME: 
   Runtime name = 5144@Babuli-PC 
   Runtime spec name = Java Virtual Machine Specification 
   Runtime vendor = Oracle Corporation 
   Runtime spec version = 1.7 
   Runtime management spec version = 1.2
   
MEMORY: 
   HEAP STORAGE: 
      Memory committed = 16252928 
      Memory init = 16777216 
      Memory max = 259522560 
      Memory used = 7355840
   
NON-HEAP STORAGE: 
   Non-heap memory committed = 37715968 
   Non-heap memory init = 35815424 
   Non-heap memory max = 123731968 
   Non-heap memory used = 18532232 
   
GARBAGE COLLECTION: 
   name = Copy 
   collection count = 15 
   collection time = 47 
   mpool name = Eden Space 
   mpool name = Survivor Space
		
   name = MarkSweepCompact 
      collection count = 0 
      collection time = 0 
		
      mpool name = Eden Space 
      mpool name = Survivor Space 
      mpool name = Tenured Gen 
      mpool name = Perm Gen 
      mpool name = Perm Gen [shared-ro] 
      mpool name = Perm Gen [shared-rw]

Giám sát Tomcat

Để giám sát tomcat, thông số sau phải được đặt khi tomcat được khởi động:

set JAVA_OPTS = -Dcom.sun.management.jmxremote 
Dcom.sun.management.jmxremote.port = 9004\
 
-Dcom.sun.management.jmxremote.authenticate=false 
Dcom.sun.management.jmxremote.ssl = false

Đoạn mã sau sử dụng JMX để khám phá MBeans có sẵn trong Tomcat đang chạy, xác định đâu là mô-đun web và trích xuất thời gian xử lý cho từng mô-đun web.

import groovy.swing.SwingBuilder
  
import javax.management.ObjectName 
import javax.management.remote.JMXConnectorFactory as JmxFactory 
import javax.management.remote.JMXServiceURL as JmxUrl 
import javax.swing.WindowConstants as WC 
 
import org.jfree.chart.ChartFactory 
import org.jfree.data.category.DefaultCategoryDataset as Dataset 
import org.jfree.chart.plot.PlotOrientation as Orientation 
 
def serverUrl = 'service:jmx:rmi:///jndi/rmi://localhost:9004/jmxrmi' 
def server = JmxFactory.connect(new JmxUrl(serverUrl)).MBeanServerConnection 
def serverInfo = new GroovyMBean(server, 'Catalina:type = Server').serverInfo 
println "Connected to: $serverInfo" def query = new ObjectName('Catalina:*') String[] allNames = server.queryNames(query, null) def modules = allNames.findAll { name -> name.contains('j2eeType=WebModule') }.collect{ new GroovyMBean(server, it) } println "Found ${modules.size()} web modules. Processing ..." 
def dataset = new Dataset() 
 
modules.each { m ->
   println m.name()
   dataset.addValue m.processingTime, 0, m.path 
}

Chương này trình bày cách chúng ta có thể sử dụng ngôn ngữ Groovy để phân tích cú pháp và tạo các đối tượng JSON.

Các hàm JSON

Sr.No Chức năng & Thư viện
1

JsonSlurper

JsonSlurper là một lớp phân tích văn bản JSON hoặc nội dung trình đọc thành dữ liệu Groovy

Các cấu trúc như bản đồ, danh sách và các kiểu nguyên thủy như Integer, Double, Boolean và String.

2

JsonOutput

Phương thức này chịu trách nhiệm nối tiếp các đối tượng Groovy thành chuỗi JSON.

Phân tích cú pháp dữ liệu bằng JsonSlurper

JsonSlurper là một lớp phân tích văn bản JSON hoặc nội dung trình đọc thành các Cấu trúc dữ liệu Groovy như bản đồ, danh sách và các kiểu nguyên thủy như Integer, Double, Boolean và String.

Cú pháp

def slurper = new JsonSlurper()

JSON slurper phân tích cú pháp văn bản hoặc nội dung trình đọc thành cấu trúc dữ liệu của danh sách và bản đồ.

Lớp JsonSlurper đi kèm với một vài biến thể để triển khai trình phân tích cú pháp. Đôi khi bạn có thể có các yêu cầu khác nhau khi phân tích các chuỗi nhất định. Hãy lấy một ví dụ trong đó một người cần đọc JSON được trả về từ phản hồi từ máy chủ web. Trong trường hợp như vậy, sẽ có lợi khi sử dụng biến thể phân tích cú pháp JsonParserLax. Trình phân tích cú pháp này cho phép nhận xét trong văn bản JSON cũng như không có chuỗi trích dẫn, v.v. Để chỉ định loại trình phân tích cú pháp này, bạn cần sử dụng loại trình phân tích cú pháp JsonParserType.LAX khi xác định một đối tượng của JsonSlurper.

Hãy xem một ví dụ về điều này được đưa ra dưới đây. Ví dụ là lấy dữ liệu JSON từ máy chủ web bằng mô-đun http. Đối với loại truyền tải này, tùy chọn tốt nhất là đặt loại phân tích cú pháp thành biến thể JsonParserLax.

http.request( GET, TEXT ) {
   headers.Accept = 'application/json'
   headers.'User-Agent' = USER_AGENT
	
   response.success = { 
      res, rd ->  
      def jsonText = rd.text 
		
      //Setting the parser type to JsonParserLax
      def parser = new JsonSlurper().setType(JsonParserType.LAX)
      def jsonResp = parser.parseText(jsonText)
   }
}

Tương tự, các loại phân tích cú pháp bổ sung sau đây có sẵn trong Groovy:

  • Trình phân tích cú pháp JsonParserCharArray về cơ bản nhận một chuỗi JSON và hoạt động trên mảng ký tự bên dưới. Trong quá trình chuyển đổi giá trị, nó sao chép các mảng con ký tự (một cơ chế được gọi là "cắt") và hoạt động trên chúng riêng lẻ.

  • JsonFastParser là một biến thể đặc biệt của JsonParserCharArray và là trình phân tích cú pháp nhanh nhất. JsonFastParser còn được gọi là trình phân tích cú pháp lớp phủ chỉ mục. Trong quá trình phân tích cú pháp của Chuỗi JSON đã cho, nó cố gắng hết sức có thể để tránh tạo ra các mảng char hoặc phiên bản Chuỗi mới. Nó chỉ giữ các con trỏ đến mảng ký tự gốc bên dưới mà thôi. Ngoài ra, nó làm giảm khả năng tạo đối tượng càng muộn càng tốt.

  • JsonParserUsingCharacterSource là một trình phân tích cú pháp đặc biệt cho các tệp rất lớn. Nó sử dụng một kỹ thuật được gọi là "cửa sổ ký tự" để phân tích cú pháp các tệp JSON lớn (trong trường hợp này là các tệp có kích thước lớn hơn 2MB) với các đặc điểm hiệu suất không đổi.

Phân tích cú pháp văn bản

Hãy xem một số ví dụ về cách chúng ta có thể sử dụng lớp JsonSlurper.

import groovy.json.JsonSlurper 

class Example {
   static void main(String[] args) {
      def jsonSlurper = new JsonSlurper()
      def object = jsonSlurper.parseText('{ "name": "John", "ID" : "1"}') 
		
      println(object.name);
      println(object.ID);
   } 
}

Trong ví dụ trên, chúng ta -

  • Đầu tiên tạo một phiên bản của lớp JsonSlurper

  • Sau đó, chúng tôi đang sử dụng hàm parseText của lớp JsonSlurper để phân tích cú pháp một số văn bản JSON.

  • Khi chúng tôi nhận được đối tượng, bạn có thể thấy rằng chúng tôi thực sự có thể truy cập các giá trị trong chuỗi JSON thông qua khóa.

Đầu ra của chương trình trên được đưa ra dưới đây:

John 
1

Phân tích cú pháp danh sách các số nguyên

Hãy xem một ví dụ khác về phương pháp phân tích cú pháp JsonSlurper. Trong ví dụ sau, chúng tôi đang viết hoa một danh sách các số nguyên. Bạn sẽ nhận thấy từ codethat sau đây, chúng tôi có thể sử dụng phương thức Danh sách của từng loại và chuyển một đóng cho nó.

import groovy.json.JsonSlurper 
class Example {
   static void main(String[] args) {
      def jsonSlurper = new JsonSlurper()
      Object lst = jsonSlurper.parseText('{ "List": [2, 3, 4, 5] }')
      lst.each { println it }
   } 
}

Đầu ra của chương trình trên được đưa ra dưới đây:

List=[2, 3, 4, 5]

Danh sách phân tích cú pháp các kiểu dữ liệu nguyên thủy

Trình phân tích cú pháp JSON cũng hỗ trợ các kiểu dữ liệu nguyên thủy là chuỗi, số, đối tượng, true, false và null. Lớp JsonSlurper chuyển đổi các kiểu JSON này thành các kiểu Groovy tương ứng.

Ví dụ sau cho thấy cách sử dụng JsonSlurper để phân tích cú pháp chuỗi JSON. Và ở đây bạn có thể thấy rằng JsonSlurper có thể phân tích cú pháp các mục riêng lẻ thành các kiểu nguyên thủy tương ứng của chúng.

import groovy.json.JsonSlurper 
class Example {

   static void main(String[] args) {
      def jsonSlurper = new JsonSlurper()
      def obj = jsonSlurper.parseText ''' {"Integer": 12, "fraction": 12.55, "double": 12e13}'''
		
      println(obj.Integer);
      println(obj.fraction);
      println(obj.double); 
   } 
}

Đầu ra của chương trình trên được đưa ra dưới đây:

12 
12.55 
1.2E+14

JsonOutput

Bây giờ chúng ta hãy nói về cách in đầu ra trong Json. Điều này có thể được thực hiện bằng phương thức JsonOutput. Phương thức này chịu trách nhiệm nối tiếp các đối tượng Groovy thành chuỗi JSON.

Cú pháp

Static string JsonOutput.toJson(datatype obj)

Parameters - Các tham số có thể là một đối tượng của kiểu dữ liệu - Số, Boolean, ký tự, Chuỗi, Ngày, Bản đồ, bao đóng, v.v.

Return type - Kiểu trả về là một chuỗi json.

Thí dụ

Sau đây là một ví dụ đơn giản về cách có thể đạt được điều này.

import groovy.json.JsonOutput 
class Example {
   static void main(String[] args) {
      def output = JsonOutput.toJson([name: 'John', ID: 1])
      println(output);  
   }
}

Đầu ra của chương trình trên được đưa ra dưới đây:

{"name":"John","ID":1}

JsonOutput cũng có thể được sử dụng cho các đối tượng trơn cũ. Trong ví dụ sau, bạn có thể thấy rằng chúng tôi đang thực sự chuyển các đối tượng kiểu Student sang phương thức JsonOutput.

import groovy.json.JsonOutput  
class Example {
   static void main(String[] args) {
      def output = JsonOutput.toJson([ new Student(name: 'John',ID:1),
         new Student(name: 'Mark',ID:2)])
      println(output);  
   } 
}
 
class Student {
   String name
   int ID; 
}

Đầu ra của chương trình trên được đưa ra dưới đây:

[{"name":"John","ID":1},{"name":"Mark","ID":2}]

Groovy cho phép người ta bỏ qua các dấu ngoặc đơn xung quanh các đối số của một lệnh gọi phương thức cho các câu lệnh cấp cao nhất. Đây được gọi là tính năng "chuỗi lệnh". Tiện ích mở rộng này hoạt động bằng cách cho phép một chuỗi các cuộc gọi phương thức không có dấu ngoặc đơn như vậy, không yêu cầu dấu ngoặc đơn xung quanh các đối số hoặc dấu chấm giữa các lệnh gọi chuỗi.

Nếu một cuộc gọi được thực hiện như a b c d, điều này thực sự sẽ tương đương với a(b).c(d).

Ngôn ngữ cụ thể của DSL hoặc Tên miền nhằm đơn giản hóa mã được viết bằng Groovy theo cách dễ hiểu đối với người dùng thông thường. Ví dụ sau đây cho thấy chính xác ý nghĩa của việc có một ngôn ngữ cụ thể cho miền.

def lst = [1,2,3,4] 
print lst

Đoạn mã trên hiển thị danh sách các số được in ra bảng điều khiển bằng cách sử dụng câu lệnh println. Trong một ngôn ngữ cụ thể của miền, các lệnh sẽ như sau:

Given the numbers 1,2,3,4
 
Display all the numbers

Vì vậy, ví dụ trên cho thấy sự chuyển đổi của ngôn ngữ lập trình để đáp ứng nhu cầu của một ngôn ngữ miền cụ thể.

Hãy xem một ví dụ đơn giản về cách chúng ta có thể triển khai DSL trong Groovy -

class EmailDsl {  
   String toText 
   String fromText 
   String body 
	
   /** 
   * This method accepts a closure which is essentially the DSL. Delegate the 
   * closure methods to 
   * the DSL class so the calls can be processed 
   */ 
   
   def static make(closure) { 
      EmailDsl emailDsl = new EmailDsl() 
      // any method called in closure will be delegated to the EmailDsl class 
      closure.delegate = emailDsl
      closure() 
   }
   
   /** 
   * Store the parameter as a variable and use it later to output a memo 
   */ 
	
   def to(String toText) { 
      this.toText = toText 
   }
   
   def from(String fromText) { 
      this.fromText = fromText 
   }
   
   def body(String bodyText) { 
      this.body = bodyText 
   } 
}

EmailDsl.make { 
   to "Nirav Assar" 
   from "Barack Obama" 
   body "How are things? We are doing well. Take care" 
}

Khi chúng ta chạy chương trình trên, chúng ta sẽ nhận được kết quả sau:

How are things? We are doing well. Take care

Cần lưu ý những điều sau đây về việc triển khai mã trên:

  • Một phương thức tĩnh được sử dụng để chấp nhận một bao đóng. Đây chủ yếu là một cách không phức tạp để triển khai DSL.

  • Trong ví dụ email, lớp EmailDsl có một phương thức make. Nó tạo ra một thể hiện và ủy quyền tất cả các lệnh gọi trong bao đóng cho thể hiện. Đây là cơ chế mà phần "đến" và "từ" kết thúc việc thực thi các phương thức bên trong lớp EmailDsl.

  • Khi phương thức to () được gọi, chúng tôi lưu trữ văn bản trong phiên bản để định dạng sau này.

  • Bây giờ chúng ta có thể gọi phương thức EmailDSL bằng một ngôn ngữ dễ hiểu, dễ hiểu cho người dùng cuối.

Mô-đun groovy-sql của Groovy cung cấp tính trừu tượng ở mức cao hơn so với công nghệ JDBC của Java hiện tại. Groovy sql API hỗ trợ nhiều loại cơ sở dữ liệu, một số trong số đó được hiển thị bên dưới.

  • HSQLDB
  • Oracle
  • Máy chủ SQL
  • MySQL
  • MongoDB

Trong ví dụ của chúng tôi, chúng tôi sẽ sử dụng MySQL DB làm ví dụ. Để sử dụng MySQL với Groovy, điều đầu tiên cần làm là tải xuống tệp jar MySQL jdbc từ trang web mysql.The format của MySQL sẽ được hiển thị bên dưới.

mysql-connector-java-5.1.38-bin

Sau đó, đảm bảo thêm tệp jar ở trên vào classpath trong máy trạm của bạn.

Kết nối cơ sở dữ liệu

Trước khi kết nối với cơ sở dữ liệu MySQL, hãy đảm bảo những điều sau:

  • Bạn đã tạo một cơ sở dữ liệu TESTDB.
  • Bạn đã tạo một bảng EMPLOYEE trong TESTDB.
  • Bảng này có các trường FIRST_NAME, LAST_NAME, AGE, SEX và THU NHẬP.
  • ID người dùng "testuser" và mật khẩu "test123" được đặt để truy cập TESTDB.
  • Đảm bảo bạn đã tải xuống tệp jar mysql và thêm tệp vào classpath của bạn.
  • Bạn đã xem qua hướng dẫn MySQL để hiểu Kiến thức cơ bản về MySQL

Ví dụ sau cho thấy cách kết nối với cơ sở dữ liệu MySQL "TESTDB".

import java.sql.*; 
import groovy.sql.Sql 

class Example {
   static void main(String[] args) {
      // Creating a connection to the database
      def sql = Sql.newInstance('jdbc:mysql://localhost:3306/TESTDB', 
         'testuser', 'test123', 'com.mysql.jdbc.Driver')
			
      // Executing the query SELECT VERSION which gets the version of the database
      // Also using the eachROW method to fetch the result from the database
   
      sql.eachRow('SELECT VERSION()'){ row ->
         println row[0]
      }
		
      sql.close()  
   } 
}

Trong khi chạy tập lệnh này, nó tạo ra kết quả sau:

5.7.10-log 
The Sql.newInstance method is used to establish a connection to the database.

Tạo bảng cơ sở dữ liệu

Bước tiếp theo sau khi kết nối với cơ sở dữ liệu là tạo các bảng trong cơ sở dữ liệu của chúng tôi. Ví dụ sau đây cho thấy cách tạo một bảng trong cơ sở dữ liệu bằng Groovy. Phương thức thực thi của lớp Sql được sử dụng để thực thi các câu lệnh đối với cơ sở dữ liệu.

import java.sql.*; 
import groovy.sql.Sql 

class Example { 
   static void main(String[] args) {
      // Creating a connection to the database
      def sql = Sql.newInstance('jdbc:mysql://localhost:3306/TESTDB', 'testuser',  
         'test123', 'com.mysql.jdbc.Driver')
			
      def sqlstr = """CREATE TABLE EMPLOYEE ( 
         FIRST_NAME CHAR(20) NOT NULL,
         LAST_NAME CHAR(20),
         AGE INT,
         SEX CHAR(1),
         INCOME FLOAT )""" 
							
      sql.execute(sqlstr);
      sql.close() 
   } 
}

Chèn hoạt động

Nó được yêu cầu khi bạn muốn tạo bản ghi của mình vào một bảng cơ sở dữ liệu.

Thí dụ

Ví dụ sau sẽ chèn một bản ghi trong bảng nhân viên. Mã được đặt trong một khối try catch để nếu bản ghi được thực thi thành công, giao dịch được cam kết với cơ sở dữ liệu. Nếu giao dịch không thành công, quá trình khôi phục được thực hiện.

import java.sql.*; 
import groovy.sql.Sql 

class Example {
   static void main(String[] args) { 
      // Creating a connection to the database
      def sql = Sql.newInstance('jdbc:mysql://localhost:3306/TESTDB', 'testuser', 
         'test123', 'com.mysql.jdbc.Driver')
			
      sql.connection.autoCommit = false
		
      def sqlstr = """INSERT INTO EMPLOYEE(FIRST_NAME,
         LAST_NAME, AGE, SEX, INCOME) VALUES ('Mac', 'Mohan', 20, 'M', 2000)""" 
      try {
         sql.execute(sqlstr);
         sql.commit()
         println("Successfully committed") 
      }catch(Exception ex) {
         sql.rollback()
         println("Transaction rollback") 
      }
		
      sql.close()
   } 
}

Giả sử nếu bạn muốn chỉ chọn các hàng nhất định dựa trên một tiêu chí. Đoạn mã sau đây cho biết cách bạn có thể thêm trình giữ chỗ tham số để tìm kiếm giá trị. Ví dụ trên cũng có thể được viết để nhận các tham số như trong đoạn mã sau. Biểu tượng $ được sử dụng để xác định một tham số sau đó có thể được thay thế bằng các giá trị khi câu lệnh sql được thực thi.

import java.sql.*; 
import groovy.sql.Sql
 
class Example {
   static void main(String[] args) {
      // Creating a connection to the database
      def sql = Sql.newInstance('jdbc:mysql://localhost:3306/TESTDB', 'testuser', 
         'test123', 'com.mysql.jdbc.Driver')
			
      sql.connection.autoCommit = false  
      
      def firstname = "Mac"
      def lastname ="Mohan"
      def age = 20
      def sex = "M"
      def income = 2000  
		
      def sqlstr = "INSERT INTO EMPLOYEE(FIRST_NAME,LAST_NAME, AGE, SEX, 
         INCOME) VALUES " + "(${firstname}, ${lastname}, ${age}, ${sex}, ${income} )"
			
      try {
         sql.execute(sqlstr);
         sql.commit()
         println("Successfully committed") 
      } catch(Exception ex) {
         sql.rollback()
         println("Transaction rollback")
      }
		
      sql.close()
   }
}

ĐỌC hoạt động

ĐỌC Hoạt động trên bất kỳ cơ sở dữ liệu nào có nghĩa là lấy một số thông tin hữu ích từ cơ sở dữ liệu. Khi kết nối cơ sở dữ liệu của chúng tôi được thiết lập, bạn đã sẵn sàng thực hiện truy vấn vào cơ sở dữ liệu này.

Thao tác đọc được thực hiện bằng cách sử dụng phương thức eachRow của lớp sql.

Cú pháp

eachRow(GString gstring, Closure closure)

Thực hiện truy vấn SQL đã cho gọi Closure đã cho với mỗi hàng của tập kết quả.

Parameters

  • Gstring - Câu lệnh sql cần được thực hiện.

  • Closure- Câu lệnh đóng để xử lý các hàng được lấy lại từ thao tác đọc. Thực hiện truy vấn SQL đã cho gọi Closure đã cho với mỗi hàng của tập kết quả.

Ví dụ mã sau đây cho thấy cách tìm nạp tất cả các bản ghi từ bảng nhân viên.

import java.sql.*; 
import groovy.sql.Sql
 
class Example {
   static void main(String[] args) {
      // Creating a connection to the database
      def sql = Sql.newInstance('jdbc:mysql://localhost:3306/TESTDB', 'testuser', 
         'test123', 'com.mysql.jdbc.Driver')  
			
      sql.eachRow('select * from employee') {
         tp -> 
         println([tp.FIRST_NAME,tp.LAST_NAME,tp.age,tp.sex,tp.INCOME])
      }  
		
      sql.close()
   } 
}

Kết quả từ chương trình trên sẽ là:

[Mac, Mohan, 20, M, 2000.0]

Cập nhật hoạt động

CẬP NHẬT Hoạt động trên bất kỳ cơ sở dữ liệu nào có nghĩa là cập nhật một hoặc nhiều bản ghi đã có sẵn trong cơ sở dữ liệu. Quy trình sau đây cập nhật tất cả các bản ghi có SEX là 'M'. Ở đây, chúng tôi tăng TUỔI của tất cả nam giới lên một năm.

import java.sql.*; 
import groovy.sql.Sql 

class Example {
   static void main(String[] args){
      // Creating a connection to the database
      def sql = Sql.newInstance('jdbc:mysql://localhost:3306/TESTDB', 'testuser', 
         'test@123', 'com.mysql.jdbc.Driver')
			
      sql.connection.autoCommit = false
      def sqlstr = "UPDATE EMPLOYEE SET AGE = AGE + 1 WHERE SEX = 'M'" 
	  
      try {
         sql.execute(sqlstr);
         sql.commit()
         println("Successfully committed")
      }catch(Exception ex) {
         sql.rollback() 
         println("Transaction rollback")
      }
		
      sql.close()
   } 
}

Thao tác DELETE

Thao tác DELETE là bắt buộc khi bạn muốn xóa một số bản ghi khỏi cơ sở dữ liệu của mình. Sau đây là quy trình để xóa tất cả các bản ghi khỏi NHÂN VIÊN có TUỔI trên 20.

import java.sql.*; 
import groovy.sql.Sql 

class Example {
   static void main(String[] args) {
      // Creating a connection to the database
      def sql = Sql.newInstance('jdbc:mysql://localhost:3306/TESTDB', 'testuser', 
         'test@123', 'com.mysql.jdbc.Driver')
			
      sql.connection.autoCommit = false
      def sqlstr = "DELETE FROM EMPLOYEE WHERE AGE > 20"
   
      try {
         sql.execute(sqlstr);
         sql.commit()
         println("Successfully committed")
      }catch(Exception ex) {
         sql.rollback()
         println("Transaction rollback")
      }
   
      sql.close()
   } 
}

Thực hiện giao dịch

Giao dịch là một cơ chế đảm bảo tính nhất quán của dữ liệu. Giao dịch có bốn thuộc tính sau:

  • Atomicity - Một giao dịch hoàn tất hoặc không có gì xảy ra cả.

  • Consistency - Một giao dịch phải bắt đầu ở trạng thái nhất quán và để hệ thống ở trạng thái nhất quán.

  • Isolation - Kết quả trung gian của một giao dịch không được hiển thị bên ngoài giao dịch hiện tại.

  • Durability - Một khi giao dịch đã được cam kết, các ảnh hưởng vẫn tồn tại, ngay cả sau khi hệ thống bị lỗi.

Đây là một ví dụ đơn giản về cách thực hiện các giao dịch. Chúng tôi đã xem ví dụ này từ chủ đề trước của chúng tôi về hoạt động XÓA.

def sqlstr = "DELETE FROM EMPLOYEE WHERE AGE > 20" 
 
try {
   sql.execute(sqlstr); 
   sql.commit()
   println("Successfully committed") 
}catch(Exception ex) {
   sql.rollback()
   println("Transaction rollback") 
} 
sql.close()

Cam kết hoạt động

Hoạt động cam kết là những gì yêu cầu cơ sở dữ liệu tiến hành trước hoạt động và hoàn thành tất cả các thay đổi đối với cơ sở dữ liệu.

Trong ví dụ trên của chúng tôi, điều này đạt được bằng câu lệnh sau:

sql.commit()

Thao tác khôi phục

Nếu bạn không hài lòng với một hoặc nhiều thay đổi và bạn muốn hoàn nguyên những thay đổi đó hoàn toàn, thì hãy sử dụng phương pháp khôi phục. Trong ví dụ trên của chúng tôi, điều này đạt được bằng câu lệnh sau:

sql.rollback()

Ngắt kết nối cơ sở dữ liệu

Để ngắt kết nối Cơ sở dữ liệu, hãy sử dụng phương pháp đóng.

sql.close()

Trong quá trình phát triển phần mềm, đôi khi các nhà phát triển dành nhiều thời gian để tạo cấu trúc dữ liệu, lớp miền, XML, bố cục GUI, luồng đầu ra, v.v. Và đôi khi mã được sử dụng để tạo các yêu cầu cụ thể này dẫn đến việc thay đổi lại cùng một đoạn mã mã ở nhiều nơi. Đây là lúc các nhà xây dựng Groovy phát huy tác dụng. Groovy có các trình xây dựng có thể được sử dụng để tạo các đối tượng và cấu trúc tiêu chuẩn. Các trình xây dựng này tiết kiệm thời gian vì nhà phát triển không cần viết mã của riêng họ để tạo các trình xây dựng này. Trong phần kết của chương này, chúng ta sẽ xem xét các trình xây dựng khác nhau có sẵn trong Groovy.

Người xây dựng xích đu

Trong Groovy, người ta cũng có thể tạo giao diện người dùng đồ họa bằng cách sử dụng các trình tạo swing có sẵn trong Groovy. Lớp chính để phát triển các thành phần swing là lớp SwingBuilder. Lớp này có nhiều phương thức để tạo các thành phần đồ họa như:

  • JFrame - Đây là để tạo phần tử khung.

  • JTextField - Điều này được sử dụng để tạo thành phần trường văn bản.

Hãy xem một ví dụ đơn giản về cách tạo một ứng dụng Swing bằng cách sử dụng lớp SwingBuilder. Trong ví dụ sau, bạn có thể thấy những điểm sau:

  • Bạn cần nhập các lớp groovy.swing.SwingBuilder và javax.swing. *.

  • Tất cả các thành phần được hiển thị trong ứng dụng Swing là một phần của lớp SwingBuilder.

  • Đối với chính khung, bạn có thể chỉ định vị trí và kích thước ban đầu của khung. Bạn cũng có thể chỉ định tiêu đề của khung.

  • Bạn cần đặt thuộc tính Visibility thành true để khung được hiển thị.

import groovy.swing.SwingBuilder 
import javax.swing.* 

// Create a builder 
def myapp = new SwingBuilder()

// Compose the builder 
def myframe = myapp.frame(title : 'Tutorials Point', location : [200, 200], 
   size : [400, 300], defaultCloseOperation : WindowConstants.EXIT_ON_CLOSE {         
      label(text : 'Hello world')
   } 
	
// The following  statement is used for displaying the form 
frame.setVisible(true)

Kết quả của chương trình trên được đưa ra dưới đây. Đầu ra sau đây hiển thị một JFrame cùng với một JLabel với nội dung Hello World.

Hãy xem ví dụ tiếp theo của chúng tôi để tạo màn hình nhập với các hộp văn bản. Trong ví dụ sau, chúng ta muốn tạo một biểu mẫu có các hộp văn bản cho Tên học sinh, môn học và Tên trường. Trong ví dụ sau, bạn có thể thấy những điểm chính sau:

  • Chúng tôi đang xác định bố cục cho các điều khiển của chúng tôi trên màn hình. Trong trường hợp này, chúng tôi đang sử dụng Bố cục Lưới.
  • Chúng tôi đang sử dụng thuộc tính căn chỉnh cho các nhãn của chúng tôi.
  • Chúng tôi đang sử dụng phương thức textField để hiển thị các hộp văn bản trên màn hình.
import groovy.swing.SwingBuilder 
import javax.swing.* 
import java.awt.*
 
// Create a builder 
def myapp = new SwingBuilder() 

// Compose the builder 
def myframe = myapp.frame(title : 'Tutorials Point', location : [200, 200], 
   size : [400, 300], defaultCloseOperation : WindowConstants.EXIT_ON_CLOSE) { 
      panel(layout: new GridLayout(3, 2, 5, 5)) { 
         label(text : 'Student Name:', horizontalAlignment : JLabel.RIGHT) 
         textField(text : '', columns : 10) 
			
         label(text : 'Subject Name:', horizontalAlignment : JLabel.RIGHT) 
         textField(text : '', columns : 10)
			
         label(text : 'School Name:', horizontalAlignment : JLabel.RIGHT) 
         textField(text : '', columns : 10) 
      } 
   } 
	
// The following  statement is used for displaying the form 
myframe.setVisible(true)

Đầu ra của chương trình trên được đưa ra dưới đây:

Trình xử lý sự kiện

Bây giờ chúng ta hãy xem xét các trình xử lý sự kiện. Trình xử lý sự kiện được sử dụng cho nút để thực hiện một số loại xử lý khi một nút được nhấn. Mỗi lệnh gọi giả hiệu nút bao gồm tham số actionPerformed. Điều này đại diện cho một khối mã được trình bày dưới dạng một bao đóng.

Hãy xem ví dụ tiếp theo để tạo một màn hình có 2 nút. Khi nhấn một trong hai nút, một thông báo tương ứng sẽ được gửi đến màn hình điều khiển. Trong ví dụ sau, bạn có thể thấy những điểm chính sau:

  • Đối với mỗi nút được xác định, chúng tôi đang sử dụng phương thức actionPerformed và xác định một lần đóng để gửi một số đầu ra đến bảng điều khiển khi nút được nhấp.

import groovy.swing.SwingBuilder 
import javax.swing.* 
import java.awt.* 

def myapp = new SwingBuilder()
  
def buttonPanel = {
   myapp.panel(constraints : BorderLayout.SOUTH) {
	
      button(text : 'Option A', actionPerformed : {
         println 'Option A chosen'
      })
		
      button(text : 'Option B', actionPerformed : {
         println 'Option B chosen'
      })
   }
}
  
def mainPanel = {
   myapp.panel(layout : new BorderLayout()) {
      label(text : 'Which Option do you want', horizontalAlignment : 
      JLabel.CENTER,
      constraints : BorderLayout.CENTER)
      buttonPanel()
   }
}
  
def myframe = myapp.frame(title : 'Tutorials Point', location : [100, 100],
   size : [400, 300], defaultCloseOperation : WindowConstants.EXIT_ON_CLOSE){
      mainPanel()
   }
	
myframe.setVisible(true)

Kết quả của chương trình trên được đưa ra dưới đây. Khi bạn nhấp vào một trong hai nút, thông báo bắt buộc sẽ được gửi đến màn hình nhật ký bảng điều khiển.

Một biến thể khác của ví dụ trên là xác định các phương thức có thể hoạt động như trình xử lý. Trong ví dụ sau, chúng tôi đang xác định 2 trình xử lý DisplayA và DisplayB.

import groovy.swing.SwingBuilder 
import javax.swing.* 
import java.awt.* 

def myapp = new SwingBuilder()
  
def DisplayA = {
   println("Option A") 
} 

def DisplayB = {
   println("Option B")
}

def buttonPanel = {
   myapp.panel(constraints : BorderLayout.SOUTH) {
      button(text : 'Option A', actionPerformed : DisplayA) 
      button(text : 'Option B', actionPerformed : DisplayB)
   }
}  

def mainPanel = {
   myapp.panel(layout : new BorderLayout()) {
      label(text : 'Which Option do you want', horizontalAlignment : JLabel.CENTER,
      constraints : BorderLayout.CENTER)
      buttonPanel()
   }
}  

def myframe = myapp.frame(title : 'Tutorials Point', location : [100, 100],
   size : [400, 300], defaultCloseOperation : WindowConstants.EXIT_ON_CLOSE) {
      mainPanel()
   } 
	
myframe.setVisible(true)

Đầu ra của chương trình trên sẽ vẫn giống như ví dụ trước đó.

Trình tạo DOM

Trình tạo DOM có thể được sử dụng để phân tích cú pháp HTML, XHTML và XML và chuyển đổi nó thành cây DOM W3C.

Ví dụ sau cho thấy cách sử dụng trình tạo DOM.

String records = '''
   <library>
	
      <Student>
         <StudentName division = 'A'>Joe</StudentName>
         <StudentID>1</StudentID>
      </Student>
	  
      <Student>
         <StudentName division = 'B'>John</StudentName>
         <StudentID>2</StudentID>
      </Student>
	  
      <Student>
         <StudentName division = 'C'>Mark</StudentName>
         <StudentID>3</StudentID>
      </Student>
		
   </library>'''
   
def rd = new StringReader(records) 
def doc = groovy.xml.DOMBuilder.parse(rd)

JsonBuilder

JsonBuilder được sử dụng để tạo các đối tượng kiểu json.

Ví dụ sau đây cho thấy cách sử dụng trình tạo Json.

def builder = new groovy.json.JsonBuilder() 

def root = builder.students {
   student {
      studentname 'Joe'
      studentid '1'
		
      Marks(
         Subject1: 10,
         Subject2: 20,
         Subject3:30,
      )
   } 
} 
println(builder.toString());

Kết quả của chương trình trên được đưa ra dưới đây. Kết quả clearlt đầu ra cho thấy Jsonbuilder đã có thể xây dựng đối tượng json từ một tập hợp các nút có cấu trúc.

{"students":{"student":{"studentname":"Joe","studentid":"1","Marks":{"Subject1":10,
"S ubject2":20,"Subject3":30}}}}

Jsonbuilder cũng có thể lấy một danh sách và chuyển đổi nó thành một đối tượng json. Ví dụ sau đây cho thấy cách này có thể được thực hiện.

def builder = new groovy.json.JsonBuilder() 
def lst = builder([1, 2, 3]) 
println(builder.toString());

Kết quả của chương trình trên được đưa ra dưới đây.

[1,2,3]

JsonBuilder cũng có thể được sử dụng cho các lớp. Ví dụ sau đây cho thấy cách các đối tượng của một lớp có thể trở thành đầu vào cho trình tạo json.

def builder = new groovy.json.JsonBuilder() 

class Student {
   String name  
} 

def studentlist = [new Student (name: "Joe"), new Student (name: "Mark"), 
   new Student (name: "John")] 
	
builder studentlist, { Student student ->name student.name} 
println(builder)

Kết quả của chương trình trên được đưa ra dưới đây.

[{"name":"Joe"},{"name":"Mark"},{"name":"John"}]

NodeBuilder

NodeBuilder được sử dụng để tạo cây lồng nhau của các đối tượng Node để xử lý dữ liệu tùy ý. Dưới đây là một ví dụ về cách sử dụng Nodebuilder.

def nodeBuilder = new NodeBuilder() 

def studentlist = nodeBuilder.userlist {
   user(id: '1', studentname: 'John', Subject: 'Chemistry')
   user(id: '2', studentname: 'Joe', Subject: 'Maths')
   user(id: '3', studentname: 'Mark', Subject: 'Physics') 
} 

println(studentlist)

FileTreeBuilder

FileTreeBuilder là một trình xây dựng để tạo cấu trúc thư mục tệp từ một đặc tả. Sau đây là một ví dụ về cách sử dụng FileTreeBuilder.

tmpDir = File.createTempDir() 
def fileTreeBuilder = new FileTreeBuilder(tmpDir) 

fileTreeBuilder.dir('main') {
   dir('submain') {
      dir('Tutorial') {
        file('Sample.txt', 'println "Hello World"')
      }
   } 
}

Từ việc thực thi đoạn mã trên, một tệp có tên là sample.txt sẽ được tạo trong thư mục main / submain / Tutorial. Và tệp sample.txt sẽ có nội dung là “Hello World”.

Groovy shell được gọi là groovysh có thể dễ dàng được sử dụng để đánh giá các biểu thức groovy, định nghĩa các lớp và chạy các chương trình đơn giản. Trình bao dòng lệnh được cài đặt khi Groovy được cài đặt.

Sau đây là các tùy chọn dòng lệnh có sẵn trong Groovy:

Tham số dòng lệnh Họ và tên Chi tiết
-C --color [= FLAG] Bật hoặc tắt sử dụng màu ANSI
-D --define = NAME = VALUE Xác định thuộc tính hệ thống
-T --terminal = TYPE Chỉ định TYPE đầu cuối để sử dụng
-V --phiên bản Hiển thị phiên bản
-classpath Chỉ định nơi tìm tệp lớp - phải là đối số đầu tiên
-cp --classpath Bí danh cho '-classpath'
-d --debug --debug Bật đầu ra gỡ lỗi
-e --evaluate = arg Đánh giá nắm đấm tùy chọn khi bắt đầu phiên tương tác
-h --Cứu giúp Hiển thị thông báo trợ giúp này
-q --Yên tĩnh Ngăn chặn sản lượng thừa
-v --verbose Bật đầu ra dài dòng

Ảnh chụp nhanh sau đây cho thấy một ví dụ đơn giản về một biểu thức đang được thực thi trong Groovy shell. Trong ví dụ dưới đây, chúng tôi chỉ in “Hello World” trong lớp vỏ linh hoạt.

Lớp và Chức năng

Rất dễ dàng để xác định một lớp trong dấu nhắc lệnh, tạo một đối tượng mới và gọi một phương thức trên lớp đó. Ví dụ sau cho thấy cách này có thể được thực hiện. Trong ví dụ sau, chúng ta đang tạo một lớp Sinh viên đơn giản với một phương thức đơn giản. Trong chính dấu nhắc lệnh, chúng ta đang tạo một đối tượng của lớp và gọi phương thức Display.

Rất dễ dàng để xác định một phương thức trong dấu nhắc lệnh và gọi phương thức đó. Lưu ý rằng phương thức được định nghĩa bằng kiểu def. Cũng lưu ý rằng chúng tôi đã bao gồm một tham số được gọi là tên sau đó được thay thế bằng giá trị thực khi phương thức Hiển thị được gọi. Ví dụ sau cho thấy cách này có thể được thực hiện.

Lệnh

Trình bao có một số lệnh khác nhau, cung cấp khả năng truy cập phong phú vào môi trường của trình bao. Sau đây là danh sách của họ và những gì họ làm.

Sr.No Lệnh & smp; Mô tả lệnh
1

:help

(: h) Hiển thị thông báo trợ giúp này

2

?

(:?) Bí danh:: help

3

:exit

(: x) Thoát khỏi trình bao

4

:quit

(: q) Bí danh đến:: exit

5

import

(: i) Nhập một lớp vào không gian tên

6

:display

(: d) Hiển thị bộ đệm hiện tại

7

:clear

(: c) Xóa bộ đệm và đặt lại bộ đếm lời nhắc

số 8

:show

(: S) Hiển thị các biến, lớp hoặc nhập

9

:inspect

(: n) Kiểm tra một biến hoặc kết quả cuối cùng bằng trình duyệt đối tượng GUI

10

:purge

(: p) Xóa biến, lớp, nhập hoặc tùy chọn

11

:edit

(: e) Chỉnh sửa bộ đệm hiện tại

12

:load

(: l) Tải tệp hoặc URL vào bộ đệm

13

.

(:.) Bí danh thành:: load

14

.save

(: s) Lưu bộ đệm hiện tại vào một tệp

15

.record

(: r) Ghi lại phiên hiện tại vào một tệp

16

:alias

(: a) Tạo bí danh

17

:set

(: =) Đặt (hoặc liệt kê) tùy chọn

18

:register

(: rc) Đăng ký một lệnh mới với shell

19

:doc

(: D) Mở cửa sổ trình duyệt hiển thị tài liệu cho đối số

20

:history

(: H) Hiển thị, quản lý và nhớ lại lịch sử dòng chỉnh sửa

Đơn vị cơ bản của hệ thống hướng đối tượng là lớp. Do đó, kiểm thử đơn vị bao gồm thử nghiệm trong một lớp. Cách tiếp cận được thực hiện là tạo một đối tượng của lớp đang được thử nghiệm và sử dụng nó để kiểm tra xem các phương thức đã chọn có thực thi như mong đợi hay không. Không phải mọi phương pháp đều có thể được kiểm tra, vì không phải lúc nào việc kiểm tra từng thứ và mọi thứ đều thực tế. Nhưng kiểm tra đơn vị nên được tiến hành cho các phương pháp quan trọng và quan trọng.

JUnit là một khuôn khổ kiểm thử mã nguồn mở, là tiêu chuẩn công nghiệp được chấp nhận để kiểm tra đơn vị tự động của mã Java. May mắn thay, khung công tác JUnit có thể dễ dàng được sử dụng để kiểm tra các lớp Groovy. Tất cả những gì được yêu cầu là mở rộng lớp GroovyTestCase là một phần của môi trường Groovy tiêu chuẩn. Lớp trường hợp thử nghiệm Groovy dựa trên trường hợp thử nghiệm Junit.

Viết một trường hợp thử nghiệm Junit đơn giản

Giả sử chúng ta có lớp sau được định nghĩa trong tệp lớp ứng dụng:

class Example {
   static void main(String[] args) {
      Student mst = new Student();
      mst.name = "Joe";
      mst.ID = 1;
      println(mst.Display())
   } 
} 
 
public class Student {
   String name;
   int ID;
	
   String Display() {
      return name +ID;
   }  
}

Kết quả của chương trình trên được đưa ra dưới đây.

Joe1

Và bây giờ giả sử chúng ta muốn viết một trường hợp thử nghiệm cho lớp Sinh viên. Một trường hợp thử nghiệm điển hình sẽ giống như bên dưới. Các điểm sau đây cần được lưu ý về mã sau:

  • Lớp test case mở rộng lớp GroovyTestCase
  • Chúng tôi đang sử dụng câu lệnh khẳng định để đảm bảo rằng phương thức Hiển thị trả về đúng chuỗi.
class StudentTest extends GroovyTestCase {
   void testDisplay() {
      def stud = new Student(name : 'Joe', ID : '1')
      def expected = 'Joe1'
      assertToString(stud.Display(), expected)
   }
}

Bộ thử nghiệm Groovy

Thông thường khi số lượng bài kiểm tra đơn vị tăng lên, sẽ trở nên khó khăn để tiếp tục thực hiện tất cả các trường hợp kiểm thử một. Do đó Groovy cung cấp một cơ sở để tạo một bộ thử nghiệm có thể đóng gói tất cả các trường hợp thử nghiệm thành một đơn vị logic. Đoạn mã sau đây cho thấy cách đạt được điều này. Những điều sau đây cần được lưu ý về mã:

  • GroovyTestSuite được sử dụng để đóng gói tất cả các trường hợp thử nghiệm thành một.

  • Trong ví dụ sau, chúng tôi giả định rằng chúng tôi có hai tệp trường hợp kiểm tra, một tệp được gọi là StudentTest và cái kia là EmployeeTest trong đó có tất cả các thử nghiệm cần thiết.

import groovy.util.GroovyTestSuite 
import junit.framework.Test 
import junit.textui.TestRunner 

class AllTests { 
   static Test suite() { 
      def allTests = new GroovyTestSuite() 
      allTests.addTestSuite(StudentTest.class) 
      allTests.addTestSuite(EmployeeTest.class) 
      return allTests 
   } 
} 

TestRunner.run(AllTests.suite())

Công cụ mẫu của Groovy hoạt động giống như kết hợp thư (tự động thêm tên và địa chỉ từ cơ sở dữ liệu vào thư và phong bì để tạo điều kiện gửi thư, đặc biệt là quảng cáo, đến nhiều địa chỉ) nhưng nó chung chung hơn nhiều.

Tạo mẫu đơn giản trong chuỗi

Nếu bạn lấy ví dụ đơn giản bên dưới, trước tiên chúng ta đang xác định một biến tên để chứa chuỗi “Groovy”. Trong câu lệnh println, chúng ta đang sử dụng biểu tượng $ để xác định một tham số hoặc mẫu nơi một giá trị có thể được chèn vào.

def name = "Groovy" 
println "This Tutorial is about ${name}"

Nếu đoạn mã trên được thực thi trong Groovy, kết quả sau sẽ được hiển thị. Kết quả cho thấy rõ ràng rằng $ name đã được thay thế bằng giá trị được gán bởi câu lệnh def.

Công cụ mẫu đơn giản

Sau đây là một ví dụ về SimpleTemplateEngine cho phép bạn sử dụng các script giống như JSP và các biểu thức EL trong mẫu của bạn để tạo văn bản được tham số hóa. Công cụ tạo khuôn mẫu cho phép bạn liên kết danh sách các tham số và giá trị của chúng để có thể thay thế chúng trong chuỗi có trình giữ chỗ đã xác định.

def text ='This Tutorial focuses on $TutorialName. In this tutorial you will learn 

about $Topic'  

def binding = ["TutorialName":"Groovy", "Topic":"Templates"]  
def engine = new groovy.text.SimpleTemplateEngine() 
def template = engine.createTemplate(text).make(binding) 

println template

Nếu đoạn mã trên được thực thi trong Groovy, kết quả sau sẽ được hiển thị.

Bây giờ hãy sử dụng tính năng tạo khuôn mẫu cho tệp XML. Bước đầu tiên, hãy thêm đoạn mã sau vào một tệp có tên là Student.template. Trong tệp sau, bạn sẽ nhận thấy rằng chúng tôi đã không thêm các giá trị thực tế cho các phần tử, mà là các phần giữ chỗ. Vì vậy, $ name,$is and $tất cả chủ đề đều được đặt làm trình giữ chỗ sẽ cần được thay thế trong thời gian chạy.

<Student> 
   <name>${name}</name> <ID>${id}</ID> 
   <subject>${subject}</subject> 
</Student>

Bây giờ, hãy thêm mã tập lệnh Groovy của chúng tôi để thêm chức năng có thể được sử dụng để thay thế mẫu trên bằng các giá trị thực tế. Những điều sau đây cần được lưu ý về đoạn mã sau.

  • Việc ánh xạ các trình giữ chỗ với các giá trị thực tế được thực hiện thông qua một liên kết và một SimpleTemplateEngine. Ràng buộc là một Bản đồ với phần giữ vị trí là khóa và phần thay thế là giá trị.

import groovy.text.* 
import java.io.* 

def file = new File("D:/Student.template") 
def binding = ['name' : 'Joe', 'id' : 1, 'subject' : 'Physics']
				  
def engine = new SimpleTemplateEngine() 
def template = engine.createTemplate(file) 
def writable = template.make(binding) 

println writable

Nếu đoạn mã trên được thực thi trong Groovy, kết quả sau sẽ được hiển thị. Từ kết quả đầu ra, có thể thấy rằng các giá trị được thay thế thành công trong các trình giữ chỗ có liên quan.

<Student> 
   <name>Joe</name> 
   <ID>1</ID> 
   <subject>Physics</subject> 
</Student>

StreamingTemplateEngine

Công cụ StreamingTemplateEngine là một công cụ tạo khuôn mẫu khác có sẵn trong Groovy. Đây là loại tương đương với SimpleTemplateEngine, nhưng tạo mẫu bằng cách sử dụng các bao đóng có thể ghi, làm cho nó có thể mở rộng hơn cho các mẫu lớn. Cụ thể công cụ mẫu này có thể xử lý các chuỗi lớn hơn 64k.

Sau đây là một ví dụ về cách StreamingTemplateEngine được sử dụng:

def text = '''This Tutorial is <% out.print TutorialName %> The Topic name 

is ${TopicName}''' 
def template = new groovy.text.StreamingTemplateEngine().createTemplate(text)
  
def binding = [TutorialName : "Groovy", TopicName  : "Templates",]
String response = template.make(binding) 
println(response)

Nếu đoạn mã trên được thực thi trong Groovy, kết quả sau sẽ được hiển thị.

This Tutorial is Groovy The Topic name is Templates

XMLTemplateEngine

XmlTemplateEngine được sử dụng trong các kịch bản tạo mẫu trong đó cả nguồn mẫu và đầu ra dự kiến ​​đều là XML. Mẫu sử dụng bình thường${expression} and $ký hiệu biến để chèn một biểu thức tùy ý vào mẫu.

Sau đây là một ví dụ về cách sử dụng XMLTemplateEngine.

def binding = [StudentName: 'Joe', id: 1, subject: 'Physics'] 
def engine = new groovy.text.XmlTemplateEngine() 

def text = '''\
   <document xmlns:gsp='http://groovy.codehaus.org/2005/gsp'>
      <Student>
         <name>${StudentName}</name> <ID>${id}</ID>
         <subject>${subject}</subject>
      </Student>
   </document> 
''' 

def template = engine.createTemplate(text).make(binding) 
println template.toString()

Nếu đoạn mã trên được thực thi trong Groovy, kết quả sau sẽ được hiển thị

Joe
    
    
   1
    
    
   Physics

Lập trình đối tượng meta hoặc MOP có thể được sử dụng để gọi động các phương thức và cũng có thể tạo các lớp và phương thức một cách nhanh chóng.

Vì vậy, điều này có nghĩa là gì? Hãy xem xét một lớp được gọi là Sinh viên, là một lớp trống không có biến hoặc phương thức thành viên. Giả sử nếu bạn phải gọi các câu lệnh sau trên lớp này.

Def myStudent = new Student() 
myStudent.Name = ”Joe”; 
myStudent.Display()

Bây giờ trong lập trình đối tượng meta, mặc dù lớp không có tên biến thành viên hoặc phương thức Display (), đoạn mã trên vẫn hoạt động.

Làm thế nào điều này có thể hoạt động? Để điều này diễn ra tốt đẹp, người ta phải triển khai giao diện GroovyInterceptable để kết nối vào quá trình thực thi của Groovy. Sau đây là các phương pháp có sẵn cho giao diện này.

Public interface GroovyInterceptable { 
   Public object invokeMethod(String methodName, Object args) 
   Public object getproperty(String propertyName) 
   Public object setProperty(String propertyName, Object newValue) 
   Public MetaClass getMetaClass() 
   Public void setMetaClass(MetaClass metaClass) 
}

Vì vậy, trong mô tả giao diện ở trên, giả sử nếu bạn phải triển khai invokeMethod (), nó sẽ được gọi cho mọi phương thức tồn tại hoặc không tồn tại.

Thiếu thuộc tính

Vì vậy, hãy xem một ví dụ về cách chúng ta có thể triển khai Lập trình đối tượng Meta cho các Thuộc tính bị thiếu. Những điều quan trọng sau đây cần được lưu ý về mã sau.

  • Lớp Sinh viên không có biến thành viên được gọi là Tên hoặc ID được xác định.

  • Lớp Sinh viên triển khai giao diện GroovyInterceptable.

  • Có một tham số gọi là dynamicProps sẽ được sử dụng để giữ giá trị của các biến thành viên được tạo nhanh chóng.

  • Các phương thức getproperty và setproperty đã được triển khai để lấy và thiết lập các giá trị của thuộc tính của lớp trong thời gian chạy.

class Example {
   static void main(String[] args) {
      Student mst = new Student();
      mst.Name = "Joe";
      mst.ID = 1;
		
      println(mst.Name);
      println(mst.ID);
   }
}

class Student implements GroovyInterceptable { 
   protected dynamicProps=[:]
	
   void setProperty(String pName,val) {
      dynamicProps[pName] = val
   }
   
   def getProperty(String pName) {
      dynamicProps[pName]
   } 
}

Đầu ra của đoạn mã sau sẽ là:

Joe 
1

Thiếu phương pháp

Vì vậy, hãy xem một ví dụ về cách chúng ta có thể triển khai Lập trình đối tượng Meta cho các Thuộc tính bị thiếu. Những điều quan trọng sau đây cần được lưu ý về mã sau:

  • Lớp Student bây giờ áp dụng phương thức invokeMethod được gọi bất kể phương thức đó có tồn tại hay không.

class Example {
   static void main(String[] args) {
      Student mst = new Student();
      mst.Name = "Joe";
      mst.ID = 1;
		
      println(mst.Name);
      println(mst.ID);
      mst.AddMarks();
   } 
}
 
class Student implements GroovyInterceptable {
   protected dynamicProps = [:]  
    
   void setProperty(String pName, val) {
      dynamicProps[pName] = val
   } 
   
   def getProperty(String pName) {
      dynamicProps[pName]
   }
   
   def invokeMethod(String name, Object args) {
      return "called invokeMethod $name $args"
   }
}

Đầu ra của mã sau đây sẽ được hiển thị bên dưới. Lưu ý rằng không có lỗi thiếu Phương thức Ngoại lệ mặc dù Phương thức Hiển thị không tồn tại.

Joe 
1

Metaclass

Chức năng này liên quan đến việc triển khai MetaClass. Trong triển khai mặc định, bạn có thể truy cập vào các trường mà không cần gọi getters và setters của chúng. Ví dụ sau đây cho thấy bằng cách sử dụng hàm metaClass, chúng ta có thể thay đổi giá trị của các biến private trong lớp.

class Example {
   static void main(String[] args) {
      Student mst = new Student();
      println mst.getName()
      mst.metaClass.setAttribute(mst, 'name', 'Mark')
      println mst.getName()
   } 
} 

class Student {
   private String name = "Joe";
	
   public String getName() {
      return this.name;
   } 
}

Đầu ra của đoạn mã sau sẽ là:

Joe 
Mark

Phương thức bị thiếu

Groovy ủng hộ khái niệm methodMissing. Phương thức này khác với invokeMethod ở chỗ nó chỉ được gọi trong trường hợp gửi phương thức không thành công, khi không thể tìm thấy phương thức nào cho tên đã cho và / hoặc các đối số đã cho. Ví dụ sau cho thấy cách methodMissing có thể được sử dụng.

class Example {
   static void main(String[] args) {
      Student mst = new Student();
      mst.Name = "Joe";
      mst.ID = 1;
		
      println(mst.Name);
      println(mst.ID);
      mst.AddMarks();
   } 
} 

class Student implements GroovyInterceptable {
   protected dynamicProps = [:]  
    
   void setProperty(String pName, val) {
      dynamicProps[pName] = val
   }
   
   def getProperty(String pName) {
      dynamicProps[pName]
   }
   
   def methodMissing(String name, def args) {         
      println "Missing method"
   }  
}

Đầu ra của đoạn mã sau sẽ là:

Joe 
1 
Missing method