Java 5 Systemvaruhuset AB Råsundavägen 166 Tel 08 50 52 10 42 Fax 08 50 52 10 10 Org. Nr 556665-7614 169 36 Solna E-post [email protected] www.systemvaruhuset.se Introduktion till Java 5 1 Bakgrund och historik .......................................................................... 2 2 Versionsbenämning i Java .................................................................... 2 3 Nyheter i språket ................................................................................ 2 3.1 Stöd för metadata........................................................................ 2 3.2 Generisk kod .............................................................................. 5 3.3 Autoboxing och Auto-Unboxing av primitiva datatyper ..................... 6 3.4 Förenklad for-loop ....................................................................... 6 3.5 Uppräkningsbar typ ..................................................................... 7 3.6 Variabelt antal argument till metoder.............................................. 7 4 Övrigt................................................................................................ 7 5 Läs mer.............................................................................................. 9 1(9) Java 5 Systemvaruhuset AB Råsundavägen 166 Tel 08 50 52 10 42 Fax 08 50 52 10 10 Org. Nr 556665-7614 1 169 36 Solna E-post [email protected] www.systemvaruhuset.se Bakgrund och historik Java 5 släpptes den 29 september 2004 och innebar en betydande förändring av språket. 2 Versionsbenämning i Java Java 5 eller J2SE (Java 2 Standard Edition) 5.0 har även versionsnumret 1.5.0 och kodnamnet Tiger. Anledningen till numret 1.5.0 är att föregående versioner har numrerats från 1.1.4, 1.1.5 till 1.4.2, som är föregångaren till 1.5.0. Från och med 1.5.0 säger Sun att varje Javaversion har ett internt versionsnummer (ex. 1.5.0) och ett externt versionsnummer (ex. 5.0). Dessutom kallas alla versioner från och med 1.2, Java 2 så därav Java 2 Standard Edition 5.0 (1.5.0). Förutom Standard Edition som är själva språket och alla klasser/interface som ingår (String, Collection, ArrayList, alla swingoch awt-klasser och många fler) så finns det en Enterprise Edition (J2EE) som specificerar ett ramverk som kan användas för att bygga distribuerade applikationer (innehåller bl.a. en specifikation för ett persistent ramverk, asynkron meddelandehantering etc.). Vidare finns det en Mobile Edition (J2ME) som är anpassad för mobila enheter, exempelvis mobiltelefoner. Kuriosa: planerade framtida versioner skall heta J2SE 6.0 (1.6.0) Mustang och J2SE 7.0 (1.7.0) Dolphin. 3 Nyheter i språket 3.1 Stöd för metadata Via s.k. Annotations kan extra data kopplas till klasser, interface, metoder och attribut. Det finns tre stycken inbyggda annotations i Java 5 varav @Override är en och denna exemplifierar hur annotations kan användas. En metod i en subklass som skall överrida en metod i en basklass kan märkas med @Override vilket gör att kompilatorn genererar ett fel om den @Overridedeklarerade metoden saknas i basklassen. Detta eliminerar ett klassiskt fel där programmeraren stavar fel på metoden i subklassen och således inte överrider metoden i basklassen. Ett exempel är att metoden hashCode skall överridas och 2(9) Java 5 Systemvaruhuset AB Råsundavägen 166 Tel 08 50 52 10 42 Fax 08 50 52 10 10 Org. Nr 556665-7614 169 36 Solna E-post [email protected] www.systemvaruhuset.se metoden stavas hashcode istället för hashCode i subklassen. I och med Java 5 kan detta fel undgås med hjälp av @Override. Exempel: @Override public int hashCode() {...} // OK @Override public int hashcode() {...} // Ger kompileringsfel. hashcode saknas i basklassen. Förutom de inbyggda annoteringarna kan egna annoteringar definieras. I nedanstående exempel definieras en annotation @UnitTest och denna används i ett mycket enkelt ramverk för enhetstester som helt enkelt exekverar de metoder (i de .class-filer som är inparameter) som är annoterade med @UnitTest och skriver ut värdet som är parameter till @UnitTest. Observera hur annoteringen UnitTest deklareras med inledande public @interface. @Retention och RetentionPolicy.RUNTIME säger att annoteringen skall gälla även under exekvering eftersom det är där vi med hjälp av reflection läser vilka metoder som är annoterade med @UnitTest (se TestRunner). Exempelvis @Override som nämns ovan kan ha RetentionPolicy.CLASS vilket innebär att annoteringen inte finns med vid exekvering. @Override skall ju användas endast vid kompilering. @Target anger på vilken typ av programelement denna annotering är applicerbar. I detta fall på metoder. Kom ihåg att aktivera assertions (-ea-parametern) om exekvering av detta exempel. // UnitTest.java import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.METHOD}) public @interface UnitTest { String value(); } 3(9) Java 5 Systemvaruhuset AB Råsundavägen 166 Tel 08 50 52 10 42 Fax 08 50 52 10 10 Org. Nr 556665-7614 169 36 Solna E-post [email protected] www.systemvaruhuset.se // Example.java public class Example { @UnitTest (value="testar om 4 är lika med 2*2") public void method1() { assert 4 == 2*2; } @UnitTest (value="testar om 4 är mindre än 2*2") public void method2() { assert 4 < 2*2; } public void method3() { // This method will not be executed as a unit test } } // TestRunner.java import java.lang.reflect.*; public class TestRunner { static void executeUnitTests(String className) { try { Object testObject = Class.forName(className).newInstance(); Method[] methods = testObject.getClass().getDeclaredMethods(); for (Method amethod : methods) { UnitTest utAnnotation = amethod.getAnnotation(UnitTest.class); if (utAnnotation != null) { System.out.print(utAnnotation.value() + " : "); String result = invoke(amethod, testObject); System.out.println(result); } } } catch (Exception e) { e.printStackTrace(); } } static String invoke(Method m, Object o) { String result = "passed"; try { Object[] noparams = {}; m.invoke(o, noparams); } catch (Exception e) { result = "failed"; } return result; } public static void main(String[] args) { executeUnitTests(args[0]); } } Efter exekvering av detta exempel blir utdata: 4(9) Java 5 Systemvaruhuset AB Råsundavägen 166 Tel 08 50 52 10 42 Fax 08 50 52 10 10 Org. Nr 556665-7614 169 36 Solna E-post [email protected] www.systemvaruhuset.se testar om 4 är lika med 2*2 : passed testar om 4 är mindre än 2*2 : failed Mycket av idéerna bakom annotations kommer från SourceForge XDoclet som blivit defacto-standard inom J2EE-utveckling. I och med J2EE 5 så kommer annotations att användas på liknande sätt som XDoclet-tag:ar använts för att generera deploymentdeskriptorer och Remote-interface. 3.2 Generisk kod Generics är Javas motsvarighet till C++ templates. I och med generics får Java compile-time-polymorfism vilket är mycket användbart bl.a. vid användning av Collections (ArrayList i nedanstående exempel). Ett tidigare mycket vanligt misstag var att anropa en metod som returnerade exempelvis en ArrayList varefter anroparen typomvandlade objekten i listan till en icke giltig typ och fick ett ClassCastException. Med generics får anroparen stöd av kompilatorn för denna typomvandling och den som implementerar metoden kan returnera en ArrayList av en viss typ av objekt. Exempel med och utan generics: public static ArrayList fooJava1_4() { Person person1 = new Person(); Person person2 = new Person(); ArrayList ret = new ArrayList(); ret.add(person1); ret.add(person2); return ret; } public static void exempelJava1_4() { ArrayList list = fooJava1_5(); for (int i = 0; i < list.size(); i++) { Fordon f = (Fordon)list.get(i); // Ger inget kompileringsfel. // ClassCastException kastas vid exekvering. } } // generics public static ArrayList<Person> fooJava1_5() { Person person1 = new Person(); Person person2 = new Person(); ArrayList<Person> ret = new ArrayList<Person>(); ret.add(person1); ret.add(person2); return ret; } // generics public static void exempelJava1_5() { 5(9) Java 5 Systemvaruhuset AB Råsundavägen 166 Tel 08 50 52 10 42 Fax 08 50 52 10 10 Org. Nr 556665-7614 169 36 Solna E-post [email protected] www.systemvaruhuset.se ArrayList<Person> list = fooJava1_5(); for (int i = 0; i < list.size(); i++) { Person p = list.get(i); // Ger kompileringsfel om försöker läsa // nåt annat än ett Person-objekt ur listan } } 3.3 Autoboxing och Auto-Unboxing av primitiva datatyper Konvertering mellan primitiva datatyper (ex. int, char, boolean) och dess motsvarande omslutande klasser (ex. Integer, Character, Boolean) sker sedan Java 5 implicit av kompilatorn. Detta medför att tilldelningar enligt nedan är fullt möjliga: int i1 = 5; Integer i2 = i1; int i3 = i2; Dock medför denna språkegenskap ökad risk till fel vilket visas av nedanstående tilldelning som kommer att resultera i ett NullPointerException vid exekvering. Tidigare förhindrade kompilatorn detta. Integer uninitialized = null; int i = uninitialized; 3.4 Förenklad for-loop Java 5 ger ett förkortat sätt att skriva en for-loop: ArrayList<Integer> list = new ArrayList<Integer>(); for (Iterator i = list.iterator(); i.hasNext();) { Integer value=(Integer)i.next(); } // Java 5 ArrayList<Integer> list = new ArrayList<Integer>(); for (Integer value : list) { ... } 6(9) Java 5 Systemvaruhuset AB Råsundavägen 166 Tel 08 50 52 10 42 Fax 08 50 52 10 10 Org. Nr 556665-7614 169 36 Solna E-post [email protected] www.systemvaruhuset.se 3.5 Uppräkningsbar typ Tidigare implementerades en uppräkningsbar typ via ett idiom, i och med Java 5 ingår nyckelordet enum i språket: public enum StopLight { red, amber, green }; 3.6 Variabelt antal argument till metoder Enligt nedan kan metoder med variabelt antal argument definieras och anropas. public static void varargs(int... arguments) { for (int i = 0; i < arguments.length; i++) { System.out.println("arguments[" + i + "]=" + arguments[i]); } } public static void foo() { varargs(8, 2, 3); } Denna egenskap medför att det i Java 5 finns en System.out.printf motsvarande printf i C/C++ som tar en formatsträng som första argument och ett efterföljande variabelt antal argument. System.out.printf("En sträng: %s, ett heltal: %d", "Hello World", 8); 4 Övrigt • Ett nytt paket java.util.concurrent med klasser för hantering av samtidighet och trådar • En ny klass java.util.Scanner som kan användas på System.in för att läsa textinmatning. Exempel: Scanner scan = new Scanner(System.in); System.out.print("What is your name? "); String name = scan.next(); System.out.print("How old are you? "); int age = scan.nextInt(); String msgPattern = "Hi {0}. You are {1} years old."; 7(9) Java 5 Systemvaruhuset AB Råsundavägen 166 Tel 08 50 52 10 42 Fax 08 50 52 10 10 Org. Nr 556665-7614 169 36 Solna E-post [email protected] www.systemvaruhuset.se String msg = MessageFormat.format(msgPattern, name, age); System.out.println(msg); • • Förbättringar vad gäller säkerhet som ger möjlighet att använda ickeblockerande SSL/TLS, Kerberos krypteringsalgoritmer, SASL och Time Stamp-protokollet. Ett nytt tema javax.swing.plaf.metal.OceanTheme (Figur 1) till Metal look and feel. Jämför med tidigare javax.swing.plaf.metal.DefaultMetalTheme enligt Figur 2. Figur 1: javax.swing.plaf.metal.OceanTheme 8(9) Java 5 Systemvaruhuset AB Råsundavägen 166 Tel 08 50 52 10 42 Fax 08 50 52 10 10 Org. Nr 556665-7614 169 36 Solna E-post [email protected] www.systemvaruhuset.se Figur 2: javax.swing.plaf.metal.DefaultMetalTheme • • Stöd för att skriva ut innehållet i en JTable. Detta var mycket komplicerat i tidigare Javaversioner. Ett nytt API kallat JVMTI (Java Virtual Machine Tool Interface) som ger acess till applikationer i JVM:en. Används av bl.a. utvecklings- och övervakningsverktyg. Ersätter JVMPI och JVMDI. Dessutom innehåller JPDA (Java Platform Debugger Architecture) diverse förbättringar och nyheter. 5 Läs mer • http://java.sun.com/developer/technicalArticles/releases/j2se15 • http://java.sun.com/developer/technicalArticles/releases/j2se50/Migr ateToTiger.html • Benämningar av Javaversioner: http://java.sun.com/j2se/codenames.html 9(9)