Java syntax changes being considered by Amber

What is Amber

A project to extend the Java language http://openjdk.java.net/projects/amber/

Amber branch

http://hg.openjdk.java.net/amber/amber/branches

I think that this will be released in the May rain ceremony every six months with JDK 14, 15, 16 ... It's pretty scary.

Records[preview in JDK14] This is a class for holding data. JEP is here as a Preview in 14. JEP 359: Records (Preview) The flow of preview 2 in Java 15 and formalization in Java 16.

~~ JEP is not found so far. ~~ ~~ Click here for JEP draft ~~ ~~JEP draft: Records and Sealed Types~~

http://cr.openjdk.java.net/~briangoetz/amber/datum.html http://hg.openjdk.java.net/amber/amber/file/15a61b5af8f5/test/langtools/tools/javac/datum

Define it as record.

record Foo(int x, int y) {}

No other class can inherit.

record record name(Status) {Definition}

This would be a class like this:

class Foo extends Record{
  //State defined as private final
  private final int x;
  private final int y;
  //No additional instance fields can be defined

  //A constructor that sets the state to the field is defined
  public Foo(int x, int y) {
    this.x = x;
    this.y = y;
  }

  //A method with the same name as the state is defined
  public int x() {
    return x;
  }
  public int y() {
    return y;
  }

  //A hashCode that reflects the state is defined
  public int hashCode() { ... }
  //Equals to compare states are defined
  public boolean equals() { ... }
  //A toString that displays the status is defined
  public String toString() { ... }
}

Constructors can be defined for state checking and normalization.

record Range(int lo, int hi) {
  public Range {
    if (lo > hi) throw IllegalArgumentException();
    //Fields that were not set will be set later
  }
}

Improvements in Preview 2 are suggested here. https://mail.openjdk.java.net/pipermail/amber-spec-experts/2020-January/001913.html

-- java.util.Record is a class, but Valhalla's inline class can only inherit interface, so should this be an interface? --Visibility to required members (Is it strange that the members of private record are public?) --Currently, records cannot be nested in the inner class, which is not static, but I want to support it.

sealed type

A sealed type that limits inheritance is also being promoted. JEP 360: Sealed Types (Preview) Sealed type specifications are also decided as a set with ~~ record. ~~ ~~JEP draft: Records and Sealed Types~~ It seems to be in preview with JDK15.

You can limit inheritance. For pattern matching

sealed interface Node 
  permits A, B, C {}

Node is implemented in the A, B, and C classes specified in permits. You can omit permits if they are in the same compilation unit. Interfaces and abstract classes that inherit from the sealed type are sealed types. The non-abstract class that implements and inherits the sealed type is final.

sealed interface Expr {};

record AddExpr(Expr a, Expr b) implements Expr {}
record SubExpr(Expr a, Expr b) implements Expr {}
record MulExpr(Expr a, Expr b) implements Expr {}
record DivExpr(Expr a, Expr b) implements Expr {}

It is also interesting to include the hyphen-separated keyword non-sealed.

Pattern matching [preview in JDK 14]

It is pattern matching. First of all, pattern matching using instance of will be included in 14 as a preview. http://openjdk.java.net/jeps/305

You can match the values with the value instanceof pattern. The pattern is a constant or variable definition. In the case of a variable definition, if the types match, it becomes true and a value is assigned to that variable.

if (x instanceof Integer i) {
    // can use i here
}

It will be 15 or later, but pattern matching can also be used with switch. JEP draft: Pattern matching for switch (Preview)

String formatted;
switch (obj) {
    case Integer i: formatted = String.format("int %d", i); break;
    case Byte b:    formatted = String.format("byte %d", b); break;
    case Long l:    formatted = String.format("long %d", l); break;
    case Double d:  formatted = String.format("double %f", d); break;
    case String s:  formatted = String.format("String %s", s); break
    default:        formatted = obj.toString();
}

It's not JEP yet, but the goal is to be able to perform structural decomposition in combination with data classes.

record Point(int x, int y) {}

int getLen(Point p) {
  return switch (p) {
    case Point(0, int y) -> y;
    case Point(int x, 0) -> x;
    case Point(int x, int y) -> (int)sqrt(x * x + y * y);
  }
}

Then you may be able to use double and boolean with switch.

switch (obj) {
  case 12 :   msg = "12"; break;
  case true : msg = "Turu"; break;
  case 3.14:  msg = "In pi"; break;
}

Extended switch [standard in JDK 14, preview in JDK 12, 13]

You can now use the previously statement switch as an expression. It seems that it will be introduced as a preview in Java 12, a specification change in Java 13, and an official function in Java 14. https://openjdk.java.net/jeps/361

Preview JEP https://openjdk.java.net/jeps/325 https://openjdk.java.net/jeps/354

switch was a statement, but since many switches used it to assign values to the same variable or return in all cases, it can also be used as an expression so that it can be written efficiently. I will.

In other words, like this.

int numLetters = switch (day) {
    case MONDAY, FRIDAY, SUNDAY -> 6;
    case TUESDAY -> 7;
    case THURSDAY, SATURDAY -> 8;
    case WEDNESDAY -> 9;
};

You can also return a value with yield.

int result = switch (s) {
    case "Foo":
        yield 1;
    case "Bar":
        yield 2;
    default:
        System.out.println("Neither Foo nor Bar, hmmm...");
        yield 3;
}

The basic form is to return a value with yield.

case LABEL: yield expression;

It seems that you can write like lambda as that syntax sugar.

case LABEL -> expression;

It also allows you to specify multiple values for case.

switch (day) {
    case MONDAY, FRIDAY, SUNDAY: 
        numLetters = 6;
        break;
    ...
};

Such case extensions are also valid for existing switch statements.

I should have been able to use null for case, but it seems that it is out of JEP325.

String formatted = switch (s) {
    case null -> "(null)";
    case "" -> "(empty)";
    default -> s;
}

If there is no case null, the following case is automatically inserted.

case null: throw new NullPointerException();

Extension of string literals [preview in JDK 13,14]

http://openjdk.java.net/jeps/368

You can define a character string that includes line breaks. Enclose in " "" . It is included as a Preview in JDK13. http://openjdk.java.net/jeps/355

In JDK14, there are some specification changes such as escaping line breaks. It will be standard in JDK15.

Initially I was planning to enter JDK 12 as Raw String Literals, but it was rejected. ~~http://openjdk.java.net/jeps/326~~

// same as "You can write\ntwo line string.\n"
var str = """
  You can write
  two line string.
  """;

The start " "" cannot be followed by a string, and the indentation is based on the "" " or the shallowest part of the internal string.

var str = """
..You can write
..two line string.
  """;
var str = """
..  You can write
..  two line string.
  """;

You can also escape line breaks.

var str = """
  You can write \
  two line string, \
  but this is single.
  """;

This will be " You can write two line string, but this is single. ".

Spaces at the end of the line are removed. So, if you need a space at the end of the line, put \ s to indicate that you need a space.

var str = """
  test\s
  test \s
  """;

This will be " test_ \ ntest__ \ n ". (In Qiita, even if you put multiple spaces, it will be one space)

It doesn't matter, but Qiita```I feel that there will be a lot of people in trouble because the backticks cannot be surrounded by backticks like this. 2018/5/At 8 point, it is rendered as follows. Screenshot 2018-05-08 4.38.25.png

#Lambda tweaks Lambda tweaks http://openjdk.java.net/jeps/302

For variables you don't use_Can be used.

BiFunction<Integer, String, String> biss = (i, _) -> String.valueOf(i);

Also, in the following casesfalseBecause it returnsPredicateIt is clear that it will be, but at present it is an error. The idea is to be able to type infer this properly.

m(Predicate<String> ps) { ... }
m(Function<String, String> fss) { ... }

m(s -> false) //ambiguous

#Extended enum The idea is to allow generics to be specified in enums. http://openjdk.java.net/jeps/301

enum Argument<X> { // declares generic enum
   STRING<String>(String.class), 
   INTEGER<Integer>(Integer.class), ... ;

   Class<X> clazz;

   Argument(Class<X> clazz) { this.clazz = clazz; }

   Class<X> getClazz() { return clazz; }
}

Class<String> cs = Argument.STRING.getClazz(); //uses sharper typing of enum constant

#Simplified method definition

http://openjdk.java.net/jeps/8209434

In the method definition->To be able to use

int twice(int x) -> x * x;

Method reference=so

int min(int x, int y) = Integer::min;

Transfers such as overload and override can be written neatly.

#Local method

2019/11/As of 16, there is no JEP etc., but if you look at the branch of the amber repository, it seems that you are doing an extension that allows you to define methods in methods.

It allows you to define methods within methods as follows.

int norm(int x, int y) {
  int square(int n) {
    return n * n;
  }
  return square(x) + square(y);
}

Combined with the simplification of the method definition, you should be able to write:

int norm(int x, int y) {
  int square(int n) -> n * n;
  return square(x) + square(y);
}

#Local variable type inference[standard in JDK10] It introduces type inference for local variables. http://openjdk.java.net/jeps/286

var x = 12;

Introduced in JDK 10.

#Var support for lambda[standard in JDK11] Also in the variable definition of lambdavarIs intended to be able to be written explicitly. http://openjdk.java.net/jeps/323

I used to write like this.

(x, y) -> x + y

varIs an attempt to explicitly specify that it is type inference.

(var x, var y) -> x + y

Cannot be mixed

(var x, y) -> x + y

I'm in JDK 11.

#Other than syntax It seems that a constructor version of indy is being developed under the name condy. ->It was Constant Dynamic. http://openjdk.java.net/jeps/309

I'm in JDK 11.

Recommended Posts

Java syntax changes being considered by Amber
Java control syntax
Java control syntax
Changes in Java 11
Changes from Java 8 to Java 11
[Java] Control syntax notes
[For beginners] About the JavaScript syntax explained by Java Gold