Mã luôn là dữ liệu! Các hướng dẫn bytecode cho một chương trình được lưu trữ trong bộ nhớ. Lập trình viên không có quyền truy cập đọc và ghi trực tiếp vào bộ nhớ này, nhưng nó ở đó.
Khi chúng ta nói về "xử lý" mã dưới dạng dữ liệu, chúng tôi tham khảo lưu trữ các tham chiếu đến bộ nhớ đó theo cách nó có thể được sử dụng và sắp xếp theo cách chúng ta thường nghĩ về "dữ liệu".
Ví dụ, người ta có thể tưởng tượng rằng bên button
nó trông giống như sau:
class Button {
private ActionListener[] listeners = new ActionListener[100];
private int count = 0;
public void addActionListener(ActionListener listener) {
listeners[count] = listener;
++count;
}
// called somehow when the button is clicked
void notifyListeners() {
ActionEvent theEvent = new ActionEvent(...);
for(int i = 0; i < count; ++i) {
listeners[i].actionPerformed(theEvent);
}
}
}
Về cơ bản Button
là giữ một danh sách các chức năng trong một mảng: đây là đối xử với mã như dữ liệu. Trong hầu hết các trường hợp, ActionListener
không phục vụ mục đích nào khác ngoại trừ việc chỉ định một ghi đè cụ thể của actionPerformed
.
Vì tất cả các phương pháp thể hiện Java là ảo, chúng tôi luôn có thể coi mã là dữ liệu. Điều này được thể hiện bằng khung lắng nghe sự kiện phức tạp của AWT/Swing. Các biểu thức Lambda chỉ thêm nhấn mạnh khái niệm và cú pháp ngắn. (Ngoài ra một hiệu suất đạt được trong hầu hết các tình huống do thực hiện của họ.)
Lambdas cho phép chúng tôi thể hiện rõ hơn ý định của mình khi chúng tôi đang sử dụng một đối tượng chỉ để thực hiện một phương pháp cụ thể.
Về mặt kỹ thuật, điều này được thực hiện thông qua vô hướng. An ActionListener
không giữ mã: thay vào đó, máy ảo biết bằng cách nào đó (rằng chúng tôi không phải là riêng) mà nó trỏ đến một cấu trúc cụ thể trong bộ nhớ mà giữ một con trỏ đến mã. Vì vậy, một số loại tham chiếu đến mã là những gì thực sự được truyền đi xung quanh, do đó "xử lý mã làm dữ liệu".
Tôi đoán rằng nó đề cập đến việc truyền xung quanh một phương thức như một giá trị, mà lambdas mang đến cho ảo giác về việc làm. Các giá trị được xem là dữ liệu và "mã" có thể đề cập đến khối mã là phương thức –
Trông giống như bất kỳ ngôn ngữ chức năng nào xử lý các hàm như _prime class citizens_ (khái niệm để cung cấp hàm như đầu vào cho hàm khác). Ví dụ này với tôi trông khá lộn xộn, các ngôn ngữ khác có chức năng hoặc lai-chức năng làm một công việc tốt hơn với cú pháp, hãy kiểm tra Scala ví dụ (mà vẫn còn dựa trên JVM). – Marcs
"Mã dưới dạng dữ liệu" là khẩu hiệu không có nghĩa là bất kỳ điều gì bạn chưa biết. – immibis