2008-09-21 25 views
33

Tôi là người hâm mộ của static metaprogramming in C++. Tôi biết Java bây giờ có generics. Điều này có nghĩa là metaprogramming tĩnh (tức là, thực hiện chương trình biên dịch thời gian) có thể thực hiện được trong Java không? Nếu có, bất kỳ ai cũng có thể giới thiệu bất kỳ tài nguyên nào tốt nơi người ta có thể tìm hiểu thêm về nó không?Metaprogramming tĩnh có thể trong Java không?

+0

Ra khỏi tò mò: Vượt thách thức kỹ thuật, những lợi ích thực tế của lập trình meta tĩnh là gì? – Uri

+1

@Uri: Di ​​chuyển càng nhiều công việc và các nguồn lỗi để biên dịch thời gian càng tốt - tạo mã, tối ưu hóa và đa hình tĩnh sẽ là một số từ khóa. –

Trả lời

22

Không, điều này là không thể. Generics không mạnh bằng mẫu. Ví dụ, một đối số mẫu có thể là một kiểu do người dùng định nghĩa, một kiểu nguyên thủy hoặc một giá trị; nhưng đối số mẫu chung chỉ có thể là Object hoặc một loại phụ của mẫu đó.

Chỉnh sửa: Đây là câu trả lời cũ; kể từ năm 2011, chúng tôi có Java 7, có Annotations that can be used for such trickery.

+2

+1: Câu trả lời hay! – Partial

+3

Tuy nhiên, sự phản chiếu mạnh hơn các mẫu - tại sao bạn lại sử dụng công cụ sai (generics) cho công việc? –

+10

Một từ: loại an toàn. (Zero ... một ... xem? Một từ.) – Thomas

2

Không, Generics trong Java hoàn toàn là một cách để tránh việc cast Object.

+0

Không đúng về mặt kỹ thuật, vì một số generics có sẵn khi chạy. ví dụ: Tiện ích của Gafter: http://gafter.blogspot.ca/2006/12/super-type-tokens.html – btiernay

3

Không. Thậm chí nhiều hơn, các kiểu chung chung sẽ bị xóa theo giới hạn trên của trình biên dịch, vì vậy bạn không thể tạo một thể hiện mới của kiểu T chung khi chạy.

Cách tốt nhất để thực hiện metaprogamming trong Java là phá vỡ kiểu xóa và tay trong đối tượng Class<T> của loại T. Tuy nhiên, đây chỉ là một hack.

12

Hãy xem Clojure. Đó là một LISP với Macro (siêu lập trình) chạy trên JVM và rất tương thích với Java.

+2

không thể nhận được nhiều hơn nữa meta so với lisp – gtrak

0

Tôi không chắc mình hiểu được lợi thế của lập trình meta tĩnh. Trong Java, bạn có thể phản ánh để tìm thông tin về các lớp của bạn và làm tất cả những điều meta-lập trình sẽ làm, bạn chỉ cần làm cho chúng bên trong mã của bạn mà không cần thêm cú pháp mới và cách suy nghĩ khác nhau. Chú thích cũng có thể thực hiện một số tác vụ lập trình meta nhất định theo cách có cấu trúc hơn.

Tôi có thể sai về điều này, tôi nghiêm túc xem xét việc mở một câu hỏi trên đó bởi vì tôi không chắc chắn tôi nhận được nó. Nó có vẻ như lập trình meta tĩnh là một hack gọn gàng mà được xung quanh thực tế là một số ngôn ngữ không giữ rất nhiều thông tin thời gian biên dịch có sẵn tại thời gian chạy (một trong những điểm mạnh của Java và ngôn ngữ động).

Nếu bất kỳ ai có thể trả lời bằng một liên kết đến một ví dụ trong đó meta-programming cung cấp giải pháp dễ hiểu hơn, dễ đọc hơn hoặc tốt hơn so với phản xạ, tôi đánh giá cao nỗ lực này.

+0

Đây là một tác vụ siêu lập trình đơn giản là không thể từ bên trong C++: cơ cấu lại kiến ​​trúc. Có hai bài báo bạn có thể đọc về chủ đề: Akers, Baxter, Mehlich, Ellis, Luecke, "Nghiên cứu điển hình: Tái cấu trúc các thành phần C++ Thông qua chuyển đổi chương trình tự động", Công nghệ thông tin và phần mềm 49 (3): 275-291 2007 Có sẵn từ nhà xuất bản, và mô tả kết quả cuối cùng và ... –

+0

.... Và (cùng một tác giả) "Tái cấu trúc C++ thành phần mô hình thông qua chuyển đổi chương trình tự động" có sẵn tại http://www.semanticdesigns.com/Company/ Ấn phẩm. Điều này mô tả công việc ở trạng thái không hoàn chỉnh nhưng có nhiều hương vị giống nhau. –

+0

Tôi đã đề cập đến một lợi thế của meta-lập trình trên một công nghệ tích cực hơn như phản ánh. Tôi nhận ra rằng C++ bị giới hạn trong hoạt động biên dịch và do đó có thể phải thực hiện những thứ mà các ngôn ngữ động hoặc VM có thể thực hiện trong thời gian chạy, nhưng tại sao bạn lại muốn hack như các khuôn mẫu khi bạn có sự phản chiếu đúng? –

2

Nếu bạn cần logic biên dịch mạnh mẽ cho Java, một cách để làm điều đó là với một số loại tạo mã. Vì, như các áp phích khác đã chỉ ra, ngôn ngữ Java không cung cấp bất kỳ tính năng nào phù hợp để thực hiện logic biên dịch, đây có thể là lựa chọn tốt nhất của bạn (iff bạn thực sự cần có logic biên dịch). Một khi bạn đã cạn kiệt các khả năng khác và bạn chắc chắn bạn muốn để làm mã thế hệ mới, bạn có thể quan tâm trong dự án mã nguồn mở của tôi Rjava, có sẵn tại địa chỉ:

http://www.github.com/blak3mill3r

Đó là một thế hệ mã Java thư viện được viết bằng Ruby, mà tôi đã viết để tạo các giao diện Bộ công cụ Web của Google cho các ứng dụng Ruby on Rails một cách tự động. Nó đã tỏ ra khá tiện dụng cho điều đó.

Như một cảnh báo, có thể rất khó gỡ lỗi mã Rjava, Rjava không thực hiện kiểm tra nhiều, nó chỉ giả định bạn biết bạn đang làm gì.Đó là khá nhiều trạng thái của metaprogramming tĩnh anyway. Tôi muốn nói rằng nó dễ dàng hơn để gỡ lỗi hơn bất cứ điều gì không tầm thường được thực hiện với C++ TMP, và nó có thể sử dụng nó cho cùng một loại thứ.

Dù sao, nếu bạn đang cân nhắc việc viết chương trình xuất ra mã nguồn Java, hãy dừng ngay bây giờ và kiểm tra Rjava. Nó có thể không làm những gì bạn muốn được nêu ra, nhưng nó được cấp phép MIT, do đó, cảm thấy tự do để cải thiện nó, sâu chiên nó, hoặc bán nó cho bà của bạn. Tôi rất vui khi có những nhà phát triển khác có kinh nghiệm về lập trình chung để nhận xét về thiết kế.

4

Bạn chính xác có ý nghĩa gì khi "lập trình meta tĩnh"? Vâng, C++ mẫu Lập trình meta là không thể trong Java, nhưng nó cung cấp các phương pháp khác, mạnh hơn rất nhiều so với những người từ C++:

  • phản ánh
  • lập trình hướng khía cạnh (@AspectJ)
  • bytecode thao tác (Javassist, ObjectWeb ASM, đại lý Java)
  • thế hệ mã (Công cụ chế biến chú thích, mẫu động cơ như Velocity)
  • cú pháp trừu tượng Tree thao tác (API được cung cấp bởi IDE phổ biến)
  • khả năng để chạy trình biên dịch Java và sử dụng mã được biên dịch ngay cả khi đang chạy

Không có phương pháp tốt nhất: mỗi phương pháp đều có điểm mạnh và điểm yếu của nó. Do tính linh hoạt của JVM, tất cả các phương thức trong Java có thể được sử dụng cả ở thời gian biên dịch và thời gian chạy.

Các vấn đề liên quan