Top Banner
Project Coin features i Java 7 Jan Krag 14. Juni 2013 For Udvikling 1
35

Project Coin features in Java 7

Jul 17, 2015

Download

Technology

Jan Krag
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Project Coin features in Java 7

Project Coin features i Java 7

Jan Krag

14. Juni 2013

For Udvikling 1

Page 2: Project Coin features in Java 7

Project Coin

Projekt til forbedring af Java sproget http://openjdk.java.net/projects/coin/

Delt op mod hhv. Java 7 og Java 8

Målsætninger: Gøre java kode mere læsbar

Opfordre til at skrive mere pålidelig kode

velintegreret med både tidligere og fremtidigesprogændringer

Færre tastetryk, renere kode, gladereudviklere

Page 3: Project Coin features in Java 7

Begrænsninger

INGEN ændringer I JVM’en

Koordineret med kommende Java 8/9 ændringer

Forholdsvis små sprogændringer

Dvs. “små” med henblik på:

ændringer til language spec.

Implementering

Refac af eksisterende libraries

Test

Page 4: Project Coin features in Java 7

Overblik: the 7-4-7

1. Improved literals

2. Strings in switch

3. Try-with-resources

4. Multicatch

5. Precise rethrow

6. Diamond operator

7. Safe Varargs

Page 5: Project Coin features in Java 7

1a) Binary literals

Nu kan man også specificere konstanter

I binær form:

byte b = 0b01001101;

Page 6: Project Coin features in Java 7

1b) Underscores in literals

Den “lille forskel”

Det er nu lovligt at sætte (vilkårligt

mange) underscores mellem “cifre” in

talkonstanter

Kun med formål at gøre koden mere

læsbar.

Ingen konsekvenser efter compile

Page 7: Project Coin features in Java 7

Eksempel

long creditCardNumber =

1234567890123456L;

long bytes =

0b11010010011010011001010010010010;

Kan nu skrives som:

long creditCardNumber =

1234_5678_9012_3456L;

long bytes =

0b11010010_01101001_10010100_10010010;

long hexWords = 0xCAFE_BABE;

int ok = 5_______2;

Page 8: Project Coin features in Java 7

Men ikke alt er lovligt:

float pi1 = 3_.1415F;

float pi2 = 3._1415F;

long s = 999_99_9999_L;

int x3 = 52_;

int x6 = 0x_52;

int x5 = 0_x52;

int x1 = _52; // lovligt, men er et variabel navn, ikke en talkostant

Page 9: Project Coin features in Java 7

// Courtesy Josh Bloch

int bond =

0000_____________0000________0000000000000000__000000000000000000+

00000000_________00000000______000000000000000__0000000000000000000+

000____000_______000____000_____000_______0000__00______0+

000______000_____000______000_____________0000___00______0+

0000______0000___0000______0000___________0000_____0_____0+

0000______0000___0000______0000__________0000___________0+

0000______0000___0000______0000_________000+__0000000000+

0000______0000___0000______0000________0000+

000______000_____000______000________0000+

000____000_______000____000_______00000+

00000000_________00000000_______0000000+

0000_____________0000________000000007;

Page 10: Project Coin features in Java 7

2) Strings in switch

int monthNameToDays(String s, int year) {

switch(s) {case "April":

case "June":

case "September":

case "November":

return 30;

case "January":

case "March":

case "May":

case "July":

case "August":

case "December":

return 31;

case "February":

return 31;

default: ...

}

Page 11: Project Coin features in Java 7

Strings in switch

Tilføjet kun 1 ord i JLS!

Implementeret med “desugaring” instedet for JVM ændring!

Dvs. koden reduceres pre-compile til en form der allerede er understøttet

Bruger en switch på String.hashCode (ogequality checks ved hash collision) til at oversætte til int’s, og derefter bare en intswitch.

… perfomer derved klart bedre end en langrække equality checks på strenge

Page 12: Project Coin features in Java 7

Ulempe???

Risiko: Kan friste udviklere til at

misbruge Strings til kode hvor rigtige

type-stærke datatyper ville være bedre

(ofte Enums)

Page 13: Project Coin features in Java 7

3) Try with resources

Stort problem med nuværende måde at

sikre lukning af åbne resourcer.

Åbning af resourcer kan smide exceptions,

og skal derfor I try-catch.

Lukning af resourcer kan smide exceptions

og derfor skal der ny try-catch I finally osv.

Går helt galt med de typiske chainede

resourcer (input stream etc.), hvor der er

flere lag der kan smide exceptions

Page 14: Project Coin features in Java 7

Du tror måske…

… at du kan skrive koden “rigtig” men…

Da man i forbindelse med den nye feature

(tålmodighed please) analyserede de

eksisterende Java standard libraries, fandt

man ud af at koden var “forkert” I 66% af

alle tilfælde, så selv dem der har skrevet

JDK’en har ikke kunnet finde ud af at gøre

koden vandtæt.

Page 15: Project Coin features in Java 7

public static void main(String[] args) {

BufferedReader br = null;

try {

String line;

br = new BufferedReader(

new FileReader("C:\\testing.txt")

);

while ((line = br.readLine()) != null) {

System.out.println(line);

}

} catch (IOException e) {

e.printStackTrace();

} finally {

try {

if (br != null)br.close();

} catch (IOException ex) {

ex.printStackTrace();

}

}

}

Page 16: Project Coin features in Java 7

Ny version:

public static void main(String[] args) {

try (

BufferedReader br =

new BufferedReader(

new FileReader("C:\\testing.txt")))

{

String line;

while ((line = br.readLine()) != null) {

System.out.println(line);

}

} catch (IOException e) {

e.printStackTrace();

}

}

Page 17: Project Coin features in Java 7

try(assignment; assignment; …)

Alle resourcer bliver automatisk lukket eftertry-blokken

Men: der var en del “skjulte” detaljer der skulle håndteres:

Der kan nu genereres flere exceptions I blokken, og vi vil ikke “miste” de underliggende helt

null- håndtering (forsøg på close afresource initialiseret til null)

Page 18: Project Coin features in Java 7

Try with resources -

implementering

Nyt interface: java.lang.AutoCloseable,

indsat I hieraki over java.io.Closable

Ny feature Throwable.addSuppressed

Taget I brug I den eksisterende JDK

Bl.a. også I JDBC 4.1

Også implementeret med “desugaring”

instedet for JVM ændring!

Page 19: Project Coin features in Java 7

Desugar

try ResourceSpecification

Block

Page 20: Project Coin features in Java 7

… bliver til{

final VariableModifiers_minus_final R #resource = Expression;

Throwable #primaryException = null;

try ResourceSpecification

Block

catch (Throwable #t) {

#primaryException = t;

throw #t;

} finally {

if (#resource != null) {

if (#primaryException != null) {

try {

#resource.close();

} catch(Throwable #suppressedException) {

#primaryException.addSuppressed(#suppressedException);

}

} else {

#resource.close();

}

}

}

}

Page 21: Project Coin features in Java 7

4) Multicatch – kort fortalt

static <T> T instantiate(Class<? extends T> cl) {

try {

return cl.newInstance();

} catch (

IllegalAccessException | InstantiationException leeloo) {

throw new IllegalArgumentException(leeloo);

}

}

Page 22: Project Coin features in Java 7

Multicatch

Sparer en masse kode-duplikering

(DRY)

Giver faktisk lidt bedre performance, da

det oversættes (af javac) til én entry i

exception tabellen istedet for 4

Page 23: Project Coin features in Java 7

Multicatch - detaljer

Kræver i princippet at Exception

variablen er final (jvm detaljer), men det

håndteres nu af compileren med ny

“effectively final” analyse

Hvad med:

catch(Foo | SonOfFoo e) {...}

p.t. specifikt forbudt i JDK 7

Men kan sagtens tilføjes senere

Page 24: Project Coin features in Java 7

5) Precise rethrow

try {

// Reflection operationer som f.eks.

//Class.forName, Class.newInstance,

} catch(

ClassNotFoundException | InstantiationException |

NoSuchMethodException | InvocationTargetException e) {

log(e);

throw e;

}

Eller uden multicatch:

… catch(Exception e) {

log(e);

throw(e);

}

Page 25: Project Coin features in Java 7

Precise rethrow

… hvad er så typen af den Exception der

kastes i throw(e)?

I JDK <7 er det altid typen af variablen

e, dvs. I praksis “Exception”, og det er jo

problematisk og upraktisk når e ikke kan

være andet end det try-blokken rent

faktisk kan smide.

Page 26: Project Coin features in Java 7

Rethrow I JDK 7 og frem

Nu kan compileren holde styr på hvilken

type ens Exception rent faktisk kan

have, og derfor smides en “sammensat

type” af de exceptions der er på tale.

Denne sammensatte type kan ikke

“udtrykkes” i kode, (så derfor er der

stadig udfordringer hvis Exc. skal

“gemmes” og smides andetsteds f.eks. i

en anden tråd)

Page 27: Project Coin features in Java 7

Precise rethrow - konklusion

I praksis en meget brugbar feature med meget få ulemper.

Men: ikke helt bagudkompatibel…try {

throw new DaughterOfFoo();

} catch (Foo e) {

try {

throw e;

// Pre-JDK 7 smides Foo,

// nu smides DaughterOfFoo

} catch (SonOfFoo e2) {

; // Kan denne kode nås?

}

}

Page 28: Project Coin features in Java 7

6) Diamonds (are a girls coders best

friend)

Vi skriver ofte ting som:Map<Integer, Map<String, String>> usersMaps = new HashMap<Integer, Map<String, String>>();

Aaargh!!!

Nu kan vi “bare” skrive:Map<Integer, Map<String, String>> usersMaps = new HashMap<>();

<> kaldes “Diamond” operatoren

Page 29: Project Coin features in Java 7

Diamond - fortsat

Laver rigtig “type inference”, ikke bare

streng-substitution

Note: Modsat af mange andre sprog

(f.eks. Scala og .Net)

andre sprog laver inferens på variablen

(venstre side): val a = new String(“asd”)

Java 7 laver inferens på værdi-siden (højre),

dvs. Vi specificerer variablens type, og

gætter typen på det objekt der tildeles.

Page 30: Project Coin features in Java 7

Diamond - detaljer

Det viste sig at være en relativt

kompleks ændring at indføre, med

mange non-trivielle designbeslutninger

Flere mulige inferens algoritmer blev

overvejet, 2 var “lige gode” (ordnede

hver sine 90%).

problemer med anonyme indre klasser:

Page 31: Project Coin features in Java 7

Diamond – Et eksempel på problem

Object o;

List<?> arg = ...;

o = new Box<>(arg);

Bliver til:

Object o;

List<?> arg = ...;

o = new Box<List<captureof?>>(arg);

OK, Men hvad så med:

o = new Box<List<captureof ?>>(arg){...};

Laves til en ny klasse:

o = new a$1(arg);

class a$1 extends Box<List<captureof ?>>{...}

Men denne klasses skal indeholde spec af sin superklassestype-descriptor som ikke kan udtrykkes I class-filen.

Derfor ikke lovligt i java 7!

public class Box<T> { private T value;

public Box(T value){ this.value = value;

}

T getValue() { return value;

}

}

Page 32: Project Coin features in Java 7

7) Safe Varargs

Problem idag (JDK < 7) med “unchecked” warnings ved kald af library metoder der tager varargs.

Skyldes at varargs er impl. som arrays, ogarrays ikke understøtter generics pga. covariant typehierarki (kort: String[] kanassignes til Object[] og resultere I runtime CCE hvis man hiver en forkert type ud)

Warnings kommer på call-site og derforsvære at “fjerne”

Page 33: Project Coin features in Java 7

Varargs - løsning

@SafeVarargs annotation

Men:

Erklærer kun at koden opfører sig “pænt”

Forhindrer egentlig ikke runtime CCE

Kan kun bruges på static og final metoder

da annotations ikke nedarves.

Fremtidig java-version vil forhåbentligt

få compile-time checks

Page 34: Project Coin features in Java 7

… mulige Coin forbedringer i JDK 8

Try-with-resources på “effectively final”

variable

Dvs. man ikke behøver at assigne til en ny

variabel i try(…)

Fjerne nogle begrænsninger på

Diamond

Måske @SafeVarargs på private

metoder?

Page 35: Project Coin features in Java 7

… der var dog mere i JDK 7

NIO.2 – New I/O version 2

Method handles

invokeDynamic (ny bytecode instruktion)

Forbedret concurrency

Forbedret Unicode

Diverse andre småting (f.eks. Objects.deepEquals helper)

Her må være flere gode idéer til fremtidige emner(kom frit frem)

… og så er der jo hele JDK 8 !