Làm cách nào để biên dịch JavaScript sang Java?

> Điều bạn muốn thực sự không thể thực hiện được. Java không phải là javascript. Lấy ví dụ
> của bạn để minh họa vấn đề ở đây. Làm thế nào mà thậm chí
> dịch sang javascript? . Nó có
> kế thừa dựa trên nguyên mẫu. Đây là những vấn đề cơ bản của bạn.

Reinier, cảm ơn vì thông tin. Thực ra, lớp học không phải là thứ
sau. Những gì tôi thực sự muốn tạo ra là các đối tượng. Vì vậy, tôi nghĩ rằng nó có thể
dịch một cái gì đó như thế này.


...

.

.

Tôi đang thiếu gì?


>  1. Mô hình đối tượng và không gian đặt tên của Javascript quá khác biệt nên
> Nội tại GWT tạo ra các tên hoàn toàn khác và khó sử dụng cho
> đối tượng và lớp. Những tên này sau đó được xáo trộn thành mã ngắn
> không thể nhận dạng để giảm kích thước của JS đầu ra. Vì vậy, phương thức xin chào public void
> của bạn sẽ được gọi. "com. gói của tôi. Xin chào. talk
> ()" (có, bao gồm cả dấu đóng ngoặc đơn để cho biết rằng phiên bản này
> không có tham số; không giống như javascript, trong java có hai phương thức với
> same name but different parameter lists are completely separate, in
> javascript you can't do that), or it's going to be called something
> small and effectively random, so something like 'xYq' or some such.
> Không có mã để chọn một tên lành mạnh cho tương tác, vì vậy không có gì ở đó
> thậm chí chỉ nghĩ đến việc tạo ra một hàm có tên là "xin chào".

Tôi nghĩ có thể tắt xáo trộn bằng cách đặt cờ
trình biên dịch. Tôi cũng đã đọc về JSNI trong ngữ cảnh này. Một hoặc cả hai
những điều này sẽ không giúp ích gì?


>  2. Có một bộ chức năng cơ bản mà tất cả các dự án GWT bắt đầu
> với. Trình biên dịch GWT giả định cơ sở này là có.

Đó sẽ không phải là một vấn đề đối với tôi


>  3. GWT thực hiện một việc gọi là nhắm mục tiêu theo nền tảng. Đó là lý do tại sao nó
> tạo ra một số tệp JS - một tệp cho mỗi nền tảng đích. Ngoài
> hộp, đã có nhiều nền tảng (1 nền tảng cho mỗi
> trình duyệt được hỗ trợ chính, vì vậy có Opera, IE, Gecko và .
> Tôi không hoàn toàn chắc chắn nhưng tôi tin rằng cơ sở, được đề cập ở #2,
> đã được viết riêng cho từng nền tảng trình duyệt mục tiêu.

Cũng không thành vấn đề


> Nếu bạn đang tìm kiếm thị trường để xây dựng một công cụ như vậy, Nguồn GWT là
> nơi tuyệt vời để bắt đầu, nhưng trừ khi bạn sẵn sàng tìm hiểu một số .
> weeks and do a lot of dev work, I don't think GWT can do what you
> want.

Nghe quá đỉnh đầu tôi. Tuy nhiên, tôi phải nói rằng - tôi rất ngạc nhiên
điều này vẫn chưa được thực hiện. Có vẻ như cách sử dụng
GWT quá rõ ràng.

Một tính năng chính của Google Web Toolkit (GWT) là nó cho phép các nhà phát triển viết các ứng dụng Web được lưu trữ trên trình duyệt hoàn toàn bằng Java và yêu cầu GWT dịch mã Java đó sang JavaScript dành riêng cho trình duyệt. Trong cuộc phỏng vấn này với Artima, Scott Blum, kỹ sư phần mềm của Google đứng sau trình biên dịch Java-to-JavaScript của GWT, nói về những thách thức của việc biến mã nguồn Java thành JavaScript

Tuần trước, Google đã thông báo rằng họ đã hoàn toàn mã nguồn mở Google Web Toolkit, hay GWT, một bộ công cụ cho phép các nhà phát triển Java mã hóa các ứng dụng tương tác, dựa trên trình duyệt bằng Java, sau đó để GWT tự động chuyển đổi ứng dụng Java đó thành

Trọng tâm của GWT là trình biên dịch Java-to-JavaScript thực hiện phân tích tĩnh mở rộng trên các tệp nguồn Java, sau đó xuất ra các bản dịch JavaScript được tối ưu hóa cao của mã nguồn Java. Đầu ra của trình biên dịch được điều chỉnh để đáp ứng các đặc điểm riêng của bốn trình duyệt Web phổ biến nhất được sử dụng hiện nay. Artima đã nói chuyện với Scott Blum, kỹ sư phần mềm của Google đứng sau trình biên dịch Java-to-JavaScript của GWT

Frank Sommers. Bạn có thể bắt đầu bằng cách cung cấp cho chúng tôi tổng quan về quy trình phát triển GWT không?

Scott Blum. Ý tưởng cơ bản là bạn viết ứng dụng của mình bằng Java, gỡ lỗi bằng Java, sau đó trình biên dịch của chúng tôi lấy chương trình Java của bạn và biến nó thành JavaScript

Để cho phép chúng tôi thực hiện nhiều tối ưu hóa, chiến lược cơ bản mà trình biên dịch sử dụng là biên dịch nguyên khối. Đó là câu thần chú của chúng tôi. Chúng tôi tìm ra tập hợp chính xác và đầy đủ các lớp trong ứng dụng của bạn, cũng như vị trí của điểm vào ứng dụng của bạn và chúng tôi sử dụng hệ thống ràng buộc đó để cho phép chúng tôi thực hiện nhiều tối ưu hóa thực sự gọn gàng

Ví dụ: giả sử bạn có một ứng dụng được viết theo giao diện List, bởi vì bạn là một nhà phát triển hướng đối tượng giỏi và sử dụng các kiểu trừu tượng. Nhưng giả sử rằng bạn chỉ khởi tạo ArrayList dưới dạng triển khai cụ thể của List. Ở mọi nơi chúng tôi thực hiện cuộc gọi đến một phương thức List, tại thời điểm biên dịch, chúng tôi phát hiện ra rằng đó thực sự là một cuộc gọi đến một phương thức ArrayList và trong trường hợp phù hợp, chúng tôi thực sự nội tuyến cuộc gọi đó

Có lẽ lợi thế lớn nhất mang lại cho bảng là khi chúng tôi biên dịch cho các nền tảng khác nhau. chúng tôi chỉ mang đến các lớp dành riêng cho nền tảng đó. Ví dụ: khi chúng tôi biên dịch cho Firefox, chúng tôi chỉ đưa triển khai DOM cho Firefox vào trình biên dịch. Điều đó làm giảm kích thước mã, đây là điều rất quan trọng đối với chúng tôi

Frank Sommers. Sự khác biệt lớn nhất trong JavaScript mà GWT tạo ra cho các trình duyệt khác nhau là gì?

Scott Blum. Hóa ra ở cấp độ ngôn ngữ, hầu hết các trình duyệt đều khá đồng nhất. Bản thân mô hình lập trình JavaScript thực tế được triển khai khá nhất quán. Chúng tôi thực sự không có nhiều thành ngữ cụ thể mà chúng tôi sử dụng trên các trình duyệt cụ thể ở cấp độ biên dịch. Trên thực tế, trình biên dịch không có bất kỳ kiến ​​thức đặc biệt nào về trình duyệt đang được nhắm mục tiêu

Sự khác biệt chính xuất hiện khi bạn bắt đầu xử lý DOM trên các trình duyệt khác nhau và khi xử lý các sự kiện cấp giao diện người dùng của trình duyệt hoặc mô hình đối tượng mà trình duyệt hiển thị. Chúng tôi có thể giữ phần đó của vấn đề trong các lớp cụ thể được nhắm mục tiêu tới các trình duyệt riêng lẻ. Trình biên dịch không thực sự có bất kỳ kiến ​​thức trực tiếp nào về những khác biệt đó. Hệ thống biên dịch GWT mang đến các lớp thích hợp cho trình duyệt và lớp đó chứa các chi tiết triển khai

Frank Sommers. Điều gì xảy ra với một lớp Java khi nó được biên dịch thành JavaScript?

Scott Blum. JavaScript không thực sự có một hệ thống lớp được xác định rõ ràng. Đó là một ngôn ngữ dựa trên nguyên mẫu. Có những thành ngữ mà mọi người làm theo trong JavaScript để làm những việc rất giống với những gì bạn làm trong các lớp Java

Bạn có thể linh hoạt hơn với những gì bạn có thể làm trong JavaScript, theo một số cách, tôi muốn nói là có nhiều sợi dây hơn [để tự treo cổ]. Tuy nhiên, vấn đề là việc triển khai các ý tưởng về lớp của Java trong JavaScript khá dễ dàng, bởi vì JavaScript linh hoạt hơn một chút.

Ví dụ: nếu chúng ta có một lớp Java mà chúng ta đang dịch sang JavaScript, chúng ta sẽ tạo một hàm khởi tạo lớp, một hàm tạo, cho lớp đó. Và sau đó, chúng tôi thêm tất cả các trường và phương thức đa hình vào nguyên mẫu đó, để khi bạn bắt đầu khởi tạo, chẳng hạn như, một mã Button trong mã Java, những gì bạn thực sự nhận được là một lệnh gọi hàm xây dựng đó trong JavaScript trả về phiên bản đã dịch của

Các phương pháp khá nhiều được dịch trên cơ sở từng phương pháp. Nếu bạn nhìn vào phiên bản không bị xáo trộn của đầu ra trình biên dịch của chúng tôi và so sánh nó với mã nguồn Java ban đầu, thì có một mức độ tương quan cao. Bạn có thể theo dõi khá nhiều JavaScript đầu ra và có thể tìm ra mã nguồn của bạn đến từ đâu

Frank Sommers. Các đối tượng dựa trên nguyên mẫu là gì?

Scott Blum. Cách thức hoạt động của JavaScript là các đối tượng có cái được gọi là chuỗi nguyên mẫu. Khi bạn đang cố tra cứu một số trường foo trên một đối tượng cụ thể [được gán cho], chẳng hạn như một số biến X, điều đầu tiên [trình thông dịch JavaScript] làm là tìm trong X để xem liệu X có một foo hay không

Nếu X làm như vậy, thì bạn sẽ nhận được bất kỳ giá trị nào xảy ra ở đó. Nếu không, [trình thông dịch] đi lên chuỗi nguyên mẫu tới đối tượng nguyên mẫu của X và xem liệu nó có. Nó sẽ đi lên chuỗi đó [tới] bao nhiêu bố mẹ nguyên mẫu, cho đến khi đi đến cuối chuỗi. Nếu cuối cùng vẫn không tìm thấy, thì bạn sẽ nhận lại được ArrayList3

Chúng tôi đã có thể lấy cấu trúc này và lập bản đồ dựa trên ý tưởng Java về các siêu lớp. Ví dụ: chúng tôi thiết lập hàm tạo cho ArrayList4 và thiết lập một nguyên mẫu chỉ có ArrayList5, ArrayList6 và ArrayList7. Đối với bất kỳ lớp nào mà chúng tôi lấy được từ đó, chúng tôi bắt đầu với một thể hiện của ArrayList4, lớp này trở thành nguyên mẫu cho một số lớp con chuyên biệt hơn, v.v.

Frank Sommers. Loại mã Java nào khó dịch sang JavaScript nhất?

Scott Blum. Khía cạnh khó khăn nhất là hành vi chính xác của Java được chỉ định rất cao. Ví dụ: khi bạn có một lớp đang được khởi tạo trong hàm tạo của nó, sẽ có các quy tắc chi phối thời điểm hàm tạo của lớp bậc trên được gọi, khi bạn có thể thực hiện các lệnh gọi phương thức đa hình cho lớp con của mình, thứ tự đánh giá, những thứ tương tự. Có một loạt các vấn đề được chỉ định chính xác

Điều đó gây khó khăn cho việc có một trình biên dịch chính xác, bởi vì có rất nhiều trường hợp góc mà bạn phải lo lắng. Đôi khi điều tự nhiên và hiệu quả nhất mà bạn có thể muốn làm lại không thực sự làm đúng. Hầu hết mọi người sẽ không bao giờ gặp phải hầu hết các trường hợp đó, nhưng điều đó khiến việc viết trình biên dịch trở nên khá khó khăn. Nếu họ để mọi thứ lỏng lẻo hơn một chút, không xác định hơn một chút, thì hầu hết mọi người sẽ không bao giờ biết hoặc quan tâm đến chúng, nhưng nó sẽ giúp việc triển khai một trình biên dịch chính xác dễ dàng hơn rất nhiều

Frank Sommers. Bạn đã đề cập rằng chức năng dành riêng cho trình duyệt được đưa vào quy trình biên dịch từ các thư viện bên ngoài. Bạn có thể giải thích làm thế nào nó hoạt động?

Scott Blum. Chúng tôi có một cơ chế chung trong quá trình biên dịch mà chúng tôi gọi là liên kết hoãn lại. Nó cung cấp cho bạn khả năng thay thế toàn bộ các lớp tại thời điểm biên dịch

Hãy tưởng tượng rằng bạn có một lớp DOM trừu tượng và bạn muốn nó được thay thế tại thời điểm biên dịch bằng một phiên bản cụ thể sẽ được điều chỉnh chính xác cho nền tảng bạn đang sử dụng. Thông qua liên kết hoãn lại, bạn thiết lập các quy tắc trong cấu hình dự án của mình để cho phép bạn chỉ định trong những điều kiện nào các lớp cụ thể sẽ được hoán đổi cho các lớp khác

Đối với một ứng dụng cơ bản, hầu hết các nhà phát triển sẽ không phải lo lắng về điều này vì điều đó đã được tích hợp sẵn trong thư viện của chúng tôi. Đó là một phần trong cách siêu dữ liệu của chúng tôi được kế thừa. Nhưng đây là thứ bạn có thể tận dụng nếu bạn cung cấp triển khai dành riêng cho trình duyệt của thư viện lớp của riêng bạn

Khi trình biên dịch biên dịch một thứ gì đó, nó sẽ xem xét một tập hợp các thuộc tính và tạo ra một hoán vị của trình biên dịch cho từng trạng thái có thể có của một thuộc tính. Ví dụ: có một thuộc tính tác nhân người dùng có một trong bốn giá trị khác nhau—Firefox, IE, Opera hoặc Safari. Trình biên dịch sẽ tạo ra bốn phiên bản ứng dụng của bạn, một phiên bản phù hợp với từng phiên bản đó

Nếu hoán vị đầu tiên là Firefox, nó sẽ xuất hiện với việc triển khai DOM của Firefox là lớp thay thế chính xác và lần sau, nó sẽ xuất hiện một lớp cho IE, v.v.

Ngoài việc chỉ có thể thay thế các lớp bằng các lớp đã viết sẵn, cơ sở mạnh mẽ khác là tạo các lớp một cách nhanh chóng trong quá trình biên dịch. Bạn có thể chạy một trình tạo sẽ tạo ra các lớp mới có thể là các lớp con của các lớp bạn đã xác định trong dự án của mình. Đó là cách cơ chế RPC của chúng tôi hoạt động. Tất cả mã để tuần tự hóa và giải tuần tự hóa đối tượng của bạn được tạo tại thời điểm biên dịch

Frank Sommers. Sau khi bạn có các phiên bản dành riêng cho trình duyệt đó, bạn sẽ triển khai chúng như thế nào để mỗi trình duyệt chỉ nhận được mã dành cho nó?

Scott Blum. Khi trình biên dịch tạo từng tệp đầu ra được nhắm mục tiêu bởi trình duyệt, nó cũng tạo ra thứ mà chúng tôi gọi là tập lệnh lựa chọn. Đó là tệp JavaScript chạy trên máy khách trong quá trình khởi động GWT và chạy bất kỳ logic nào cần thiết trên trình duyệt máy khách để xác định giá trị thuộc tính chính xác của chúng là gì

Dựa trên các giá trị thuộc tính đó, tập lệnh tạo yêu cầu cho một trong các hoán vị đầu ra của trình biên dịch có thể. Vì vậy, người dùng Firefox sẽ nhận được ArrayList9 cho trang, trang này sẽ bao gồm tập lệnh lựa chọn này. Tập lệnh lựa chọn nhận ra rằng nó đang chạy trên Firefox và điều đó sẽ khiến tập lệnh đó yêu cầu đầu ra trình biên dịch phù hợp làm tập lệnh tiếp theo. Là người dùng, tất cả những gì bạn thực sự phải lo lắng là sao chép đầu ra từ thư mục trình biên dịch sang máy chủ Web của mình

Frank Sommers. Bạn đã nói trước đó rằng JavaScript linh hoạt hơn Java. Bạn tận dụng tính linh hoạt hơn trong JavaScript theo cách nào để có được hiệu suất tốt hơn hoặc mã ngắn gọn hơn?

Scott Blum. Chúng tôi chắc chắn cố gắng tận dụng các thủ thuật trong JavaScript để làm cho [mã được tạo] hiệu quả hơn cả về kích thước và tốc độ

Một điều cần chỉ ra là JavaScript hỗ trợ định dạng JSON mà chúng tôi sử dụng ở một vài nơi. Trong trình biên dịch, chúng tôi sử dụng nó để có thể bọc và xây dựng các đối tượng với một lượng cú pháp rất nhỏ. Nó thực sự khá nhanh. JSON có một cú pháp ký hiệu đối tượng cho phép bạn sử dụng một dấu ngoặc mở và sau đó là một loạt các mã định danh, với dấu hai chấm ngăn cách chúng với các giá trị của chúng, theo sau là một dấu ngoặc nhọn. Chúng ta có thể sử dụng cú pháp đó để nhanh chóng xây dựng một đối tượng trông như thế nào trong mã, thay vì phải chỉ định rõ ràng từng mã định danh

Một nơi khác mà chúng tôi sử dụng nó là RPC của chúng tôi—chúng tôi sử dụng JSON làm định dạng dây RPC của mình. Điều đó cho phép chúng tôi tuần tự hóa và giải tuần tự hóa những thứ đi qua dây rất nhanh. Điều đó cắt giảm số lượng xử lý phải được thực hiện

Frank Sommers. Ngoài các công cụ tuyệt vời dành cho nhà phát triển Java, bạn nghĩ đâu là điểm khác biệt lớn nhất đối với nhà phát triển giữa việc viết ứng dụng dựa trên trình duyệt bằng Java so với viết ứng dụng đó trực tiếp bằng JavaScript?

Scott Blum. Sự khác biệt lớn nhất không phải là chương trình cuối cùng có thể làm gì, hay các đặc tính hiệu suất chung của nó—mặc dù tôi nghĩ GWT có các đặc tính hiệu suất thực sự tốt. Đối với tôi, câu chuyện thực tế là khi bạn viết một số đoạn mã lớn bằng JavaScript, bạn càng viết nhiều [mã] thì càng khó duy trì [mã đó], đơn giản vì nó không được nhập tĩnh và bạn không

Ngoài ra, [mã JavaScript] rất khó chia nhỏ thành các phần chức năng mà bạn biết sẽ phối hợp tốt với nhau, chẳng hạn như các giao diện được xác định rõ. Trong Java, những gì bạn nhận được là khả năng mở rộng, điều này phát huy tác dụng khi dự án bạn đang thực hiện càng lớn và bạn càng có nhiều người tham gia vào dự án đó.

Nếu bạn định ngồi xuống và viết một ứng dụng nhỏ, JavaScript có lẽ là một lựa chọn tốt. Nhưng điều bạn cố gắng làm càng lớn thì càng tận dụng sức mạnh của Java để thực sự giúp ích cho bạn

JavaScript khá linh hoạt và mạnh mẽ. Hầu hết các nhược điểm của nó, ít nhất là đối với tôi, không đến từ những gì bạn có thể thể hiện trong đó — bởi vì bạn có thể thể hiện rất nhiều điều — chỉ là nó hoàn toàn ở dạng tự do, có thể nói như vậy. Sức mạnh của JavaScript cũng là sợi dây mà bạn có thể dễ dàng treo cổ bằng nó

Đó là lý do tại sao, khi mọi người đang tạo các thư viện lớp lớn, rất nhiều thứ bạn đang làm là dựa trên quy ước. Bạn có một quy ước về cách bạn xây dựng một lớp, bạn có một quy ước cho cái này hay cái kia, và không có sự thực thi có lập trình nào đối với bất kỳ quy ước nào trong số đó

Frank Sommers. Các giới hạn hiện tại của trình biên dịch GWT trong việc dịch mã Java sang JavaScript là gì?

Scott Blum. Không có tính năng ngôn ngữ Java 5 nào được hỗ trợ ngay bây giờ. Chúng tôi đúng là 1. Dựa trên 4 về khả năng tương thích nguồn. Về ngôn ngữ thực tế, chúng tôi hỗ trợ khá nhiều thứ. Ví dụ, các lớp bên trong, các lớp ẩn danh được hỗ trợ. Khá nhiều thứ bạn có thể thể hiện là mã Java thẳng, bạn có thể làm trong GWT

Hạn chế thực sự duy nhất của mã Java mà bạn có thể dịch sang JavaScript là bạn phải có sẵn tất cả các nguồn. Một lý do khiến bạn không thể dịch tất cả các lớp I/O của Java là vì chúng có một loạt các phương thức gốc được triển khai trong mã C++, vì vậy không có cách nào chúng tôi có thể dịch nó. Ngoài ra, một số thứ sẽ không hợp lý trong trình duyệt, chẳng hạn như đồng bộ hóa, vì JavaScript là một luồng đơn. Và chúng tôi không hỗ trợ đầy đủ kiểu dữ liệu dài vì không có trình duyệt nào hỗ trợ. Tất cả chúng đều hỗ trợ dấu phẩy động có độ chính xác kép, nhưng không có kiểu số nguyên 64 bit

Bộ công cụ web của Google
http. //mã số. Google. com/webtoolkit/

Artima Phỏng vấn Bret Taylor của Google về GWT
http. //www. nghệ thuật. com/diễn đàn/căn hộ. jsp?forum=276&thread=185564

Nói chuyện trở lại

Có một ý kiến? . Tại sao không thêm của bạn?

Giới thiệu về tác giả

Frank Sommers là Biên tập viên cao cấp của Nhà phát triển Artima. Ông cũng là tổng biên tập bản tin của Ủy ban Kỹ thuật IEEE về Máy tính có thể mở rộng và là thành viên được bầu của Ủy ban Cố vấn Kỹ thuật của Cộng đồng Jini. Trước khi gia nhập Artima, Frank đã viết các cột Jiniology và Dịch vụ web cho JavaWorld

JavaScript có thể được chuyển đổi sang Java không?

Không, bạn không thể . Tên giống nhau thật đáng tiếc nhưng JavaScript và Java là những ngôn ngữ hoàn toàn khác nhau.

Làm cách nào để chạy tệp JavaScript trong Java?

Ví dụ. Thực thi tệp JavaScript trong Mã Java .
nhập javax. kịch bản. *;
nhập java. io. *;
lớp công khai NashornVí dụ {
public static void main(String[] args) throws Exception{
// Tạo script engine
ScriptEngine ee = ScriptEngineManager mới(). getEngineByName("Nashorn");
// Đọc tập tin Nashorn

Làm cách nào để kết nối JavaScript với Java?

Chúng ta sẽ kết nối JavaScript với Java bằng cách tạo một phiên bản mới của lớp Java bằng cách sử dụng từ khóa mới của JavaScript . Ví dụ 1 hiển thị một hàm có tên là duyệt () mở một "hộp thoại tệp" gốc bằng cách sử dụng Java tích hợp sẵn. awt. Khung và java.

Bạn có thể kết hợp JavaScript và Java không?

JavaScript cũng bao gồm các hàm để kiểm soát các tiểu dụng Java và Các tiểu dụng Java có thể truy cập các chức năng JavaScript . Bằng cách tích hợp hai ngôn ngữ Web này, bạn có thể tận dụng tốt nhất cả hai thế giới, cho phép thực hiện nhiều ứng dụng phức tạp.