75
Java SE 7 Julien Ponge

Java 7 at SoftShake 2011

Embed Size (px)

Citation preview

Page 1: Java 7 at SoftShake 2011

Java SE 7Julien Ponge

Page 2: Java 7 at SoftShake 2011
Page 3: Java 7 at SoftShake 2011

Fork / Join

Project Coin

NIO.2

invokedynamic

(...)

Page 4: Java 7 at SoftShake 2011

Fork / Join

Page 5: Java 7 at SoftShake 2011

synchronized

wait()notify()< 5

java.lang.Threadjava.lang.Runnable

Page 6: Java 7 at SoftShake 2011

Thread thread = new Thread() { public void run() { System.out.println(">>> Hello!"); }}; thread.start();thread.join();

Page 7: Java 7 at SoftShake 2011

java.util.concurrent

executorsconcurrent queuesconcurrent collectionsatomic variablessynchronization patternsrich locks

5, 6

Page 8: Java 7 at SoftShake 2011

class Sum implements Callable<Long> { private final long from; private final long to; Sum(long from, long to) { this.from = from; this.to = to; } public Long call() { long acc = 0; for (long i = from; i <= to; i++) { acc = acc + i; } return acc; } }

Page 9: Java 7 at SoftShake 2011

ExecutorService executor = Executors.newFixedThreadPool(2);

List<Future<Long>> results = executor.invokeAll(asList( new Sum(0, 10), new Sum(100, 1000), new Sum(10000, 1000000)));

for (Future<Long> result : results) { System.out.println(result.get());}

Page 10: Java 7 at SoftShake 2011

Threads made easy

Concurrency made easier

Parallelism made easier

1.01.11.21.31.4

56

7

Page 11: Java 7 at SoftShake 2011

n1 n2 n3 n4 n5 n6 n8n7 n9 ... ... ......

sum1 sum2 sum3sum1 + sum2 sum3 + (...)

total sum

Sum of an array

Page 12: Java 7 at SoftShake 2011

How many occurrences of “java.util.List” in this filesystem tree?

Page 13: Java 7 at SoftShake 2011

Load into RAM (1 thread)

subfolders: List<Folder>documents: List<Document>

Folderlines: List<String>

Document

Divide & conquer (#cores threads)

Page 14: Java 7 at SoftShake 2011

SplitFork subtasksJoin subtasksCompose results

Thread managementMaximize parallelism

Work stealing

Your workForkJoinPool

Page 15: Java 7 at SoftShake 2011

Child ForkJoinTask

fork() fork()join() join()

Child ForkJoinTask

ForkJoinTask

RecursiveActionvs

RecursiveTask

Page 16: Java 7 at SoftShake 2011

Document wordcounting task

Document wordcounting task

Folder wordcounting task

Folder wordcounting task

Document wordcounting task

Document wordcounting task

3

n

2

51

10

16

fork()

join()

Page 17: Java 7 at SoftShake 2011

(F/J demo)

Page 18: Java 7 at SoftShake 2011

1"

2"

3"

4"

5"

6"

7"

2" 4" 6" 8" 10" 12"

Speedup&

#cores

Page 19: Java 7 at SoftShake 2011

No I/ONo synchronization / locks

Decompose in simple recursive tasksDo not decompose below a threshold

Take advantage of multicores with no pain

You have more F/J candidate algorithms than you think!

Page 20: Java 7 at SoftShake 2011

try-with-resources

Page 21: Java 7 at SoftShake 2011

private void writeSomeData() throws IOException { DataOutputStream out = new DataOutputStream(new FileOutputStream("data")); out.writeInt(666); out.writeUTF("Hello"); out.close();}

Page 22: Java 7 at SoftShake 2011

private void writeSomeData() throws IOException { DataOutputStream out = new DataOutputStream(new FileOutputStream("data")); out.writeInt(666); out.writeUTF("Hello"); out.close();}

what if...

Page 23: Java 7 at SoftShake 2011

private void writeSomeData() throws IOException { DataOutputStream out = null; try { out = new DataOutputStream(new FileOutputStream("data")); out.writeInt(666); out.writeUTF("Hello"); } finally { if (out != null) { out.close(); } } }

Page 24: Java 7 at SoftShake 2011

private void writeSomeData() throws IOException { DataOutputStream out = null; try { out = new DataOutputStream(new FileOutputStream("data")); out.writeInt(666); out.writeUTF("Hello"); } finally { if (out != null) { out.close(); } } }

...this is still far from correct!

Page 25: Java 7 at SoftShake 2011

try (

FileOutputStream out = new FileOutputStream("output"); FileInputStream in1 = new FileInputStream(“input1”); FileInputStream in2 = new FileInputStream(“input2”)

) {

// Do something useful with those 3 streams! // out, in1 and in2 will be closed in any case

out.write(in1.read()); out.write(in2.read());}

Page 26: Java 7 at SoftShake 2011

public class AutoClose implements AutoCloseable { @Override public void close() { System.out.println(">>> close()"); throw new RuntimeException("Exception in close()"); } public void work() throws MyException { System.out.println(">>> work()"); throw new MyException("Exception in work()"); }}

Page 27: Java 7 at SoftShake 2011

AutoClose autoClose = new AutoClose();try { autoClose.work();} finally { autoClose.close();}

Page 28: Java 7 at SoftShake 2011

AutoClose autoClose = new AutoClose();try { autoClose.work();} finally { autoClose.close();}

>>> work() >>> close() java.lang.RuntimeException: Exception in close()        at AutoClose.close(AutoClose.java:6)        at AutoClose.runWithMasking(AutoClose.java:19)        at AutoClose.main(AutoClose.java:52)

Page 29: Java 7 at SoftShake 2011

AutoClose autoClose = new AutoClose();try { autoClose.work();} finally { autoClose.close();}

>>> work() >>> close() java.lang.RuntimeException: Exception in close()        at AutoClose.close(AutoClose.java:6)        at AutoClose.runWithMasking(AutoClose.java:19)        at AutoClose.main(AutoClose.java:52)

MyException masked by RuntimeException

Page 30: Java 7 at SoftShake 2011

“Caused by” ≠ “Also happened”

Page 31: Java 7 at SoftShake 2011

AutoClose autoClose = new AutoClose();MyException myException = null;try { autoClose.work();} catch (MyException e) { myException = e; throw e;} finally { if (myException != null) { try { autoClose.close(); } catch (Throwable t) { myException.addSuppressed(t); } } else { autoClose.close(); }}

Page 32: Java 7 at SoftShake 2011

AutoClose autoClose = new AutoClose();MyException myException = null;try { autoClose.work();} catch (MyException e) { myException = e; throw e;} finally { if (myException != null) { try { autoClose.close(); } catch (Throwable t) { myException.addSuppressed(t); } } else { autoClose.close(); }}

Page 33: Java 7 at SoftShake 2011

AutoClose autoClose = new AutoClose();MyException myException = null;try { autoClose.work();} catch (MyException e) { myException = e; throw e;} finally { if (myException != null) { try { autoClose.close(); } catch (Throwable t) { myException.addSuppressed(t); } } else { autoClose.close(); }}

Page 34: Java 7 at SoftShake 2011

AutoClose autoClose = new AutoClose();MyException myException = null;try { autoClose.work();} catch (MyException e) { myException = e; throw e;} finally { if (myException != null) { try { autoClose.close(); } catch (Throwable t) { myException.addSuppressed(t); } } else { autoClose.close(); }}

Page 35: Java 7 at SoftShake 2011

AutoClose autoClose = new AutoClose();MyException myException = null;try { autoClose.work();} catch (MyException e) { myException = e; throw e;} finally { if (myException != null) { try { autoClose.close(); } catch (Throwable t) { myException.addSuppressed(t); } } else { autoClose.close(); }}

Page 36: Java 7 at SoftShake 2011

try (AutoClose autoClose = new AutoClose()) { autoClose.work();}

Page 37: Java 7 at SoftShake 2011

try (AutoClose autoClose = new AutoClose()) { autoClose.work();}

>>> work() >>> close() MyException: Exception in work()        at AutoClose.work(AutoClose.java:11)        at AutoClose.main(AutoClose.java:16)        Suppressed: java.lang.RuntimeException: Exception in close()               at AutoClose.close(AutoClose.java:6)               at AutoClose.main(AutoClose.java:17)

Page 38: Java 7 at SoftShake 2011

public void compress(String input, String output) throws IOException { try( FileInputStream fin = new FileInputStream(input); FileOutputStream fout = new FileOutputStream(output); GZIPOutputStream out = new GZIPOutputStream(fout) ) { byte[] buffer = new byte[4096]; int nread = 0; while ((nread = fin.read(buffer)) != -1) { out.write(buffer, 0, nread); } }}

Page 39: Java 7 at SoftShake 2011

public void compress(String paramString1, String paramString2)         throws IOException {     FileInputStream localFileInputStream = new FileInputStream(paramString1);    Object localObject1 = null;     try {         FileOutputStream localFileOutputStream = new FileOutputStream(paramString2);        Object localObject2 = null;         try {             GZIPOutputStream localGZIPOutputStream = new GZIPOutputStream(localFileOutputStream);            Object localObject3 = null;             try {                 byte[] arrayOfByte = new byte[4096];                 int i = 0;                 while ((i = localFileInputStream.read(arrayOfByte)) != -1) {                     localGZIPOutputStream.write(arrayOfByte, 0, i);                 }             } catch (Throwable localThrowable6) {                 localObject3 = localThrowable6;                 throw localThrowable6;             } finally {                 if (localGZIPOutputStream != null) {                     if (localObject3 != null) {                         try {                             localGZIPOutputStream.close();                         } catch (Throwable localThrowable7) {                             localObject3.addSuppressed(localThrowable7);                         }                     } else {                         localGZIPOutputStream.close();                     }                 }             }         } catch (Throwable localThrowable4) {             localObject2 = localThrowable4;             throw localThrowable4;         } finally {             if (localFileOutputStream != null) {                 if (localObject2 != null) {                     try {                         localFileOutputStream.close();                     } catch (Throwable localThrowable8) {                         localObject2.addSuppressed(localThrowable8);                     }                 } else {                     localFileOutputStream.close();                 }             }         }     } catch (Throwable localThrowable2) {         localObject1 = localThrowable2;         throw localThrowable2;     } finally {         if (localFileInputStream != null) {             if (localObject1 != null) {                 try {                     localFileInputStream.close();                 } catch (Throwable localThrowable9) {                     localObject1.addSuppressed(localThrowable9);                 }             } else {                 localFileInputStream.close();             }         }     } }

public void compress(String input, String output) throws IOException { try( FileInputStream fin = new FileInputStream(input); FileOutputStream fout = new FileOutputStream(output); GZIPOutputStream out = new GZIPOutputStream(fout) ) { byte[] buffer = new byte[4096]; int nread = 0; while ((nread = fin.read(buffer)) != -1) { out.write(buffer, 0, nread); } }}

Page 40: Java 7 at SoftShake 2011

Not just syntactic sugarClutter-free, correct code

close(): - be more specific than java.lang.Exception - no exception if it can’t fail - no exception that shall not be suppressed (e.g., java.lang.InterruptedException)

Page 41: Java 7 at SoftShake 2011

Diamond <>

Page 42: Java 7 at SoftShake 2011

List<String> strings = new LinkedList<Integer>();

Map<String, List<String>> contacts = new HashMap<Integer, String>();

Page 43: Java 7 at SoftShake 2011

List<String> strings = new LinkedList<String>();strings.add("hello");strings.add("world");

Map<String, List<String>> contacts = new HashMap<String, List<String>>();contacts.put("Julien", new LinkedList<String>());contacts.get("Julien").addAll(asList("Foo", "Bar", "Baz"));

Page 44: Java 7 at SoftShake 2011

List<String> strings = new LinkedList<>();strings.add("hello");strings.add("world");

Map<String, List<String>> contacts = new HashMap<>();contacts.put("Julien", new LinkedList<String>());contacts.get("Julien").addAll(asList("Foo", "Bar", "Baz"));

Page 45: Java 7 at SoftShake 2011

Map<String, String> map = new HashMap<String, String>() { { put("foo", "bar"); put("bar", "baz"); }};

Page 46: Java 7 at SoftShake 2011

Map<String, String> map = new HashMap<>() { { put("foo", "bar"); put("bar", "baz"); }};

Page 47: Java 7 at SoftShake 2011

Map<String, String> map = new HashMap<>() { { put("foo", "bar"); put("bar", "baz"); }};

Diamond.java:43: error: cannot infer type arguments for HashMap; Map<String, String> map = new HashMap<>() { ^ reason: cannot use '<>' with anonymous inner classes1 error

Page 48: Java 7 at SoftShake 2011

class SomeClass<T extends Serializable & CharSequence> { }

Non-denotable type

Page 49: Java 7 at SoftShake 2011

class SomeClass<T extends Serializable & CharSequence> { }

Non-denotable type

SomeClass<?> foo = new SomeClass<String>();SomeClass<?> fooInner = new SomeClass<String>() { };

SomeClass<?> bar = new SomeClass<>();

SomeClass<?> bar = new SomeClass<>() { };

Page 50: Java 7 at SoftShake 2011

class SomeClass<T extends Serializable & CharSequence> { }

Non-denotable type

SomeClass<?> foo = new SomeClass<String>();SomeClass<?> fooInner = new SomeClass<String>() { };

SomeClass<?> bar = new SomeClass<>();

SomeClass<?> bar = new SomeClass<>() { };

No denotable typeto generate a class

Page 51: Java 7 at SoftShake 2011

Less ceremony when using generics

No diamond with inner classes

Page 52: Java 7 at SoftShake 2011

Simplified varargs

Page 53: Java 7 at SoftShake 2011

private static <T> void doSomethingBad(List<T> list, T... values) { values[0] = list.get(0);}

public static void main(String[] args) { List list = Arrays.asList("foo", "bar", "baz"); doSomethingBad(list, 1, 2, 3);}

Page 54: Java 7 at SoftShake 2011

private static <T> void doSomethingBad(List<T> list, T... values) { values[0] = list.get(0);}

public static void main(String[] args) { List list = Arrays.asList("foo", "bar", "baz"); doSomethingBad(list, 1, 2, 3);}

Heap Pollution: List = List<String>

This yields warnings + crash:

Page 55: Java 7 at SoftShake 2011

private static <T> void doSomethingGood(List<T> list, T... values) { for (T value : values) { list.add(value); }}

Page 56: Java 7 at SoftShake 2011

private static <T> void doSomethingGood(List<T> list, T... values) { for (T value : values) { list.add(value); }}

$ javac Good.java Note: Good.java uses unchecked or unsafe operations.Note: Recompile with -Xlint:unchecked for details.

Page 57: Java 7 at SoftShake 2011

@SuppressWarnings({“unchecked”,“varargs”})

public static void main(String[] args) { List<String> list = new LinkedList<>(); doSomethingGood(list, "hi", "there", "!");}

$ javac Good.java $

Page 58: Java 7 at SoftShake 2011

@SafeVarargsprivate static <T> void doSomethingGood(List<T> list, T... values) { for (T value : values) { list.add(value); }}

static, final methods, constructors

Page 59: Java 7 at SoftShake 2011

Mark your code as safe for varargs

You can’t cheat with @SafeVarags

Remove @SuppressWarnings in client code and pay attention to real warnings

Page 60: Java 7 at SoftShake 2011

Multi-catch & more precise rethrow

Page 61: Java 7 at SoftShake 2011

Class<?> stringClass = Class.forName("java.lang.String"); Object instance = stringClass.newInstance(); Method toStringMethod = stringClass.getMethod("toString"); System.out.println(toStringMethod.invoke(instance));

Page 62: Java 7 at SoftShake 2011

try { Class<?> stringClass = Class.forName("java.lang.String"); Object instance = stringClass.newInstance(); Method toStringMethod = stringClass.getMethod("toString"); System.out.println(toStringMethod.invoke(instance));} catch (ClassNotFoundException e) { e.printStackTrace();} catch (InstantiationException e) { e.printStackTrace();} catch (IllegalAccessException e) { e.printStackTrace();} catch (NoSuchMethodException e) { e.printStackTrace();} catch (InvocationTargetException e) { e.printStackTrace();}

Page 63: Java 7 at SoftShake 2011

try { Class<?> stringClass = Class.forName("java.lang.String"); Object instance = stringClass.newInstance(); Method toStringMethod = stringClass.getMethod("toString"); System.out.println(toStringMethod.invoke(instance));} catch (Throwable t) { t.printStackTrace();}

Page 64: Java 7 at SoftShake 2011

try { Class<?> stringClass = Class.forName("java.lang.String"); Object instance = stringClass.newInstance(); Method toStringMethod = stringClass.getMethod("toString"); System.out.println(toStringMethod.invoke(instance));} catch (Throwable t) { t.printStackTrace();}

How about SecurityException?

Page 65: Java 7 at SoftShake 2011

try { Class<?> stringClass = Class.forName("java.lang.String"); Object instance = stringClass.newInstance(); Method toStringMethod = stringClass.getMethod("toString"); System.out.println(toStringMethod.invoke(instance));} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | NoSuchMethodException | InvocationTargetException e) { e.printStackTrace();}

Union of alternatives

Page 66: Java 7 at SoftShake 2011

catch (SomeException e)

Now implicitly final unless assigned...

Page 67: Java 7 at SoftShake 2011

static class SomeRootException extends Exception { }static class SomeChildException extends SomeRootException { }static class SomeOtherChildException extends SomeRootException { }

public static void main(String... args) throws Throwable {try { throw new SomeChildException();} catch (SomeRootException firstException) { try { throw firstException; } catch (SomeOtherChildException secondException) { System.out.println("I got you!"); }}

Page 68: Java 7 at SoftShake 2011

static class SomeRootException extends Exception { }static class SomeChildException extends SomeRootException { }static class SomeOtherChildException extends SomeRootException { }

public static void main(String... args) throws Throwable {try { throw new SomeChildException();} catch (SomeRootException firstException) { try { throw firstException; } catch (SomeOtherChildException secondException) { System.out.println("I got you!"); }}

$ javac Imprecise.java Imprecise.java:13: error: exception SomeOtherChildException is never thrown in body of corresponding try statement } catch (SomeOtherChildException secondException) { ^1 error

Page 69: Java 7 at SoftShake 2011

Less clutterBe preciseDo not capture unintended exceptions

Better exception flow analysis

Page 70: Java 7 at SoftShake 2011

Minor additions

Page 71: Java 7 at SoftShake 2011

// 123 in decimal, octal, hexadecimal and binarybyte decimal = 123;byte octal = 0_173;byte hexadecimal = 0x7b;byte binary = 0b0111_1011;

// Other valuesdouble doubleValue = 1.111_222_444F;long longValue = 1_234_567_898L;long longHexa = 0x1234_3b3b_0123_cdefL;

Page 72: Java 7 at SoftShake 2011

public static boolean isTrue(String str) { switch(str.trim().toUpperCase()) { case "OK": case "YES": case "TRUE": return true;

case "KO": case "NO": case "FALSE": return false;

default: throw new IllegalArgumentException("Not a valid true/false string."); } }

Page 73: Java 7 at SoftShake 2011

public static boolean isTrue(String s) { String str = s.trim().toUpperCase(); int jump = -1; switch(str.hashCode()) { case 2404: if (str.equals("KO")) { jump = 3; } break;(...) switch(jump) {(...) case 3: case 4: case 5: return false; default: throw new IllegalArgumentException( "Not a valid true/false string."); }}

Bucket

Real code

Page 74: Java 7 at SoftShake 2011

Fork and Join: Java Can Excel at Painless Parallel Programming Too!

Better Resource Management withJava SE 7: Beyond Syntactic Sugar

Oracle Technology Network

http://goo.gl/tostz

http://goo.gl/7ybgr

(more soon...)

Page 75: Java 7 at SoftShake 2011

Julien Ponge

@jponge

http://gplus.to/jponge

http://julien.ponge.info/

[email protected]