Java 1.5
Transcription
Java 1.5
Java 1.5 F. Barthélemy 14 mars 2006 1 Introduction Java a connu plusieurs versions qui ont apporté des changements plus ou moins importants. A chaque fois la compatibilité ascendante est assurée. Le dernier grand changement a été le passage de la version 1.4 à la version 1.5 qui a introduit beaucoup de nouveautés dans le langage. Ce changement est intervenu dans le courant de l’été 2004. Ces changements sont apportés au niveau du langage alors que la machine virtuelle sousjacente (JVM) n’a pas changé. Pour la plupart, les changements sont donc des facilités syntaxiques qui permettent d’écrire plus simplement des programmes qui sont équivalents à ceux qu’on pouvait écrire avant. Nous allons donc pouvoir utiliser un décompilateur pour obtenir un programme type java 1.4 équivalent à ce que nous allons écrire avec java 1.5. Ce chapitre se décompose en deux parties : – diverses petites améliorations. – la généricité, qui est un changement plus conséquent. 2 2.1 Petites innovations Autoboxing des types primitifs import j a v a . u t i l . ∗ ; c l a s s Old{ public s t a t i c void main ( S t r i n g [ ] a r g s ){ Integer i ; int x = 1 2 ; i = new I n t e g e r ( x ) ; x = i . intValue ( ) ; Vector v = new Vector ( ) ; int [ ] t = { 1 , 2 , 3 , 4 } ; v . add (new I n t e g e r ( t [ 1 ] ) ) ; t [ 0 ] = ( ( I n t e g e r ) v . elementAt ( 0 ) ) . i n t V a l u e ( ) ; } } c l a s s AutoBoxing { public s t a t i c void main ( S t r i n g [ ] a r g s ){ Integer i ; int x = 1 2 ; 1 i = x; x = i; Vector v = new Vector ( ) ; int [ ] t = { 1 , 2 , 3 , 4 } ; v . add ( 1 ) ; t [ 0 ] = ( I n t e g e r ) v . elementAt ( 0 ) ; } } La décompilation de la classe AutoBoxing : // // // // Decompiled by Jad v1 . 5 . 8 e . C o p y r i g h t 2 0 0 1 P a v e l Kouznetsov . Jad home page : h t t p : / /www . g e o c i t i e s . com/ kpdus / j a d . html Decompiler o p t i o n s : p a c k i m p o r t s ( 3 ) Source F i l e Name : AutoBoxing . j a v a import j a v a . u t i l . Vector ; c l a s s AutoBoxing { AutoBoxing ( ) { } public s t a t i c void main ( S t r i n g a r g s [ ] ) { int i = 1 2 ; I n t e g e r i n t e g e r = I n t e g e r . valueOf ( i ) ; i = integer . intValue ( ) ; Vector v e c t o r = new Vector ( ) ; int a i [ ] = { 1, 2, 3, 4 }; v e c t o r . add ( I n t e g e r . valueOf ( 1 ) ) ; a i [ 0 ] = ( ( I n t e g e r ) v e c t o r . elementAt ( 0 ) ) . i n t V a l u e ( ) ; } } 2.2 Boucle for pour les iterateurs public i n t e r f a c e j a v a . u t i l . I t e r a t o r { boolean hasNext ( ) ; Object next ( ) ; } public i n t e r f a c e j a v a . l a n g . i t e r a b l e { Iterator iterator (); 2 } import j a v a . u t i l . Vector ; class ForIterator { Vector v = new Vector ( ) ; v . add ( 1 5 ) ; v . add ( 1 0 ) ; v . add ( 5 ) ; v . add ( 2 0 ) ; for ( Object o : v ){ System . out . p r i n t l n ( o . t o S t r i n g ( ) ) ; } } } c l a s s ForTableau { public s t a t i c void main ( S t r i n g [ ] a r g s ) { int [ ] tab = { 1 , 2 , 3 , 4 } ; for ( int i : tab ){ System . out . p r i n t l n ( i ) ; } } } Décompilation de ces classes : / Decompiled by Jad v1 . 5 . 8 e . Copyright 2 0 0 1 Pavel Kouznetsov . // Jad home page : h t t p : / /www . g e o c i t i e s . com/ kpdus / j a d . html // Decompiler o p t i o n s : p a c k i m p o r t s ( 3 ) // Source F i l e Name : ForIterator . java import j a v a . i o . PrintStream ; import j a v a . u t i l . I t e r a t o r ; import j a v a . u t i l . Vector ; class ForIterator { ForIterator () { } public s t a t i c void main ( S t r i n g a r g s [ ] ) { Vector v e c t o r = new Vector ( ) ; v e c t o r . add ( I n t e g e r . valueOf ( 1 5 ) ) ; v e c t o r . add ( I n t e g e r . valueOf ( 1 0 ) ) ; v e c t o r . add ( I n t e g e r . valueOf ( 5 ) ) ; v e c t o r . add ( I n t e g e r . valueOf ( 2 0 ) ) ; 3 Object o b j ; for ( I t e r a t o r i t e r a t o r = v e c t o r . i t e r a t o r ( ) ; i t e r a t o r . hasNext ( ) ; System . o t . p r i n t l n ( obj . t o S t r i n g ( ) ) ) o b j = i t e r a t o r . next ( ) ; } } // // // // Decompiled by Jad v1 . 5 . 8 e . C o p y r i g h t 2 0 0 1 P a v e l Kouznetsov . Jad home page : h t t p : / /www . g e o c i t i e s . com/ kpdus / j a d . html Decompiler o p t i o n s : p a c k i m p o r t s ( 3 ) Source F i l e Name : ForIterator . java import j a v a . i o . PrintStream ; c l a s s ForTableau { ForTableau ( ) { } public s t a t i c void main ( S t r i n g a r g s [ ] ) { int a i [ ] = { 1, 2, 3, 4 }; int a i 1 [ ] = a i ; int i = a i 1 . l e n g t h ; for ( int j = 0 ; j < i ; j ++) { int k = a i 1 [ j ] ; System . out . p r i n t l n ( k ) ; } } } 2.3 Méthodes à nombre de paramètres variable class TroisPoints { public s t a t i c int a d d i t i o n n e r ( int . . . v a l s ) { int t o t a l = 0 ; for ( int i =0; i <v a l s . l e n g t h ; i ++){ total = total + vals [ i ] ; } return t o t a l ; 4 } public s t a t i c void main ( S t r i n g [ ] a r g s ) { int [ ] tab = { 1 , 2 , 3 } ; System . out . p r i n t l n ( a d d i t i o n n e r ( 1 , 2 , 3 , 4 , 5 ) ) ; System . out . p r i n t l n ( a d d i t i o n n e r ( tab ) ) ; } } Décompilation : // // // // Decompiled by Jad v1 . 5 . 8 e . C o p y r i g h t 2 0 0 1 P a v e l Kouznetsov . Jad home page : h t t p : / /www . g e o c i t i e s . com/ kpdus / j a d . html Decompiler o p t i o n s : p a c k i m p o r t s ( 3 ) Source F i l e Name : TroisPoints . java import j a v a . i o . PrintStream ; class TroisPoints { TroisPoints () { } public s t a t i c transient int a d d i t i o n n e r ( int a i [ ] ) { int i = 0 ; for ( int j = 0 ; j < a i . l e n g t h ; j ++) i += a i [ j ] ; return i ; } public s t a t i c void main ( S t r i n g a r g s [ ] ) { int a i [ ] = { 1, 2, 3 }; System . out . p r i n t l n ( a d d i t i o n n e r (new int [ ] { 1, 2, 3, 4, 5 })); System . out . p r i n t l n ( a d d i t i o n n e r ( a i ) ) ; } } class TroisPointsBis{ public s t a t i c int a d d i t i o n n e r ( boolean b , int . . . v a l s ) { int t o t a l = 0 ; 5 for ( int i =0; i <v a l s . l e n g t h ; i ++){ total = total + vals [ i ] ; } return t o t a l ; } public s t a t i c void main ( S t r i n g [ ] a r g s ) { int [ ] tab = { 1 , 2 , 3 } ; System . out . p r i n t l n ( a d d i t i o n n e r ( true , 1 , 2 , 3 , 4 , 5 ) ) ; System . out . p r i n t l n ( a d d i t i o n n e r ( f a l s e , tab ) ) ; } } On ne peut utiliser qu’un seul type d’argument variable par méthode, et il doit obligatoirement être en dernière position dans la liste des paramètres. 2.4 Types énumérés enum Carte {PIQUE , COEUR, CARREAU, TREFLE} 6 f i n a l c l a s s Carte extends Enum { public s t a t i c Carte valueOf ( S t r i n g s ) { Carte a c a r t e [ ] = $VALUES ; int i = a c a r t e . l e n g t h ; for ( int j = 0 ; j < i ; j ++) { Carte c a r t e = a c a r t e [ j ] ; i f ( c a r t e . name ( ) . e q u a l s ( s ) ) return c a r t e ; } throw new I l l e g a l A r g u m e n t E x c e p t i o n ( s ) ; } private Carte ( S t r i n g s , int i ) { super ( s , i ) ; } public s t a t i c f i n a l Carte PIQUE ; public s t a t i c f i n a l Carte COEUR; public s t a t i c f i n a l Carte CARREAU; public s t a t i c f i n a l Carte TREFLE; private s t a t i c f i n a l Carte $VALUES [ ] ; static { PIQUE = new Carte ( ”PIQUE” , 0 ) ; COEUR = new Carte ( ”COEUR” , 1 ) ; CARREAU = new Carte ( ”CARREAU” , 2 ) ; TREFLE = new Carte ( ”TREFLE” , 3 ) ; $VALUES = (new Carte [ ] { PIQUE , COEUR, CARREAU, TREFLE }); } } 7 public enum Numbers { ONE( ” p r e m i e r e o c c u r r e n c e ” , 1 ) , TWO( ” deuxieme o c c u r r e n c e ” , 2 ) , THREE( ” t r o i s i e m e o c c u r r e n c e ” , 3 ) ; Numbers ( S t r i n g d e s c r i p t i o n , int v a l u e ) { this . d e s c r i p t i o n = d e s c r i p t i o n ; this . value = value ; } private S t r i n g d e s c r i p t i o n ; private int v a l u e ; public S t r i n g g e t D e s c r i p t i o n ( ) { return t h i s . d e s c r i p t i o n ; } public int getValue ( ) { return t h i s . v a l u e ; } } 8 public f i n a l c l a s s Numbers extends Enum { public s t a t i c f i n a l Numbers [ ] v a l u e s ( ) { return ( Numbers [ ] ) $VALUES . c l o n e ( ) ; } public s t a t i c Numbers valueOf ( S t r i n g s ) { Numbers anumbers [ ] = $VALUES ; int i = anumbers . l e n g t h ; for ( int j = 0 ; j < i ; j ++) { Numbers numbers = anumbers [ j ] ; i f ( numbers . name ( ) . e q u a l s ( s ) ) return numbers ; } throw new I l l e g a l A r g u m e n t E x c e p t i o n ( s ) ; } private Numbers ( S t r i n g s , int i , S t r i n g s1 , int j ) { super ( s , i ) ; d e s c r i p t i o n = s1 ; value = j ; } public S t r i n g g e t D e s c r i p t i o n ( ) { return d e s c r i p t i o n ; } public int getValue ( ) { return v a l u e ; } public s t a t i c f i n a l Numbers ONE; public s t a t i c f i n a l Numbers TWO; public s t a t i c f i n a l Numbers THREE; private S t r i n g d e s c r i p t i o n ; private int v a l u e ; private s t a t i c f i n a l Numbers $VALUES [ ] ; 9 static { ONE = new Numbers ( ”ONE” , 0 , ” p r e m i e r e o c c u r r e n c e ” , 1 ) ; TWO = new Numbers ( ”TWO” , 1 , ” deuxieme o c c u r r e n c e ” , 2 ) ; THREE = new Numbers ( ”THREE” , 2 , ” t r o i s i e m e o c c u r r e n c e ” , 3 ) ; $VALUES = (new Numbers [ ] { ONE, TWO, THREE }); } } 3 La généricité 3.1 Avant la généricité Avant la généricité, on renonçait à typer certaines variables, à charge pour le programmeur de faire lui même un typage explicite (cast) dans certains cas. Exemple : class Cell { private Object v a l ; C e l l ( Object o ){ val = o ; } void s e t ( Object o ){ val = o ; } Object g e t ( ) { return v a l ; } } class UseCell { public s t a t i c void main ( S t r i n g [ ] a r g s ){ C e l l c = new C e l l (new Compte ( ” Martin ” ) ) ; // c . g e t ( ) . d e p o t ( 5 0 ) ; // C e l l . j a v a : 1 6 : cannot f i n d symbol // symbol : method d e p o t ( i n t ) // l o c a t i o n : c l a s s j a v a . l a n g . O b j e c t ( ( Compte ) c . g e t ( ) ) . depot ( 5 0 ) ; ( ( Compte ) c . g e t ( ) ) . p r i n t ( ) ; } } Autre exemple, tiré de la librairie standard : import j a v a . u t i l . Vector ; c l a s s UseVector { public s t a t i c void main ( S t r i n g [ ] a r g s ){ 10 Vector v = new Vector ( 1 2 ) ; v . add (new Compte ( ” Martin ” ) ) ; v . add (new I n t e g e r ( 5 ) ) ; v . add (new Vector ( ) ) ; System . out . p r i n t l n ( v . t o S t r i n g ( ) ) ; // [ Compte@82ba41 , 5 , [ ] ] // // v . elementAt ( 0 ) . d e p o t ( 5 0 ) ; // UseVector . j a v a : 9 : cannot f i n d symbol // symbol : method d e p o t ( i n t ) // l o c a t i o n : c l a s s j a v a . l a n g . O b j e c t ( ( Compte ) v . elementAt ( 0 ) ) . depot ( 5 0 ) ; ( ( Compte ) v . elementAt ( 0 ) ) . p r i n t ( ) ; } } 3.2 Avec la généricité, version de base c l a s s C e l l 2 <T>{ T val ; C e l l 2 (T x ){ val = x ; } void s e t (T x ){ val = x ; } T get (){ return v a l ; } } class UseCell2 { public s t a t i c void main ( S t r i n g [ ] a r g s ){ C e l l 2 <Compte> c = new C e l l 2 <Compte>( new Compte ( ” Martin ” ) ) ; c . g e t ( ) . depot ( 5 0 ) ; c . get ( ) . print ( ) ; } } Décompilation : // // // // Decompiled by Jad v1 . 5 . 8 e . C o p y r i g h t 2 0 0 1 P a v e l Kouznetsov . Jad home page : h t t p : / /www . g e o c i t i e s . com/ kpdus / j a d . html Decompiler o p t i o n s : p a c k i m p o r t s ( 3 ) Source F i l e Name : UseCell2 . java 11 class Cell2 { C e l l 2 ( Object o b j ) { val = obj ; } void s e t ( Object o b j ) { val = obj ; } Object g e t ( ) { return v a l ; } Object v a l ; } // // // // Decompiled by Jad v1 . 5 . 8 e . C o p y r i g h t 2 0 0 1 P a v e l Kouznetsov . Jad home page : h t t p : / /www . g e o c i t i e s . com/ kpdus / j a d . html Decompiler o p t i o n s : p a c k i m p o r t s ( 3 ) Source F i l e Name : UseCell2 . java class UseCell2 { UseCell2 ( ) { } public s t a t i c void main ( S t r i n g a r g s [ ] ) { C e l l 2 c e l l 2 = new C e l l 2 (new Compte ( ” Martin ” ) ) ; ( ( Compte ) c e l l 2 . g e t ( ) ) . depot ( 5 0 ) ; ( ( Compte ) c e l l 2 . g e t ( ) ) . p r i n t ( ) ; } } Et l’autre exemple : import j a v a . u t i l . Vector ; c l a s s UseVector2 { public s t a t i c void main ( S t r i n g [ ] a r g s ){ Vector<Compte> v = new Vector<Compte > ( 1 2 ) ; v . add (new Compte ( ” Martin ” ) ) ; 12 // v . add ( new I n t e g e r ( 5 ) ) ; // UseVector2 . j a v a : 6 : cannot f i n d symbol // symbol : method add ( j a v a . l a n g . I n t e g e r ) // l o c a t i o n : c l a s s j a v a . u t i l . Vector<Compte> System . out . p r i n t l n ( v . t o S t r i n g ( ) ) ; // [ Compte@82ba41 ] v . elementAt ( 0 ) . depot ( 5 0 ) ; v . elementAt ( 0 ) . p r i n t ( ) ; } } 3.3 Paramètre de type avec borne supérieure c l a s s C e l l 3 <T extends Compte>{ T val ; C e l l 3 (T x ){ val = x ; } void s e t (T x ){ val = x ; } T get (){ return v a l ; } void a f f i c h e ( ) { val . print ( ) ; } } class UseCell3 { public s t a t i c void main ( S t r i n g [ ] a r g s ){ C e l l 3 <CompteSecurise > c ; c = new C e l l 3 <CompteSecurise >( new CompteSecurise ( ” Martin ” ) ) ; c . get ( ) . r e t r a i t (60); c . g e t ( ) . depot ( 5 0 ) ; c . get ( ) . print ( ) ; } } Décompilation : // // // // Decompiled by Jad v1 . 5 . 8 e . C o p y r i g h t 2 0 0 1 P a v e l Kouznetsov . Jad home page : h t t p : / /www . g e o c i t i e s . com/ kpdus / j a d . html Decompiler o p t i o n s : p a c k i m p o r t s ( 3 ) Source F i l e Name : UseCell3 . java 13 class Cell3 { C e l l 3 ( Compte compte ) { v a l = compte ; } void s e t ( Compte compte ) { v a l = compte ; } Compte g e t ( ) { return v a l ; } void a f f i c h e ( ) { val . print ( ) ; } Compte v a l ; } 14