Metaprogramming is the writing of computer programs that write or manipulate other programs (or themselves) as their data or that do part of the work during compile time that is otherwise done at run time. In many cases, this allows programmers to get more done in the same amount of time as they would take to write all the code manually.
-wikipedia
Mówią że C++ daje narzędzia do metaprogrammingu a java nie. Przykładowo by wygenerować klasę całkują funkcje zwracającą double i std::complex, starczy napisać jeden szablon integrator
Ale to Java ma powera do metaprogrammingu. Czytałem sobie w "Thinking in Java"* w rozdziale o adnotacjach, adnotacje to są takie fajne metadane dołaczane do kodu źródłowego. Ogólnie można do każdego elementu klasy dopisać jakąś informację. Co więcej, można za pomocą narzędzia apt (annotation processing tool), generować nowe pliki klas.
Dziś pisałem sejwowanie klasy do XML wygląda tak że na początku pisze się kod:
Element root = new Element ("[nazwa klasy]");a dla każdej składowej klasy pisze się:
Element [nazwa składowej] = new Element ("[nazwa składowej]");W sumie upierdliwe jak się ma 9 składowych. Wyglądało to tak:
[nazwa_składowej].appendChild(String.valueOf(this.[nazwa_składowej]));
root.appendChild([nazwa_składowej]);
package jb.sk;
import java.io.Serializable;
import java.text.ParseException;
import nu.xom.Element;
public class Comment implements Serializable, Comparable{ private static final long serialVersionUID = -5532948060127766412L;}
String author;
String authorEmail;
long authorIP;
String authorUrl;
long date;
boolean deleted;
String message;
CommentId no = null;
boolean visible;
public Element getXML(){}
Element comment = new Element("comment");
Element author = new Element("author");
author.appendChild(getAuthor());
comment.appendChild(author);
Element authorEmail = new Element("authorEmail");
authorEmail.appendChild(getAuthorEmail());
comment.appendChild(authorEmail);
Element authorIP = new Element("authorIP");
authorIP.appendChild(String.valueOf(getAuthorIP()));
comment.appendChild(authorIP);
Element authorUrl = new Element("authorUrl");
authorUrl.appendChild(getAuthorUrl());
comment.appendChild(authorUrl);
Element date = new Element("date");
date.appendChild(String.valueOf(getDate()));
comment.appendChild(date);
Element deleted = new Element("this.deleted");
date.appendChild(String.valueOf(isDeleted()));
comment.appendChild(deleted);
Element message = new Element("message");
message.appendChild(getMessage());
comment.appendChild(message);
Element no = new Element("no");
no.appendChild(this.no.toString());
comment.appendChild(no);
Element visible = new Element("visible");
visible.appendChild(String.valueOf(isVisible()));
comment.appendChild(visible);
return comment;
/*...*/
No i trafiło mnie żestarczyłoby utworzyć takie coś:
@XMLAble
abstract Comment_base{@XMLAbleElement}
String author;
/*..*/
Comment(Element e){set(e);}
abstract Element getXML();
abstract set(Element elem);
/*..*/
Potem automatycznie (przy pomocy apta) pisać klasę: Comment, która te dwie metody nadpisuje kodem generowanym w trywialny sposób. Po prostu tworzyłaby nową klasę dla @XMLAble i która sejwowałaby każdy element z annotacją @XMLAbleElement. Trywial :). Może kiedyś napisze coś takiego :).
---
* Wersji IV, wersja III dostępna na stronie autora (nie ma w niej chyba rozdziału w którym mówie).