a múlt héten főleg javascripttel kapcsolatos dolgokat olvastam, de azért akad itt más is. ráadásul a DSL-ek nagyon érdekelnek, szóval sok ezzel kapcsolatos írás került elém.
a java elődjében, az oak-ban volt rengeteg furcsaság. szerencsére ezek nagy része eltűnt, viszont pár dolog megmaradt. ha például megkérdezném, hogy mit ír ki az alábbi kód, akkor a programozók legnagyobb része azonnal rávágná, hogy semmit:
class NothingSpecial extends Thread {
public void run() {
try {
while(true) {
}
}catch(NullPointerException ex) {
System.out.println("?");
}
}
}
a while magja üres, így nem dobódhat benne NullPointerException. vagy mégis? sajnos előfordulhat olyan eset, amikor ez a kód az "?" sztringet írja ki.
az oak nyelvben létezett az aszinkron kivétel fogalma, és ez megmaradt a javában is (a nyelvi specifikációban szántak is rá egy rövid bekezdést). egy kivétel attól aszinkron, hogy nem az a szál hozza létre, amiben kezelni kell. előfordulhat JVM InternalError esetén, vagy a Thread.stop() metódus meghívásakor. a stop() metódusnak átadhatunk egy Throwable példányt és ez a kivétel fog eldobódni a szában. nem véletlen, hogy ez a metódus deprecated: ez a viselkedés nagyon veszélyes is lehet. a fenti példában is olyan helyen fordul elő kivétel, ahol normális körülmények között nem számítanánk rá.
a kivételt előállító kód így néz ki:
class SomethingSpecial {
public static void main(String... args) throws Exception{
NothingSpecial thread = new NothingSpecial();
thread.start();
Thread.sleep(200);
thread.stop(new NullPointerException());
Thread.sleep(200);
}
}
Tanulság: a stop() metódus nem véletlenül deprecated.
a JDK7 újdonságai között hosszú huzavona után végül ott lesznek a lambda kifejezések. azt még senki nem tudja, milyen formában és milyen mélységben, de bekerülnek a nyelvbe. a vitákról és a különböző specifikációkról rengeteg anyagot találhattok, mivel az utóbbi időben minden nagy javás arc ezzel a témával foglalkozott. kezdésnek talán neal gafter blogján érdemes végigfutni. valószínűleg amit ő leír nincs túl távol attól, ami végül a nyelvben megjelenik.
addig is amíg ez az újítás nem jelenik meg, kereshetünk olyan megoldásokat, amik nagyon emlékeztetnek a lambda kifejezésekre. itt van például ez:
thread = java.lang.Thread(
function() {
print(java.lang.Thread.currentThread().getName());
}
);
thread.start();
hogy mi is ez? pontosan az, amit a legtöbb java programozó lambda kifejezés néven a nyelvben látni szeretne. itt egy függvényt adunk át a Thread konstruktorának, ami tudja, hogy ezt hívja meg a run() metódus helyett (ez egyébként nem teljesen így van, de szép gondolat).
sajnos azonban erre még várnunk kell: a fenti kód ugyanis egy javascript részlet. a tegnapelőtt postban írtam a rhinoról, a java scripting api egy javascript script engine implementációjáról. akkor elmondtam, hogy a rhinoban használhatunk java objektumokat, kihagytam viszont egy érdekes dolgot. abban az esetben, ha egy olyan interfészt kellene implementálnunk, amiben csak egy metódus van, a rhino megengedi, hogy csak a függvényimplementációt adjuk át. ebből ő majd előállítja a megfelelő interfész implementációt, de arról nekünk nem kell tudnunk. (a single abstract method (SAM) osztályok fogalma egyébként a java lambda kifejezés implementációja kapcsán is felmerült).
a fenti példában tehát előáll egy olyan Runnable implementáció. ha mégis magunknak akarjuk implementálni az interfészt, akkor azt így tehetjük meg:
var o = { run: function() {
print(java.lang.Thread.currentThread().getName());
}
};
var r = new java.lang.Runnable(o);
még több érdekességet találhattok a rhino és a java kapcsolatáról a rhino dokumentációban.
a java se 6 óta tudunk javascriptet futtatni java kódban. ez azért előnyös, mert használhatunk java objektumokat miközben megmarad a javascript egyszerűsége. ezen a keverék példakódon ez jól látszik:
importPackage(javax.swing);
function drawWindow(text) {
var frame = new JFrame();
var label = new JLabel(text.toString());
frame.add(label);
frame.pack();
frame.setVisible(true);
}
a szkriptek értelmezéséhez szükséges eszközök a javax.script csomagba kerültek. három fontos osztállyal kell itt foglalkoznunk:
ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByMimeType("text/javascript");
engine.eval(new FileReader("test.js"));
Invocable invocable = (Invocable) engine;
invocable.invokeFunction("drawWindow", "alma");
(a fenti javascript kód a test.js fájlban van). a JDK-ban egyébként alapból benne van a mozzilla rhino javascript implementáció. mivel azonban a ScriptEngineManager a service loader mechanizmust használja az implementációk megtalálására, ezért nagyon könnyű új megvalósításokat beilleszteni.
a témával kapcsolatban találhattok itt egy jó prezentációt, itt pedig egy javascript-java kombóvaal megvalósított számológépet.
múlthéten ezekre volt időm:
twitteren követek néhány szakit, akiket minden java programozónak érdemes ismernie. josh bloch például tt írta meg, hogy elkészült a dual-pivot quicksort implementációjával (én legalábbis innen tudtam meg). íme a lista:

a java nyelvkezdőknek, néha haladóknak, interjú kérdések, beugratós tesztek, példakódok, újdonságok stb.
magamról
iratkozz fel!
iratkozz fel gyorsan!