Amberとは

Java言語を拡張するプロジェクトです
http://openjdk.java.net/projects/amber/

Amberのブランチ

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

  • datum データクラス
  • patterns パターンマッチ
  • switch 拡張switch
  • lambda-leftovers ラムダの微修正
  • enhanced-enums 拡張enum
  • lvti ローカル変数型推論

これが、JDK10、11、12...と半年ごとに五月雨式にリリースされていくことになると思います。結構恐怖ですね。

データクラス

データ保持用のクラスです。
JEPは今のところ見当たりません。
http://hg.openjdk.java.net/amber/amber/file/c6ca12231746/test/langtools/tools/javac/datum

recordとして定義します。

record Foo(int x, int y) {}

継承できるのはAbstract recordのみ

abstract record Sup(int x, int y) {}
record Bar(int x, int y, int z) extends Sup(x, y);

スーパーrecordに渡すのは同じ名前でないといけない

明示的にコンストラクタを定義する場合の値の設定はdefaultを使う

record Foo(int x, int y) {
  Foo(int x, int y) {
    default(x, y);
  }
}

ガードとして条件を指定できる

record Range1(int lo, int hi) where lo <= hi;
record Range2(int lo, int hi) where lo <= hi {};

パターンマッチング

パターンマッチングです。
http://openjdk.java.net/jeps/305

値 matches パターンで、値をマッチさせることができます。
パターンは、定数か変数定義です。変数定義の場合には、型が一致していた場合にtrueになりその変数に値が割り当てられます。

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

switchでもパターンマッチが使えます。

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

つまり、switchでdoubleやbooleanも使えるようになるということです。

switch (obj) {
  case 12 :   msg = "12だ"; break;
  case true : msg = "とぅるー"; break;
  case 3.14:  msg = "円周率では"; break;
}

JEP 305には含まれませんが、データクラスと組み合わせて構造の分解を行うことができるようになるということも目標です。

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

拡張switch

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

switchはステートメントでしたが、多くのswitchで同一の変数に値を割り当てたりすべてのcaseでreturnしたりといった使いかががされていたため、式としても使えるようになります。

つまり、こう。

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

breakで値を返すということもできます。

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

基本的な形はbreakで値を返すものです。

case LABEL: break expression;

そのシンタックスシュガーとしてラムダっぽく書けるということのようです。

case LABEL -> expression;

casenullも使えるようになります。

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

case nullがない場合には次のようなcaseが自動的に挿入されます。

case null: throw new NullPointerException();

また、caseに複数の値を指定できるようにもなります。

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

このようなcaseの拡張は、既存のswitchステートメントでも有効です。

ラムダの微修正

ラムダの微修正
http://openjdk.java.net/jeps/302

使わない変数に_を使えます。

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

あと、次のような場合、falseを返すのでPredicateになることは明確ですが、現状ではエラーになってます。これをちゃんと型推論できるようにしようというもの。

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

m(s -> false) //ambiguous

拡張enum

enumでgenericsを指定できるようにしようというものです。
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

ローカル変数型推論

ローカル変数の型推論を導入するものです。
http://openjdk.java.net/jeps/286

var x = 12;

JDK 10で導入されることが決まっています。

ラムダへのvar対応

ラムダの変数定義にもvarを明示的に書けるようにしようというものです。
http://openjdk.java.net/jeps/323

いままでこう書けていました。

(x, y) -> x + y

varで明示的に型推論であることを指定しようというものです。

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

混在はできません

(var x, y) -> x + y

JDK 11に入りそう。

Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account log in.