Änderungen der Java-Syntax werden von Amber berücksichtigt

Was ist Amber?

Ein Projekt zur Erweiterung der Java-Sprache http://openjdk.java.net/projects/amber/

Bernsteins Zweig

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

Ich denke, dies wird in der Regenzeremonie im Mai alle sechs Monate mit JDK14, 15, 16 ... veröffentlicht. Es ist ziemlich beängstigend.

Records[preview in JDK14] Dies ist eine Klasse zum Speichern von Daten. JEP ist hier als Vorschau in 14. JEP 359: Records (Preview) Der Ablauf von Vorschau 2 in Java 15 und Formalisierung in Java 16.

~~ JEP wurde bisher nicht gefunden. ~~ ~~ Klicken Sie hier für den JEP-Entwurf ~~ ~~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

Definieren Sie es als Datensatz.

record Foo(int x, int y) {}

Keine andere Klasse kann erben.

record Name des Datensatzes(Status) {Definition}

Dies wäre eine Klasse wie diese:

class Foo extends Record{
  //Staat als privates Finale definiert
  private final int x;
  private final int y;
  //Es können keine zusätzlichen Instanzfelder definiert werden

  //Ein Konstruktor, der den Status auf das Feld setzt, wird definiert
  public Foo(int x, int y) {
    this.x = x;
    this.y = y;
  }

  //Eine Methode mit demselben Namen wie der Status wird definiert
  public int x() {
    return x;
  }
  public int y() {
    return y;
  }

  //Ein Hashcode, der den Status widerspiegelt, wird definiert
  public int hashCode() { ... }
  //Gleich zum Vergleichen von Zuständen werden definiert
  public boolean equals() { ... }
  //Ein toString, der den Status anzeigt, ist definiert
  public String toString() { ... }
}

Sie können einen Konstruktor für die Statusprüfung und Normalisierung definieren.

record Range(int lo, int hi) {
  public Range {
    if (lo > hi) throw IllegalArgumentException();
    //Felder, die nicht festgelegt wurden, werden später festgelegt
  }
}

Verbesserungen in Vorschau 2 werden hier vorgeschlagen. https://mail.openjdk.java.net/pipermail/amber-spec-experts/2020-January/001913.html

--java.util.Record ist eine Klasse, aber die Inline-Klasse von Valhalla kann nur die Schnittstelle erben. Sollte dies also eine Schnittstelle sein?

versiegelter Typ

Ein versiegelter Typ, der die Vererbung begrenzt, wird ebenfalls gefördert. JEP 360: Sealed Types (Preview) Versiegelte Typspezifikationen werden auch als Satz mit ~~ Datensatz festgelegt. ~~ ~~JEP draft: Records and Sealed Types~~ Es scheint in der Vorschau mit JDK15 zu sein.

Sie können die Vererbung einschränken. Für den Mustervergleich

sealed interface Node 
  permits A, B, C {}

Der Knoten ist in den in "Genehmigungen" angegebenen Klassen A, B und C implementiert. Sie können "Genehmigungen" weglassen, wenn sie sich in derselben Kompilierungseinheit befinden. Schnittstellen und abstrakte Klassen, die vom versiegelten Typ erben, sind versiegelte Typen. Die nicht abstrakte Klasse, die den versiegelten Typ implementiert und erbt, ist endgültig.

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 {}

Es ist auch interessant, das durch Bindestriche getrennte Schlüsselwort "nicht versiegelt" aufzunehmen.

Mustervergleich [Vorschau in JDK 14]

Es ist Mustervergleich. Zunächst wird eine Musterübereinstimmung mit der Instanz von in 14 als Vorschau aufgenommen. http://openjdk.java.net/jeps/305

Sie können die Werte mit der "Wertinstanz des Musters" abgleichen. Das Muster ist eine konstante oder variable Definition. Wenn bei einer Variablendefinition die Typen übereinstimmen, wird sie wahr und dieser Variablen wird ein Wert zugewiesen.

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

Es wird 15 oder später sein, aber der Mustervergleich kann auch mit dem Schalter verwendet werden. 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();
}

Es ist noch kein JEP, aber das Ziel ist es, eine strukturelle Zerlegung in Kombination mit Datenklassen durchführen zu können.

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);
  }
}

Dann können Sie möglicherweise double und boolean für den Switch verwenden.

switch (obj) {
  case 12 :   msg = "12"; break;
  case true : msg = "Turu"; break;
  case 3.14:  msg = "Im Umfangsverhältnis"; break;
}

Erweiterter Schalter [Standard in JDK 14, Vorschau in JDK 12, 13]

Sie können jetzt die vorherige Anweisung "switch" als Ausdruck verwenden. Es scheint, dass es als Vorschau in Java 12, als Spezifikationsänderung in Java 13 und als offizielle Funktion in Java 14 eingeführt wird. https://openjdk.java.net/jeps/361

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

Switch war eine Anweisung, aber da viele Switches sie verwendeten, um derselben Variablen Werte zuzuweisen oder in allen Fällen zurückzugeben, kann sie auch als Ausdruck verwendet werden, damit sie effizient geschrieben werden kann. Ich werde.

Mit anderen Worten, so.

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

Sie können auch einen Wert mit "Yield" zurückgeben.

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

Die Grundform besteht darin, einen Wert mit "Ausbeute" zurückzugeben.

case LABEL: yield expression;

Es scheint, dass Sie wie Lambda als diese Syntax Zucker schreiben können.

case LABEL -> expression;

Außerdem können Sie mehrere Werte für "case" angeben.

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

Diese "case" -Erweiterungen gelten auch für vorhandene "switch" -Anweisungen.

Ich hätte in der Lage sein sollen, "null" für "case" zu verwenden, aber es scheint, dass es nicht in JEP325 ist.

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

Wenn es keinen "Fall null" gibt, wird automatisch der folgende "Fall" eingefügt.

case null: throw new NullPointerException();

Erweiterung des String-Literal [Vorschau in JDK 13,14]

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

Sie können eine Zeichenfolge definieren, die Zeilenumbrüche enthält. Fügen Sie in "" "" "ein. Es ist als Vorschau in JDK13 enthalten. http://openjdk.java.net/jeps/355

In JDK14 gibt es einige Spezifikationsänderungen, z. B. Zeilenumbrüche. Es wird Standard in JDK15 sein.

Ursprünglich geplant, JDK 12 als Raw String Literals einzugeben, wurde es abgelehnt. ~~http://openjdk.java.net/jeps/326~~

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

Dem Start "" "kann kein String folgen, und der Einzug basiert auf dem" "" "oder dem flachsten Teil des internen Strings.

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

Sie können auch Zeilenumbrüchen entkommen.

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

Dies ist "Sie können eine zweizeilige Zeichenfolge schreiben, dies ist jedoch eine einzelne."

Das Leerzeichen am Ende der Zeile wird entfernt. Wenn Sie also am Ende der Zeile ein Leerzeichen benötigen, geben Sie "\ s" ein, um anzugeben, dass Sie ein Leerzeichen benötigen.

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

Dies ist "test_ \ ntest__ \ n". (Selbst wenn Sie in Qiita mehrere Leerzeichen einfügen, ist dies ein Leerzeichen.)

Es ist egal, aber Qiita```Ich habe das Gefühl, dass es viele Menschen in Schwierigkeiten geben wird, weil die hinteren Anführungszeichen nicht von den hinteren Anführungszeichen umgeben sein können. 2018/5/Ab 8 wird es wie folgt gerendert. Screenshot 2018-05-08 4.38.25.png

#Lambda Minor Fix Lambda Minor Fix http://openjdk.java.net/jeps/302

Für nicht verwendete Variablen_Kann verwendet werden.

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

Auch in den folgenden FällenfalseWeil es zurückkehrtPredicateEs ist klar, dass es so sein wird, aber derzeit ist es ein Fehler. Die Idee ist, dies richtig eingeben zu können.

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

m(s -> false) //ambiguous

#Erweiterte Aufzählung Die Idee ist, enum die Angabe von Generika zu ermöglichen. 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

#Vereinfachte Methodendefinition

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

In der Methodendefinition->In der Lage sein zu verwenden

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

Die Methodenreferenz lautet=damit

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

Übertragungen wie Überladen und Überschreiben können sauber geschrieben werden.

#Lokale Methode

2019/11/Ab 16 gibt es kein JEP usw., aber wenn Sie sich den Zweig des Amber-Repositorys ansehen, gibt es ein Zeichen dafür, dass Sie eine Erweiterung ausführen, mit der Sie Methoden innerhalb von Methoden definieren können.

Sie können methodeninterne Methoden wie folgt definieren:

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

In Kombination mit der Vereinfachung der Methodendefinition sollten Sie schreiben können:

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

#Inferenz des lokalen Variablentyps[standard in JDK10] Es wird eine Typinferenz für lokale Variablen eingeführt. http://openjdk.java.net/jeps/286

var x = 12;

Eingeführt in JDK 10.

#Var Unterstützung für Lambda[standard in JDK11] Auch in der Variablendefinition von LambdavarSoll explizit geschrieben werden können. http://openjdk.java.net/jeps/323

Ich habe so geschrieben.

(x, y) -> x + y

varIst ein Versuch, explizit anzugeben, dass es sich um eine Typinferenz handelt.

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

Kann nicht gemischt werden

(var x, y) -> x + y

JDK 11 eingegeben.

#Andere als Syntax Es scheint, dass eine Konstruktorversion von Indy unter dem Namen Condy entwickelt wird. ->Es war konstant dynamisch. http://openjdk.java.net/jeps/309

JDK 11 eingegeben.

Recommended Posts

Änderungen der Java-Syntax werden von Amber berücksichtigt
Java-Steuerungssyntax
Java-Steuerungssyntax
Änderungen in Java 11
Änderungen von Java 8 zu Java 11
[Java] Hinweis zur Steuerungssyntax
[Für Anfänger] Über die von Java Gold erklärte JavaScript-Syntax