diff --git a/collections/BasicRecord.java b/collections/BasicRecord.java new file mode 100644 index 00000000..0fa0f251 --- /dev/null +++ b/collections/BasicRecord.java @@ -0,0 +1,29 @@ +// collections/BasicRecord.java +// (c)2021 MindView LLC: see Copyright.txt +// We make no guarantees that this code is fit for any purpose. +// Visit http://OnJava8.com for more book information. +// {NewFeature} Since JDK 16 +import java.util.*; + +record Employee(String name, int id) {} + +public class BasicRecord { + public static void main(String[] args) { + var bob = new Employee("Bob Dobbs", 11); + var dot = new Employee("Dorothy Gale", 9); + // bob.id = 12; // Error: + // id has private access in Employee + System.out.println(bob.name()); // Accessor + System.out.println(bob.id()); // Accessor + System.out.println(bob); // toString() + // Employee works as the key in a Map: + var map = Map.of(bob, "A", dot, "B"); + System.out.println(map); + } +} +/* Output: +Bob Dobbs +11 +Employee[name=Bob Dobbs, id=11] +{Employee[name=Dorothy Gale, id=9]=B, Employee[name=Bob Dobbs, id=11]=A} +*/ diff --git a/collections/CompactConstructor.java b/collections/CompactConstructor.java new file mode 100644 index 00000000..017dcbf9 --- /dev/null +++ b/collections/CompactConstructor.java @@ -0,0 +1,16 @@ +// collections/CompactConstructor.java +// (c)2021 MindView LLC: see Copyright.txt +// We make no guarantees that this code is fit for any purpose. +// Visit http://OnJava8.com for more book information. +// {NewFeature} Since JDK 16 + +record Point(int x, int y) { + void assertPositive(int val) { + if(val < 0) + throw new IllegalArgumentException("negative"); + } + Point { // Compact: No parameter list + assertPositive(x); + assertPositive(y); + } +} diff --git a/collections/ComposedRecord.java b/collections/ComposedRecord.java new file mode 100644 index 00000000..1e234b25 --- /dev/null +++ b/collections/ComposedRecord.java @@ -0,0 +1,10 @@ +// collections/ComposedRecord.java +// (c)2021 MindView LLC: see Copyright.txt +// We make no guarantees that this code is fit for any purpose. +// Visit http://OnJava8.com for more book information. +// {NewFeature} Since JDK 16 + +record Company(Employee[] e) {} + +// class Conglomerate extends Company {} +// error: cannot inherit from final Company diff --git a/collections/CopyRecord.java b/collections/CopyRecord.java new file mode 100644 index 00000000..7e2d9dd1 --- /dev/null +++ b/collections/CopyRecord.java @@ -0,0 +1,18 @@ +// collections/CopyRecord.java +// (c)2021 MindView LLC: see Copyright.txt +// We make no guarantees that this code is fit for any purpose. +// Visit http://OnJava8.com for more book information. +// {NewFeature} Since JDK 16 + +record R(int a, double b, char c) {} + +public class CopyRecord { + public static void main(String[] args) { + var r1 = new R(11, 2.2, 'z'); + var r2 = new R(r1.a(), r1.b(), r1.c()); + System.out.println(r1.equals(r2)); + } +} +/* Output: +true +*/ diff --git a/collections/FinalFields.java b/collections/FinalFields.java new file mode 100644 index 00000000..1cf0f4f4 --- /dev/null +++ b/collections/FinalFields.java @@ -0,0 +1,12 @@ +// collections/FinalFields.java +// (c)2021 MindView LLC: see Copyright.txt +// We make no guarantees that this code is fit for any purpose. +// Visit http://OnJava8.com for more book information. +// {NewFeature} Since JDK 16 +import java.util.*; + +record FinalFields(int i) { + int timesTen() { return i * 10; } + // void tryToChange() { i++; } // Error: + // cannot assign a value to final variable i +} diff --git a/collections/GenericTypeInference.java b/collections/GenericTypeInference.java new file mode 100644 index 00000000..83264de2 --- /dev/null +++ b/collections/GenericTypeInference.java @@ -0,0 +1,20 @@ +// collections/GenericTypeInference.java +// (c)2021 MindView LLC: see Copyright.txt +// We make no guarantees that this code is fit for any purpose. +// Visit http://OnJava8.com for more book information. +// {NewFeature} Since JDK 11 +import java.util.*; + +public class GenericTypeInference { + void old() { + ArrayList apples = new ArrayList<>(); + } + void modern() { + var apples = new ArrayList(); + } + void pitFall() { + var apples = new ArrayList<>(); + apples.add(new Apple()); + apples.get(0); // Comes back as plain Object + } +} diff --git a/collections/ImplementingRecord.java b/collections/ImplementingRecord.java new file mode 100644 index 00000000..4a453f77 --- /dev/null +++ b/collections/ImplementingRecord.java @@ -0,0 +1,14 @@ +// collections/ImplementingRecord.java +// (c)2021 MindView LLC: see Copyright.txt +// We make no guarantees that this code is fit for any purpose. +// Visit http://OnJava8.com for more book information. +// {NewFeature} Since JDK 16 + +interface Star { + double brightness(); + double density(); +} + +record RedDwarf(double brightness) implements Star { + @Override public double density() { return 100.0; } +} diff --git a/collections/NestedLocalRecords.java b/collections/NestedLocalRecords.java new file mode 100644 index 00000000..5ae37566 --- /dev/null +++ b/collections/NestedLocalRecords.java @@ -0,0 +1,12 @@ +// collections/NestedLocalRecords.java +// (c)2021 MindView LLC: see Copyright.txt +// We make no guarantees that this code is fit for any purpose. +// Visit http://OnJava8.com for more book information. +// {NewFeature} Since JDK 16 + +public class NestedLocalRecords { + record Nested(String s) {} + void method() { + record Local(String s) {} + } +} diff --git a/collections/NormalConstructor.java b/collections/NormalConstructor.java new file mode 100644 index 00000000..da926b64 --- /dev/null +++ b/collections/NormalConstructor.java @@ -0,0 +1,11 @@ +// collections/NormalConstructor.java +// (c)2021 MindView LLC: see Copyright.txt +// We make no guarantees that this code is fit for any purpose. +// Visit http://OnJava8.com for more book information. +// {NewFeature} Since JDK 16 + +record Value(int x) { + Value(int x) { // With the parameter list + this.x = x; // Must explicitly initialize + } +} diff --git a/collections/PlusTen.java b/collections/PlusTen.java new file mode 100644 index 00000000..a52bfed5 --- /dev/null +++ b/collections/PlusTen.java @@ -0,0 +1,20 @@ +// collections/PlusTen.java +// (c)2021 MindView LLC: see Copyright.txt +// We make no guarantees that this code is fit for any purpose. +// Visit http://OnJava8.com for more book information. +// {NewFeature} Since JDK 16 + +record PlusTen(int x) { + PlusTen { + x += 10; + } + // Adjustment to field can only happen in + // the constructor. Still not legal: + // void mutate() { x += 10; } + public static void main(String[] args) { + System.out.println(new PlusTen(10)); + } +} +/* Output: +PlusTen[x=20] +*/ diff --git a/concurrent/PSP2.txt b/concurrent/PSP2.txt index 7cdafb83..d41bfa1f 100644 --- a/concurrent/PSP2.txt +++ b/concurrent/PSP2.txt @@ -1,5 +1,5 @@ 0: main -1: main +1: ForkJoinPool.commonPool-worker-2 2: main 3: main 4: main @@ -107,22 +107,150 @@ 106: main 107: main 108: main -109: main -110: main -111: main -112: main -113: main -114: main -115: main -116: main -117: main -118: main -119: main -120: main -121: main -122: main -123: main -124: main -125: main -126: main -127: main +108: ForkJoinPool.commonPool-worker-2 +109: ForkJoinPool.commonPool-worker-2 +110: ForkJoinPool.commonPool-worker-2 +111: ForkJoinPool.commonPool-worker-2 +112: ForkJoinPool.commonPool-worker-2 +113: ForkJoinPool.commonPool-worker-2 +114: ForkJoinPool.commonPool-worker-2 +115: ForkJoinPool.commonPool-worker-2 +116: ForkJoinPool.commonPool-worker-2 +117: ForkJoinPool.commonPool-worker-2 +118: ForkJoinPool.commonPool-worker-2 +119: ForkJoinPool.commonPool-worker-2 +120: ForkJoinPool.commonPool-worker-2 +121: ForkJoinPool.commonPool-worker-2 +122: ForkJoinPool.commonPool-worker-2 +123: ForkJoinPool.commonPool-worker-2 +124: ForkJoinPool.commonPool-worker-2 +125: ForkJoinPool.commonPool-worker-2 +126: ForkJoinPool.commonPool-worker-2 +127: ForkJoinPool.commonPool-worker-2 +128: ForkJoinPool.commonPool-worker-2 +129: ForkJoinPool.commonPool-worker-2 +130: ForkJoinPool.commonPool-worker-2 +131: ForkJoinPool.commonPool-worker-2 +132: ForkJoinPool.commonPool-worker-2 +133: ForkJoinPool.commonPool-worker-2 +134: ForkJoinPool.commonPool-worker-2 +135: ForkJoinPool.commonPool-worker-2 +136: ForkJoinPool.commonPool-worker-2 +137: ForkJoinPool.commonPool-worker-2 +138: ForkJoinPool.commonPool-worker-2 +139: ForkJoinPool.commonPool-worker-2 +140: ForkJoinPool.commonPool-worker-2 +141: ForkJoinPool.commonPool-worker-2 +142: ForkJoinPool.commonPool-worker-2 +143: ForkJoinPool.commonPool-worker-2 +144: ForkJoinPool.commonPool-worker-2 +145: ForkJoinPool.commonPool-worker-2 +146: ForkJoinPool.commonPool-worker-2 +147: ForkJoinPool.commonPool-worker-2 +148: ForkJoinPool.commonPool-worker-2 +149: ForkJoinPool.commonPool-worker-2 +150: ForkJoinPool.commonPool-worker-2 +151: ForkJoinPool.commonPool-worker-2 +152: ForkJoinPool.commonPool-worker-2 +153: ForkJoinPool.commonPool-worker-2 +154: ForkJoinPool.commonPool-worker-2 +155: ForkJoinPool.commonPool-worker-2 +156: ForkJoinPool.commonPool-worker-2 +157: ForkJoinPool.commonPool-worker-2 +158: ForkJoinPool.commonPool-worker-2 +159: ForkJoinPool.commonPool-worker-2 +160: ForkJoinPool.commonPool-worker-2 +161: ForkJoinPool.commonPool-worker-2 +162: ForkJoinPool.commonPool-worker-2 +163: ForkJoinPool.commonPool-worker-2 +164: ForkJoinPool.commonPool-worker-2 +165: ForkJoinPool.commonPool-worker-2 +166: ForkJoinPool.commonPool-worker-2 +167: ForkJoinPool.commonPool-worker-2 +168: ForkJoinPool.commonPool-worker-2 +169: ForkJoinPool.commonPool-worker-2 +170: ForkJoinPool.commonPool-worker-2 +171: ForkJoinPool.commonPool-worker-2 +172: ForkJoinPool.commonPool-worker-2 +173: ForkJoinPool.commonPool-worker-2 +174: ForkJoinPool.commonPool-worker-2 +175: ForkJoinPool.commonPool-worker-2 +176: ForkJoinPool.commonPool-worker-2 +177: ForkJoinPool.commonPool-worker-2 +178: ForkJoinPool.commonPool-worker-2 +179: ForkJoinPool.commonPool-worker-2 +180: ForkJoinPool.commonPool-worker-2 +181: ForkJoinPool.commonPool-worker-2 +182: ForkJoinPool.commonPool-worker-2 +183: ForkJoinPool.commonPool-worker-2 +184: ForkJoinPool.commonPool-worker-2 +185: ForkJoinPool.commonPool-worker-2 +186: ForkJoinPool.commonPool-worker-2 +187: ForkJoinPool.commonPool-worker-2 +188: ForkJoinPool.commonPool-worker-2 +189: ForkJoinPool.commonPool-worker-2 +190: ForkJoinPool.commonPool-worker-2 +191: ForkJoinPool.commonPool-worker-2 +192: ForkJoinPool.commonPool-worker-2 +193: ForkJoinPool.commonPool-worker-2 +194: ForkJoinPool.commonPool-worker-2 +195: ForkJoinPool.commonPool-worker-2 +196: ForkJoinPool.commonPool-worker-2 +197: ForkJoinPool.commonPool-worker-2 +198: ForkJoinPool.commonPool-worker-2 +199: ForkJoinPool.commonPool-worker-2 +200: ForkJoinPool.commonPool-worker-2 +201: ForkJoinPool.commonPool-worker-2 +202: ForkJoinPool.commonPool-worker-2 +203: ForkJoinPool.commonPool-worker-2 +204: ForkJoinPool.commonPool-worker-2 +205: ForkJoinPool.commonPool-worker-2 +206: ForkJoinPool.commonPool-worker-2 +207: ForkJoinPool.commonPool-worker-2 +208: ForkJoinPool.commonPool-worker-2 +209: ForkJoinPool.commonPool-worker-2 +210: ForkJoinPool.commonPool-worker-2 +211: ForkJoinPool.commonPool-worker-2 +212: ForkJoinPool.commonPool-worker-2 +213: ForkJoinPool.commonPool-worker-2 +214: ForkJoinPool.commonPool-worker-2 +215: ForkJoinPool.commonPool-worker-2 +216: ForkJoinPool.commonPool-worker-2 +217: ForkJoinPool.commonPool-worker-2 +218: ForkJoinPool.commonPool-worker-2 +219: ForkJoinPool.commonPool-worker-2 +220: ForkJoinPool.commonPool-worker-2 +221: ForkJoinPool.commonPool-worker-2 +222: ForkJoinPool.commonPool-worker-2 +223: ForkJoinPool.commonPool-worker-2 +224: ForkJoinPool.commonPool-worker-2 +225: ForkJoinPool.commonPool-worker-2 +226: ForkJoinPool.commonPool-worker-2 +227: ForkJoinPool.commonPool-worker-2 +228: ForkJoinPool.commonPool-worker-2 +229: ForkJoinPool.commonPool-worker-2 +230: ForkJoinPool.commonPool-worker-2 +231: ForkJoinPool.commonPool-worker-2 +232: ForkJoinPool.commonPool-worker-2 +233: ForkJoinPool.commonPool-worker-2 +234: ForkJoinPool.commonPool-worker-2 +236: main +237: main +238: main +239: main +240: main +241: main +242: main +243: main +244: main +245: main +246: main +247: main +248: main +249: main +250: main +251: main +252: main +253: main +254: main +255: main diff --git a/exceptions/BetterNullPointerReports.java b/exceptions/BetterNullPointerReports.java new file mode 100644 index 00000000..e5ef495b --- /dev/null +++ b/exceptions/BetterNullPointerReports.java @@ -0,0 +1,43 @@ +// exceptions/BetterNullPointerReports.java +// (c)2021 MindView LLC: see Copyright.txt +// We make no guarantees that this code is fit for any purpose. +// Visit http://OnJava8.com for more book information. +// {NewFeature} Since JDK 15 + +class A { + String s; + A(String s) { + this.s = s; + } +} + +class B { + A a; + B(A a) { + this.a = a; + } +} + +class C { + B b; + C(B b) { + this.b = b; + } +} + +public class BetterNullPointerReports { + public static void main(String[] args) { + C[] ca = { + new C(new B(new A(null))), + new C(new B(null)), + new C(null), + }; + for(C c: ca) { + try { + System.out.println(c.b.a.s); + } catch(NullPointerException npe) { + System.out.println(npe); + } + } + } +} diff --git a/exceptions/EffectivelyFinalTWR.java b/exceptions/EffectivelyFinalTWR.java new file mode 100644 index 00000000..7ebeaf0d --- /dev/null +++ b/exceptions/EffectivelyFinalTWR.java @@ -0,0 +1,48 @@ +// exceptions/EffectivelyFinalTWR.java +// (c)2021 MindView LLC: see Copyright.txt +// We make no guarantees that this code is fit for any purpose. +// Visit http://OnJava8.com for more book information. +// {NewFeature} Since JDK 9 +import java.io.*; + +public class EffectivelyFinalTWR { + static void old() { + try ( + InputStream r1 = new FileInputStream( + new File("TryWithResources.java")); + InputStream r2 = new FileInputStream( + new File("EffectivelyFinalTWR.java")); + ) { + r1.read(); + r2.read(); + } catch(IOException e) { + // Handle exceptions + } + } + static void jdk9() throws IOException { + final InputStream r1 = new FileInputStream( + new File("TryWithResources.java")); + // Effectively final: + InputStream r2 = new FileInputStream( + new File("EffectivelyFinalTWR.java")); + try (r1; r2) { + r1.read(); + r2.read(); + } + // r1 and r2 are still in scope. Accessing + // either one throws an exception: + r1.read(); + r2.read(); + } + public static void main(String[] args) { + old(); + try { + jdk9(); + } catch(IOException e) { + System.out.println(e); + } + } +} +/* Output: +java.io.IOException: Stream Closed +*/ diff --git a/exceptions/MessyExceptions.java b/exceptions/MessyExceptions.java index 46d63337..1441abd0 100644 --- a/exceptions/MessyExceptions.java +++ b/exceptions/MessyExceptions.java @@ -13,7 +13,7 @@ public class MessyExceptions { int contents = in.read(); // Process contents } catch(IOException e) { - // Handle the error + // Handle errors } finally { if(in != null) { try { diff --git a/exceptions/TryWithResources.java b/exceptions/TryWithResources.java index 0ded5615..a82d261c 100644 --- a/exceptions/TryWithResources.java +++ b/exceptions/TryWithResources.java @@ -13,7 +13,7 @@ public class TryWithResources { int contents = in.read(); // Process contents } catch(IOException e) { - // Handle the error + // Handle errors } } } diff --git a/housekeeping/ArrayInit.java b/housekeeping/ArrayInit.java index f515f13b..fc5ffb1e 100644 --- a/housekeeping/ArrayInit.java +++ b/housekeeping/ArrayInit.java @@ -7,14 +7,8 @@ import java.util.*; public class ArrayInit { public static void main(String[] args) { - Integer[] a = { - 1, 2, - 3, // Autoboxing - }; - Integer[] b = new Integer[]{ - 1, 2, - 3, // Autoboxing - }; + Integer[] a = { 1, 2, 3, }; + Integer[] b = new Integer[]{ 1, 2, 3, }; System.out.println(Arrays.toString(a)); System.out.println(Arrays.toString(b)); } diff --git a/housekeeping/ForTypeInference.java b/housekeeping/ForTypeInference.java new file mode 100644 index 00000000..844ff10e --- /dev/null +++ b/housekeeping/ForTypeInference.java @@ -0,0 +1,19 @@ +// housekeeping/ForTypeInference.java +// (c)2021 MindView LLC: see Copyright.txt +// We make no guarantees that this code is fit for any purpose. +// Visit http://OnJava8.com for more book information. +// {NewFeature} Since JDK 11 + +public class ForTypeInference { + public static void main(String[] args) { + for(var s : Spiciness.values()) + System.out.println(s); + } +} +/* Ouput: +NOT +MILD +MEDIUM +HOT +FLAMING +*/ diff --git a/housekeeping/NewVarArgs.java b/housekeeping/NewVarArgs.java index 640dda15..6ee8d4a7 100644 --- a/housekeeping/NewVarArgs.java +++ b/housekeeping/NewVarArgs.java @@ -2,7 +2,7 @@ // (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. // Visit http://OnJava8.com for more book information. -// Using array syntax to create variable argument lists +// Using ellipses to define a variable argument list public class NewVarArgs { static void printArray(Object... args) { diff --git a/housekeeping/PrimitiveOverloading.java b/housekeeping/PrimitiveOverloading.java index 9618eddf..6a120b0c 100644 --- a/housekeeping/PrimitiveOverloading.java +++ b/housekeeping/PrimitiveOverloading.java @@ -101,20 +101,12 @@ public class PrimitiveOverloading { } } /* Output: -5: f1(int) f2(int) f3(int) f4(int) f5(long) f6(float) -f7(double) -char: f1(char) f2(int) f3(int) f4(int) f5(long) -f6(float) f7(double) -byte: f1(byte) f2(byte) f3(short) f4(int) f5(long) -f6(float) f7(double) -short: f1(short) f2(short) f3(short) f4(int) f5(long) -f6(float) f7(double) -int: f1(int) f2(int) f3(int) f4(int) f5(long) f6(float) -f7(double) -long: f1(long) f2(long) f3(long) f4(long) f5(long) -f6(float) f7(double) -float: f1(float) f2(float) f3(float) f4(float) -f5(float) f6(float) f7(double) -double: f1(double) f2(double) f3(double) f4(double) -f5(double) f6(double) f7(double) +5: f1(int) f2(int) f3(int) f4(int) f5(long) f6(float) f7(double) +char: f1(char) f2(int) f3(int) f4(int) f5(long) f6(float) f7(double) +byte: f1(byte) f2(byte) f3(short) f4(int) f5(long) f6(float) f7(double) +short: f1(short) f2(short) f3(short) f4(int) f5(long) f6(float) f7(double) +int: f1(int) f2(int) f3(int) f4(int) f5(long) f6(float) f7(double) +long: f1(long) f2(long) f3(long) f4(long) f5(long) f6(float) f7(double) +float: f1(float) f2(float) f3(float) f4(float) f5(float) f6(float) f7(double) +double: f1(double) f2(double) f3(double) f4(double) f5(double) f6(double) f7(double) */ diff --git a/housekeeping/TypeInference.java b/housekeeping/TypeInference.java new file mode 100644 index 00000000..9f06fc2d --- /dev/null +++ b/housekeeping/TypeInference.java @@ -0,0 +1,36 @@ +// housekeeping/TypeInference.java +// (c)2021 MindView LLC: see Copyright.txt +// We make no guarantees that this code is fit for any purpose. +// Visit http://OnJava8.com for more book information. +// {NewFeature} Since JDK 11 + +class Plumbus {} + +public class TypeInference { + void method() { + // Explicit type: + String hello1 = "Hello"; + // Type inference: + var hello = "Hello!"; + // Works for user-defined types: + Plumbus pb1 = new Plumbus(); + var pb2 = new Plumbus(); + } + // Also works for static methods: + static void staticMethod() { + var hello = "Hello!"; + var pb2 = new Plumbus(); + } +} + +class NoInference { + String field1 = "Field initialization"; + // var field2 = "Can't do this"; + // void method() { + // var noInitializer; // No inference data + // var aNull = null; // No inference data + // } + // var inferReturnType() { + // return "Can't infer return type"; + // } +} diff --git a/housekeeping/VarArgs.java b/housekeeping/VarArgs.java index 25f44d86..0899b861 100644 --- a/housekeeping/VarArgs.java +++ b/housekeeping/VarArgs.java @@ -13,8 +13,7 @@ public class VarArgs { System.out.println(); } public static void main(String[] args) { - printArray(new Object[]{ - 47, (float) 3.14, 11.11}); + printArray(new Object[]{47, (float) 3.14, 11.11}); printArray(new Object[]{"one", "two", "three" }); printArray(new Object[]{new A(), new A(), new A()}); } diff --git a/interfaces/CheckedDowncast.java b/interfaces/CheckedDowncast.java new file mode 100644 index 00000000..90689585 --- /dev/null +++ b/interfaces/CheckedDowncast.java @@ -0,0 +1,19 @@ +// interfaces/CheckedDowncast.java +// (c)2021 MindView LLC: see Copyright.txt +// We make no guarantees that this code is fit for any purpose. +// Visit http://OnJava8.com for more book information. +// {NewFeature} Since JDK 17 + +sealed interface II permits JJ {} +final class JJ implements II {} +class Something {} + +public class CheckedDowncast { + public void f() { + II i = new JJ(); + JJ j = (JJ)i; + // Something s = (Something)i; + // error: incompatible types: II cannot + // be converted to Something + } +} diff --git a/interfaces/MICollision.java b/interfaces/MICollision.java index a37d947a..ab1c8090 100644 --- a/interfaces/MICollision.java +++ b/interfaces/MICollision.java @@ -37,7 +37,7 @@ interface Sam2 { } } -// This works because the argument lists are distinct: +// Works because the argument lists are distinct: class Sam implements Sam1, Sam2 {} interface Max1 { diff --git a/interfaces/Machine.java b/interfaces/Machine.java deleted file mode 100644 index 72e3fcbc..00000000 --- a/interfaces/Machine.java +++ /dev/null @@ -1,36 +0,0 @@ -// interfaces/Machine.java -// (c)2021 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://OnJava8.com for more book information. -import java.util.*; -import onjava.Operations; - -class Bing implements Operations { - @Override public void execute() { - Operations.show("Bing"); - } -} - -class Crack implements Operations { - @Override public void execute() { - Operations.show("Crack"); - } -} - -class Twist implements Operations { - @Override public void execute() { - Operations.show("Twist"); - } -} - -public class Machine { - public static void main(String[] args) { - Operations.runOps( - new Bing(), new Crack(), new Twist()); - } -} -/* Output: -Bing -Crack -Twist -*/ diff --git a/interfaces/MetalWork.java b/interfaces/MetalWork.java new file mode 100644 index 00000000..071b13ac --- /dev/null +++ b/interfaces/MetalWork.java @@ -0,0 +1,39 @@ +// interfaces/MetalWork.java +// (c)2021 MindView LLC: see Copyright.txt +// We make no guarantees that this code is fit for any purpose. +// Visit http://OnJava8.com for more book information. +import onjava.Operation; + +class Heat implements Operation { + @Override public void execute() { + Operation.show("Heat"); + } +} + +public class MetalWork { + public static void main(String[] args) { + // Must be defined in a static context + // to access a method reference: + Operation twist = new Operation() { + public void execute() { + Operation.show("Twist"); + } + }; + Operation.runOps( + new Heat(), // [1] + new Operation() { // [2] + public void execute() { + Operation.show("Hammer"); + } + }, + twist::execute, // [3] + () -> Operation.show("Anneal") // [4] + ); + } +} +/* Output: +Heat +Hammer +Twist +Anneal +*/ diff --git a/interfaces/NonSealed.java b/interfaces/NonSealed.java new file mode 100644 index 00000000..8bc4b8fa --- /dev/null +++ b/interfaces/NonSealed.java @@ -0,0 +1,11 @@ +// interfaces/NonSealed.java +// (c)2021 MindView LLC: see Copyright.txt +// We make no guarantees that this code is fit for any purpose. +// Visit http://OnJava8.com for more book information. +// {NewFeature} Since JDK 17 + +sealed class Super permits Sub1, Sub2 {} +final class Sub1 extends Super {} +non-sealed class Sub2 extends Super {} +class Any1 extends Sub2 {} +class Any2 extends Sub2 {} diff --git a/interfaces/PermittedSubclasses.java b/interfaces/PermittedSubclasses.java new file mode 100644 index 00000000..73afd6eb --- /dev/null +++ b/interfaces/PermittedSubclasses.java @@ -0,0 +1,22 @@ +// interfaces/PermittedSubclasses.java +// (c)2021 MindView LLC: see Copyright.txt +// We make no guarantees that this code is fit for any purpose. +// Visit http://OnJava8.com for more book information. +// {NewFeature} Since JDK 17 + +sealed class Color permits Red, Green, Blue {} +final class Red extends Color {} +final class Green extends Color {} +final class Blue extends Color {} + +public class PermittedSubclasses { + public static void main(String[] args) { + for(var p: Color.class.getPermittedSubclasses()) + System.out.println(p.getSimpleName()); + } +} +/* Output: +Red +Green +Blue +*/ diff --git a/interfaces/PrivateInterfaceMethods.java b/interfaces/PrivateInterfaceMethods.java new file mode 100644 index 00000000..ebad9bd5 --- /dev/null +++ b/interfaces/PrivateInterfaceMethods.java @@ -0,0 +1,54 @@ +// interfaces/PrivateInterfaceMethods.java +// (c)2021 MindView LLC: see Copyright.txt +// We make no guarantees that this code is fit for any purpose. +// Visit http://OnJava8.com for more book information. +// {NewFeature} Since JDK 9 + +interface Old { + default void fd() { + System.out.println("Old::fd()"); + } + static void fs() { + System.out.println("Old::fs()"); + } + default void f() { + fd(); + } + static void g() { + fs(); + } +} + +class ImplOld implements Old {} + +interface JDK9 { + private void fd() { // Automatically default + System.out.println("JDK9::fd()"); + } + private static void fs() { + System.out.println("JDK9::fs()"); + } + default void f() { + fd(); + } + static void g() { + fs(); + } +} + +class ImplJDK9 implements JDK9 {} + +public class PrivateInterfaceMethods { + public static void main(String[] args) { + new ImplOld().f(); + Old.g(); + new ImplJDK9().f(); + JDK9.g(); + } +} +/* Output: +Old::fd() +Old::fs() +JDK9::fd() +JDK9::fs() +*/ diff --git a/interfaces/SameFile.java b/interfaces/SameFile.java new file mode 100644 index 00000000..e20e93ae --- /dev/null +++ b/interfaces/SameFile.java @@ -0,0 +1,9 @@ +// interfaces/SameFile.java +// (c)2021 MindView LLC: see Copyright.txt +// We make no guarantees that this code is fit for any purpose. +// Visit http://OnJava8.com for more book information. +// {NewFeature} Since JDK 17 + +sealed class Shape {} +final class Circle extends Shape {} +final class Triangle extends Shape {} diff --git a/interfaces/Sealed.java b/interfaces/Sealed.java new file mode 100644 index 00000000..5124606c --- /dev/null +++ b/interfaces/Sealed.java @@ -0,0 +1,12 @@ +// interfaces/Sealed.java +// (c)2021 MindView LLC: see Copyright.txt +// We make no guarantees that this code is fit for any purpose. +// Visit http://OnJava8.com for more book information. +// {NewFeature} Since JDK 17 + +sealed class Base permits D1, D2 {} + +final class D1 extends Base {} +final class D2 extends Base {} +// Illegal: +// final class D3 extends Base {} diff --git a/interfaces/SealedCat.java b/interfaces/SealedCat.java new file mode 100644 index 00000000..0356ccac --- /dev/null +++ b/interfaces/SealedCat.java @@ -0,0 +1,6 @@ +// interfaces/SealedCat.java +// (c)2021 MindView LLC: see Copyright.txt +// We make no guarantees that this code is fit for any purpose. +// Visit http://OnJava8.com for more book information. +// {NewFeature} Since JDK 17 +final class Cat extends Pet {} diff --git a/interfaces/SealedDog.java b/interfaces/SealedDog.java new file mode 100644 index 00000000..f0441afd --- /dev/null +++ b/interfaces/SealedDog.java @@ -0,0 +1,6 @@ +// interfaces/SealedDog.java +// (c)2021 MindView LLC: see Copyright.txt +// We make no guarantees that this code is fit for any purpose. +// Visit http://OnJava8.com for more book information. +// {NewFeature} Since JDK 17 +final class Dog extends Pet {} diff --git a/interfaces/SealedInterface.java b/interfaces/SealedInterface.java new file mode 100644 index 00000000..315517bb --- /dev/null +++ b/interfaces/SealedInterface.java @@ -0,0 +1,12 @@ +// interfaces/SealedInterface.java +// (c)2021 MindView LLC: see Copyright.txt +// We make no guarantees that this code is fit for any purpose. +// Visit http://OnJava8.com for more book information. +// {NewFeature} Since JDK 17 + +sealed interface Ifc permits Imp1, Imp2 {} +final class Imp1 implements Ifc {} +final class Imp2 implements Ifc {} + +sealed abstract class AC permits X {} +final class X extends AC {} diff --git a/interfaces/SealedPets.java b/interfaces/SealedPets.java new file mode 100644 index 00000000..79ab9e5b --- /dev/null +++ b/interfaces/SealedPets.java @@ -0,0 +1,6 @@ +// interfaces/SealedPets.java +// (c)2021 MindView LLC: see Copyright.txt +// We make no guarantees that this code is fit for any purpose. +// Visit http://OnJava8.com for more book information. +// {NewFeature} Since JDK 17 +sealed class Pet permits Dog, Cat {} diff --git a/interfaces/SealedRecords.java b/interfaces/SealedRecords.java new file mode 100644 index 00000000..c1fd7b7e --- /dev/null +++ b/interfaces/SealedRecords.java @@ -0,0 +1,12 @@ +// interfaces/SealedRecords.java +// (c)2021 MindView LLC: see Copyright.txt +// We make no guarantees that this code is fit for any purpose. +// Visit http://OnJava8.com for more book information. +// {NewFeature} Since JDK 17 + +sealed interface Employee + permits CLevel, Programmer {} +record CLevel(String type) + implements Employee {} +record Programmer(String experience) + implements Employee {} diff --git a/interfaces/SealedSubclasses.java b/interfaces/SealedSubclasses.java new file mode 100644 index 00000000..68b83af3 --- /dev/null +++ b/interfaces/SealedSubclasses.java @@ -0,0 +1,10 @@ +// interfaces/SealedSubclasses.java +// (c)2021 MindView LLC: see Copyright.txt +// We make no guarantees that this code is fit for any purpose. +// Visit http://OnJava8.com for more book information. +// {NewFeature} Since JDK 17 + +sealed class Bottom permits Level1 {} +sealed class Level1 extends Bottom permits Level2 {} +sealed class Level2 extends Level1 permits Level3 {} +final class Level3 extends Level2 {} diff --git a/onjava/Operations.java b/onjava/Operation.java similarity index 66% rename from onjava/Operations.java rename to onjava/Operation.java index 0f935c36..f540bb76 100644 --- a/onjava/Operations.java +++ b/onjava/Operation.java @@ -1,14 +1,13 @@ -// onjava/Operations.java +// onjava/Operation.java // (c)2021 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. // Visit http://OnJava8.com for more book information. package onjava; -import java.util.*; -public interface Operations { +public interface Operation { void execute(); - static void runOps(Operations... ops) { - for(Operations op : ops) + static void runOps(Operation... ops) { + for(Operation op : ops) op.execute(); } static void show(String msg) { diff --git a/operators/Equivalence.java b/operators/Equivalence.java index 25f7f3e7..dafc4952 100644 --- a/operators/Equivalence.java +++ b/operators/Equivalence.java @@ -14,11 +14,11 @@ public class Equivalence { Integer i1 = value; // [1] Integer i2 = value; show("Automatic", i1, i2); - // Old way, deprecated in Java 9 and on: + // Old way, deprecated since Java 9: Integer r1 = new Integer(value); // [2] Integer r2 = new Integer(value); show("new Integer()", r1, r2); - // Preferred in Java 9 and on: + // Preferred since Java 9: Integer v1 = Integer.valueOf(value); // [3] Integer v2 = Integer.valueOf(value); show("Integer.valueOf()", v1, v2); diff --git a/operators/Literals.java b/operators/Literals.java index 3f2eef05..67232c22 100644 --- a/operators/Literals.java +++ b/operators/Literals.java @@ -17,7 +17,7 @@ public class Literals { char c = 0xffff; // max char hex value System.out.println( "c: " + Integer.toBinaryString(c)); - byte b = 0x7f; // max byte hex value 10101111; + byte b = 0x7f; // max byte hex value 0111111; System.out.println( "b: " + Integer.toBinaryString(b)); short s = 0x7fff; // max short hex value diff --git a/operators/URShift.java b/operators/URShift.java index d1bcc4f0..7596408c 100644 --- a/operators/URShift.java +++ b/operators/URShift.java @@ -30,8 +30,7 @@ public class URShift { /* Output: 11111111111111111111111111111111 1111111111111111111111 -1111111111111111111111111111111111111111111111111111111 -111111111 +1111111111111111111111111111111111111111111111111111111111111111 111111111111111111111111111111111111111111111111111111 11111111111111111111111111111111 11111111111111111111111111111111 diff --git a/streams/Machine2.java b/streams/Machine2.java deleted file mode 100644 index e7b425ea..00000000 --- a/streams/Machine2.java +++ /dev/null @@ -1,23 +0,0 @@ -// streams/Machine2.java -// (c)2021 MindView LLC: see Copyright.txt -// We make no guarantees that this code is fit for any purpose. -// Visit http://OnJava8.com for more book information. -import java.util.*; -import onjava.Operations; - -public class Machine2 { - public static void main(String[] args) { - Arrays.stream(new Operations[] { - () -> Operations.show("Bing"), - () -> Operations.show("Crack"), - () -> Operations.show("Twist"), - () -> Operations.show("Pop") - }).forEach(Operations::execute); - } -} -/* Output: -Bing -Crack -Twist -Pop -*/ diff --git a/streams/MetalWork2.java b/streams/MetalWork2.java new file mode 100644 index 00000000..0bf74152 --- /dev/null +++ b/streams/MetalWork2.java @@ -0,0 +1,23 @@ +// streams/MetalWork2.java +// (c)2021 MindView LLC: see Copyright.txt +// We make no guarantees that this code is fit for any purpose. +// Visit http://OnJava8.com for more book information. +import java.util.*; +import onjava.Operation; + +public class MetalWork2 { + public static void main(String[] args) { + Arrays.stream(new Operation[] { + () -> Operation.show("Heat"), + () -> Operation.show("Hammer"), + () -> Operation.show("Twist"), + () -> Operation.show("Anneal") + }).forEach(Operation::execute); + } +} +/* Output: +Heat +Hammer +Twist +Anneal +*/ diff --git a/strings/DataPoint.java b/strings/DataPoint.java new file mode 100644 index 00000000..719e0959 --- /dev/null +++ b/strings/DataPoint.java @@ -0,0 +1,32 @@ +// strings/DataPoint.java +// (c)2021 MindView LLC: see Copyright.txt +// We make no guarantees that this code is fit for any purpose. +// Visit http://OnJava8.com for more book information. +// {NewFeature} Since JDK 15 + +public class DataPoint { + private String location; + private Double temperature; + public DataPoint(String loc, Double temp) { + location = loc; + temperature = temp; + } + @Override public String toString() { + return """ + Location: %s + Temperature: %.2f + """.formatted(location, temperature); + } + public static void main(String[] args) { + var hill = new DataPoint("Hill", 45.2); + var dale = new DataPoint("Dale", 65.2); + System.out.print(hill); + System.out.print(dale); + } +} +/* Output: +Location: Hill +Temperature: 45.20 +Location: Dale +Temperature: 65.20 +*/ diff --git a/strings/Indentation.java b/strings/Indentation.java new file mode 100644 index 00000000..71a88365 --- /dev/null +++ b/strings/Indentation.java @@ -0,0 +1,33 @@ +// strings/Indentation.java +// (c)2021 MindView LLC: see Copyright.txt +// We make no guarantees that this code is fit for any purpose. +// Visit http://OnJava8.com for more book information. +// {NewFeature} Since JDK 15 + +public class Indentation { + public static final String NONE = """ + XXX + YYY + """; // No indentation + public static final String TWO = """ + XXX + YYY + """; // Produces indent of 2 + public static final String EIGHT = """ + XXX + YYY + """; // Produces indent of 8 + public static void main(String[] args) { + System.out.print(NONE); + System.out.print(TWO); + System.out.print(EIGHT); + } +} +/* Output: +XXX +YYY + XXX + YYY + XXX + YYY +*/ diff --git a/strings/TextBlocks.java b/strings/TextBlocks.java new file mode 100644 index 00000000..0e634001 --- /dev/null +++ b/strings/TextBlocks.java @@ -0,0 +1,37 @@ +// strings/TextBlocks.java +// (c)2021 MindView LLC: see Copyright.txt +// We make no guarantees that this code is fit for any purpose. +// Visit http://OnJava8.com for more book information. +// {NewFeature} Since JDK 15 +// Poem: Antigonish by Hughes Mearns + +public class TextBlocks { + public static final String OLD = + "Yesterday, upon the stair,\n" + + "I met a man who wasn't there\n" + + "He wasn't there again today\n" + + "I wish, I wish he'd go away...\n" + + "\n" + + "When I came home last night at three\n" + + "The man was waiting there for me\n" + + "But when I looked around the hall\n" + + "I couldn't see him there at all!\n"; + + public static final String NEW = """ + Yesterday, upon the stair, + I met a man who wasn't there + He wasn't there again today + I wish, I wish he'd go away... + + When I came home last night at three + The man was waiting there for me + But when I looked around the hall + I couldn't see him there at all! + """; + public static void main(String[] args) { + System.out.println(OLD.equals(NEW)); + } +} +/* Output: +true +*/