Några nyheter i J2SE 5.0

0. Sammanfattning

Omfattande utökningar har gjorts av själva språket, se avsnitt 2 nedan. Även API:erna har genomgått flera förändringar men förutom java.lang och java.util (avsnitt 3 nedan) är nästan alla så specialicerade att de inte berör "den genomsnittliga utvecklaren".

Det kan noteras att Fedora inte finns med i listan över stödda plattformar. De enda RedHat-versioner som finns är 9 och enterprise. Faktum är att listan inte innehåller någon linuxdistribution alls som är helt gratis (om inte TurboLinux går att ladda hem gratis?).

1. Prestanda

1.1 Class Data Sharing

En del klasser från rt.jar installeras i det format jvm:en använder internt. Det gör att det går snabbare att ladda dem vid programstart. De laddas dessutom inte om ifall flera jvm:er startas vilket minskar minnesåtgången. Detta gäller endast hotspot client vm och serial gc. Ett högst ovetenskapligt test med ett hello world-program på redhat 8.0, 1.4GHz P4 och 512 MB ram antyder att exekveringstiden förkortas från knappt 0.2s till drygt 0.1s när -Xshare:on används i stället för -Xshare:off (default är -Xshare:auto).

1.2 Server-Class Machine Detection

Om jvm:en startas på en dator med pentium eller 32-bit sparc med minst 2GB ram och solaris eller linux antas det vara en server. Då används hotspot server vm i stället för hotspot client vm automatiskt. Detta gäller endast om varken -server eller -client anges.

1.3 Några länkar med mer information om hotspot och gc

1.4 StringBuilder

Den nya klassen StringBuilder ska användas i stället för StringBuffer. Till skillnad från StringBuffer är den inte synkroniserad och därför snabbare. Den innehåller alla StringBuffer:s metoder så det går att byta rakt av.

2. Ändringar i språket

2.1 Generics

2.1.1 Introduktion

Följande kod:
List myIntList = new LinkedList();
myIntList.add(new Integer(0));
Integer x = (Integer) myIntList.iterator().next();
Kan nu ersättas med:
List<Integer> myIntList = new LinkedList<Integer>();
myIntList.add(new Integer(0));
Integer x = myIntList.iterator().next();
Fördelen är att samlingen nu är typsäker. Vinsten med generics är alltså att programmet blir typsäkert, punkt. Det är garanterat att if your entire application has been compiled without unchecked warnings using javac -source 1.5, it is type safe.

2.1.2 Arkitektur

Det finns två centrala punkter som förklarar det mesta av hur generics funkar i java:

2.1.3 Mer syntax

Detta är inte allt, se länken nedan för mer information.

2.1.4 Exempel

Ett program som använder typsäkra samlingar, CollectionTest.java.
Ett exempel på deklaration av typvariabler. Programmet visar också i vilken mån Class.newInstance() kan användas typsäkert, ObjectFactory.java.

2.1.5 Slutsats

Det är mycket lämpligt att använda generics för att göra ett program typsäkert.

2.1.6 Mer om generics

Detta är en tämligen utförlig men ändå tydlig redogörelse:
http://java.sun.com/j2se/5.0/docs/guide/language/generics.html

2.2 Ny typ av for-loop (for-each)

En ny typ av for-loop som kan användas på alla samlingar som implementerar java.lang.Iterable. Nedanstående loop
    for (Iterator<MyClass> i = aCollection.iterator(); i.hasNext();) {
i.next().doSomething();
}
kan ersättas med:
    for (MyClass mc : aCollection) { //Pronounced "for each MyClass c i aCollection".
mc.doSomething();
}
När det gäller arrayer kan
    for (int i=0; i<anArray.length; i++) {
anArray[i].doSomething();
}
ersättas med
    for (TypeInArray tia : anArray) {
tia.doSomething();
}
Här är ett program som illustrerar det senaste exemplet, ForEachTest.java.

2.3 Autoboxing

Det finns två nya typer av conversions: boxing conversion och unboxing conversion. Dessa omvandlar (vid exekvering) mellan primitiva typer och deras wrapper-klasser. Det innebär att boxing och unboxing kan ske automatiskt, vilket kallas autoboxing respektive autounboxing. Här kommer ett litet exempel, AutoboxTest.java. Notera att detta enbart är en konvertering, det finns fortfarande både primitiva variabler och referensvariabler. Här kommer några klurigheter:
Denna funktionalitet är främst avsedd för att hantera primitiva typer i samlingar. Exemplat ovan är alltså inte särskilt bra.

2.4 Uppräkningsbara typer (enumerations)

Detta följer i stort Item 21 i Bloch: Effective Java Programming Language Guide. Uppräkningsbara typer deklareras så här: enum MyType {VALUE1, VALUE2, VALUE3}.

Detta leder till att kompilatorn skapar en subklass till java.lang.Enum som heter MyType och har tre statiska fält av typen MyType. Dessa innehåller tre olika objekt som heter VALUE1, VALUE2 och VALUE3. Objekten har en toString() som skriver ut deras namn. De har också lämpliga implementationer av equals() och hashCode(). De är Serializable, Comparable och final. De är inte Clonable. Klassen har två statiska metoder, valueOf() som tar en typ och ett namn och returnerar objektet av den typen med det namnet samt values() som returnerar en array med alla typens värden i den ordning de är deklarerade. Klassen EnumTest.java använder den uppräkningsbara typen Fruit.java.

Objekten som skapas kan ha konstruktorer och metoder, se ListMonths.java och Month.java.

Klienterna till en uppräkningsbar typ påverkas inte om värdena byter plats, om nya värden läggs till eller om värden tas bort (förutsatt att de inte använder de borttagna värdena). Serialiserade objekt av den uppräkningsbara typen fungerar även de bra även om sådana förändringar görs.

Det går utmärkt att använda collection-API:et men det finns två nya samlingar som är snabbare för uppräkningsbara typer, java.util.EnumSet och java.util.EnumMap. Alla element i EnumSet och alla nycklar i EnumMap måste vara av samma uppräkningsbara typ.

2.5 Varargs

Det sista argumentet i en metods parameterlista kan deklareras så här method(int... lastArg). Det innebär att den aktuella parametern vid anropet kan utgöras av ett godtyckligt antal värden eller av en array. I metoden är parametern alltid en array med så många element som det skickades värden till metoden. Här är ett exempel, VarargsTest.java.

2.6 Static Import

Det går att importera statiska deklarationer från en klass. Det görs så här, import static java.lang.Math.PI, eller så här, import static java.lang.Math.*. De importerade statiska deklarationerna kan sedan användas utan att kvalificeras med klassnamnet.

Jag är frestad att säga att det här aldrig ska användas eftersom det smutsar ner klassens namnrymd och gör det svårt för den som läser koden att förstå var en viss deklaration finns. Möjligtvis kan det vara bra om någon enstaka statisk deklaration från en annan klass används väldigt ofta. Det är i alla fall bättre än antimönstret Constant Interface eftersom de importerade deklarationerna inte blir en del av klassens publika gränssnitt.

2.7 Annotations

Det går att defineiera egna annotations (dvs godtycklig information) och sedan koppla dem till vilken deklaration som helst (klass, interface, metod...). Syftet är att de ska användas som metadata om deklarationen, dvs för att ange fakta om den. Metadatat kan sedan anändas av något verktyg för att processa den annoterade deklarationen på något sätt. Ett möjligt användningsområde vore att annotera EJB-implementationer. Sedan skulle ett verktyg kunna processa källkoden för EJB:n och generera deployment descriptorn, remote/local interfacet och home interfacet. Det finns ett verktyg (apt) som kan läsa annoterade filer. Åtgärdena som ska vidtas måste dock programmeras i Java-klasser, vilka sedan kan anropas av apt.

3 Förändringar i java.lang och java.util som inte nämnts ovan

3.1 ProcessBuilder

En ny klass som ska användas i stället för Runtime.exec för att starta subprocesser. En skillnad är att ProcessBuilder kan modifiera subprocessens operativsystemsvariabler.

3.2 Formattering i c-stil

Klassen java.util.Formatter kan hantera formattering av samma typ som i printf i C. I java.io.PrintWriter finns metoder (format() och printf()) som formatterar på det sätt som anges i java.util.Format.

3.3 java.util.Scanner

Denna klass kan scanna en text och (bla) dela upp den i tokens samt konvertera tokens i den till prmitiva typer. Indata är någon form av ström. En intressant detalj är att dess metoder endast kastar runtime exceptions. Det krävs alltså inte några catch-satser för att använda den. Klassen kan hantera regexps.

3.4 Trådhantering

3.4.1 Utility-klasser för trådprogrammering

Paketen java.util.concurrent, java.util.concurrent.atomic och java.util.concurrent.locks innehåller en massa bra-att-ha-klasser för trådprogrammering. Exempel på vad som finns är trådpol, samlingar (både nya definitioner och nya implementationer av gamla klasser som är snabbare i flertrådade program), atomära variabler (som är snabbare än att använda synchronized), lås, klassiska synkroniseringsklasser som tex semaforer och mutex samt tidtagning med (ungefär) en nanosekunds upplösning.

3.4.2 klassen java.lang.Thread

Några av ändringarna i denna klass:

3.5 Några ändringar i collection-api:et som inte nämnts ovan

3.6 Utökning av bytekoden vid runtime

Paketet java.lang.instrument innehåller ett API för att lägga till bytekod i befintliga class-filer. Det är avsett att användas av verktyg.

4. java.net

Inte särskilt mycket, men det som finns handlar bla om cookies, proxys och IPv6.

5. Säkerhets-api:erna

Främst för Kerberos, SSL, kryptering och Simple Authentication and Security Layer (SASL).

6. Monitoring och Management

JMX ingår numera i J2SE (i paketen javax.management.*). Dessutom finns, i paketet java.lang.management, en definition av ett api som bygger på jmx och kan användas för att övervaka en javamotor. Det finns även diverse kommandoradsverktyg för övervakning. En implementation av nyss nämnda api finns i com.sun.management.

7. RMI

Bland annat kan stubbar skapas automatiskt, utan att rmic behöver användas av utvecklaren. Det är även lättare än tidigare att använda rmi över ssl.

8. Databashantering

Nytt i JDBC 3.0 är bla annat att nedanstående fem implementationer av RowSet ingår.

9. Java2D

Bland annat stöd för hårdvaruaccelererad OpenGL.

10. Image I/O

Bland annat kan bmp och wbmp både läsas och skrivas nu.

11. AWT

Bland annat en hel del förbättringar och bugfixar av DnD och data transfer.

12. Swing

Bland annat detta:

13. Java Plug-in och Java Web Start

Bland annat hanterar de ett nytt format av jar-filer, Pack200, som (i bästa fall) reducerar filerna till 1/8 av en jar-fils storlek.