今さらJava7〜10までの新機能(主に言語仕様)をおさらい

しばらくJava6の開発ばかりやっていたので、java7〜10までの概要は把握しているもののここらでおさらいをしておきます。

Java7

Binary Literals

0bまたは0Bから始まるバイナリリテラルが使えるようになるようです。

// An 8-bit 'byte' value:
byte aByte = (byte)0b00100001;

// A 16-bit 'short' value:
short aShort = (short)0b1010000101000101;

// Some 32-bit 'int' values:
int anInt1 = 0b10100001010001011010000101000101;
int anInt2 = 0b101;
int anInt3 = 0B101; // The B can be upper or lower case.

// A 64-bit 'long' value. Note the "L" suffix:
long aLong = 0b1010000101000101101000010100010110100001010001011010000101000101L;

Strings in switch Statements

Switch文にStringが使えるようになります。これは結構ありがたいです。

public String getTypeOfDayWithSwitchStatement(String dayOfWeekArg) {
     String typeOfDay;
     switch (dayOfWeekArg) {
         case "Monday":
             typeOfDay = "Start of work week";
             break;
         case "Tuesday":
         case "Wednesday":
         case "Thursday":
             typeOfDay = "Midweek";
             break;
         case "Friday":
             typeOfDay = "End of work week";
             break;
         case "Saturday":
         case "Sunday":
             typeOfDay = "Weekend";
             break;
         default:
             throw new IllegalArgumentException("Invalid day of the week: " + dayOfWeekArg);
     }
     return typeOfDay;
}

The try-with-resources Statement

リソースを自動でクローズしてくれる機能です。Java6の開発をやっている上で一番のストレスでした。Java7ならクローズ漏れなんて障害は出ないのに・・・などなど。

static String readFirstLineFromFile(String path) throws IOException {
  try (BufferedReader br = new BufferedReader(new FileReader(path))) {
    return br.readLine();
  }
}

Catching Multiple Exception Types and Rethrowing Exceptions with Improved Type Checking

これも地味にありがたいですね。Exceptionをまとめて記述できます。エラー処理は共通処理が多いので、メソッド化してそれを呼ぶようにそれぞれコーディングする必要がありましたが、そういったこともなくなりますね。

Java7以前だと

catch (IOException ex) {
     logger.log(ex);
     throw ex;
catch (SQLException ex) {
     logger.log(ex);
     throw ex;
}

Java7からは

catch (IOException|SQLException ex) {
    logger.log(ex);
    throw ex;
}

スッキリ。

Underscores in Numeric Literals

読みやすさの向上?

long creditCardNumber = 1234_5678_9012_3456L;
long socialSecurityNumber = 999_99_9999L;
float pi = 	3.14_15F;
long hexBytes = 0xFF_EC_DE_5E;
long hexWords = 0xCAFE_BABE;
long maxLong = 0x7fff_ffff_ffff_ffffL;
byte nybbles = 0b0010_0101;
long bytes = 0b11010010_01101001_10010100_10010010;

Type Inference for Generic Instance Creation

newする際に型を省略できるようになります。IDEが自動でやってくれていたのであまり効率は変わらない気もします。

Java7以前

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

Java7

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

Java8

参考サイト

Qiita

# はじめに ベースはこの辺の情報です。 http://www.techempower.com/blog/2013/03/26/everything-about-java-8/ http://www.infoq.com/jp/news...[…]

インターフェースの仕様変更

デフォルトメソッドが定義できるように

    default void forEach(Consumer<? super T> action) {
        Objects.requireNonNull(action);
        for (T t : this) {
            action.accept(t);
        }
    }

staticメソッドが定義できるように

ラムダ式

Java8の目玉機能ですね。慣れるまでは違和感ありそうですが、冗長な記述をしなくて良くなるので早く慣れていきたいです。Eclipseが自動でやってくれそうですが。。

Java7まで

Collections.sort(students, new Comparator<Student>() {
    @Override
    public int compare(Student o1, Student o2) {
        return Integer.compare(o1.getHeight(), o2.getHeight());
    }
});

Java8からはだいぶスッキリ。

Collections.sort(students, (o1, o2) -> Integer.compare(o1.getHeight(), o2.getHeight()));

Stream

集合体を表すインターフェースで、集合に対する処理を簡潔に記述する事が可能になったようです。Kotlin等、後続の言語にはほぼほぼ最初からあるんですよね。
コレクション操作がかなり楽になります。

Java7

int sum = 0;
for (int i = 1; i < 101; i++) {
    sum += i;
}

Java8

int sum = IntStream.range(1, 101).sum();

日付API

joda-timeのようなAPIのようです。日付の操作がえらい楽になります。

参考サイト

Qiita

Javaで日付/時間を扱うには従来はDate/Calendar/DateFormat等のクラスを使っていたが(以下、旧API)、Java8からはjava.timeパッケージに新しくAPIが追加された(以下、新API)。 しかし新AP...[…]

日付から各値を取得(月は1始まりになった!)

LocalDateTime d = LocalDateTime.now();
System.out.println(d.getYear());
System.out.println(d.getMonth());
System.out.println(d.getDayOfMonth());
System.out.println(d.getHour());
System.out.println(d.getMinute());
System.out.println(d.getSecond());
System.out.println(d.getNano());
System.out.println(d.get(ChronoField.YEAR));

日付の操作

LocalDateTime d = LocalDateTime.of(2015, 12, 15, 23, 30, 59);
System.out.println(d.plusDays(20));       //2016-01-04T23:30:59
System.out.println(d.minusDays(20));      //2015-11-25T23:30:59
System.out.println(d.withDayOfMonth(20)); //2015-12-20T23:30:59

Java9

参考サイト

侍エンジニア塾Blog

2017年9月にリリースされたJava9は新しい機能が90個くらい追加されているそうです。 「Java9で何が変わったの?」「新機能はどのように使うの?」「どんなときに新機能を使うの?」 といった方に向けて、今回は初心者向けにJava9の新[…]

JShellでスクリプト

今までは初めてJavaを触る人がコンパイルまでやらないと実行できませんでしたが、これでかなりとっつきやすくなりました。

Jigsawでのモジュール化

依存関係を定義できるようになります。

不変コレクションの生成

Java8まで

        List<String> list = new ArrayList<>();
        list.add("a");
        list.add("b");
        list.add("c");
        list.add("d");
        list = Collections.unmodifiableList(list);
        System.out.println(list);

Java9

        List<String> list = List.of("a", "b", "c", "d");
        System.out.println(list);

匿名クラスでのダイヤモンド演算子

Java9では匿名クラスでも使えるようになったようです。

        InterfaceTest<String> it = new InterfaceTest<>() {
            @Override
            public String method(String name) {
                return "Hello " + name + "!";
            }
        };

Interface内のprivateメソッド

Java9でインターフェースにprivateメソッドを定義できるようになりました。

try-with-resources文の改良

Java8では必ずtry節内でクラスを宣言する必要がありましたが、外で定義できるようになりました。

try (BufferedReader br = new BufferedReader(fr);) {

Java9では

BufferedReader br = new BufferedReader(fr);
try (br) {

Stream APIでのメソッドの追加

ofNullableなどの便利メソッドの追加。

Optionalクラスでのメソッドの追加

Java8で追加された、NPE対策用のクラスにさらに便利メソッドの追加。

Deprecatedアノテーションの強化

@since(いつから)などの属性が追加。

Java10

このバージョンから半年おきに新バージョンが出るようになります。

Local-Variable Type Inference

ローカル変数の型推論!

var str = "123";
var list = List.of("123");

まとめ

コーディングの効率が良くなる新機能が多くありました。
eclipseも4.8が出ましたし、次の開発ではこれらを使って気持ちよくコーディングしたいですね。