Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

10のJava9で変わるJava8の嫌なとこ!

51,893 views

Published on

10のJava9で変わるJava8の嫌なとこ!

Published in: Technology
  • Java9には含まれない(と思う)ので注意してください.
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
  • 補足ですが,最後のスライドはJava9ではなく,それよりも後のJava10,11を目指して考えられている話です.
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here

10のJava9で変わるJava8の嫌なとこ!

  1. 1. 10のJava9で変わるJava8の嫌なとこ!
  2. 2. ● Java9で解決されるJava8で嫌なことランキング – 個人的主観に基づく – どのように解決されるかを紹介 – Java9に上げるときに,気をつけることなども紹介 ● 細かくは紹介しないので,気になったものがあった ら調べてください – 過去のリリースの既知の事も詳しく説明しない
  3. 3. Jigsaw(モジュール化) JShell(JavaのREPL) G1GCデフォルト化
  4. 4. 10位 コンパイルに時間かかりすぎ
  5. 5. コンパイルに時間かかりすぎ class C<T> { C() {} C(T t) {} C(C<T> c) {} static <U> C<U> m(C<U> c) {return c;} public static void main(String... args) { C<String> c = m(new C<>(m(new C<>(m(new C<>())))); // 1秒以下 } }
  6. 6. コンパイルに時間かかりすぎ m(new C<>( m(new C<>( m(new C<>( m(new C<>( m(new C<>()))))))))) // ネスト5: Javac(2.02s), ECJ(1.17s)
  7. 7. コンパイルに時間かかりすぎ m(new C<>( m(new C<>( m(new C<>( m(new C<>( m(new C<>( m(new C<>( m(new C<>()))))))))))))) // ネスト7: Javac(14.99s) ECJ(10.82s)
  8. 8. コンパイルに時間かかりすぎ m(new C<>( m(new C<>( m(new C<>( m(new C<>( m(new C<>( m(new C<>( m(new C<>( m(new C<>( m(new C<>( m(new C<>()))))))))))))))))))) //ネスト10
  9. 9. コンパイルに時間かかりすぎ 1分? 10分? 20分? 60分/それ以上?
  10. 10. 60分以上
  11. 11. コンパイルに時間かかりすぎ ● 型検査とオーバロード解決/型推論は同時に行う – m(new C<>(expr)) ● C(T)と仮定して,exprの型検査とオーバロード解決/型推論 ● C(C<U>)と仮定して,exprの型検査とオーバロード解決/型推論 – expr=m(new C<>(expr1))なら指数的に増加
  12. 12. コンパイルに時間かかりすぎ ● オーバロード数Nとすると – N*3回,exprの型検査とオーバロード解決/型推論 ● Strict, Loose, Varargs for each of overloaded methods
  13. 13. Tiered Attribution ● 型検査とオーバーロード解決/型推論を分離 ● 型検査 – オーバーロード解決内でやる必要は無かった ● オーバーロード解決/型推論 – 実引数に構造的な型与える ● 推論が必要な場合,型推論情報を持つ – 何度も同じ式を処理しない(メモ化)
  14. 14. 1秒以下
  15. 15. 4000倍
  16. 16. 9位 Stringの+のコード生成がイケてない
  17. 17. String +のコード生成 String s = “aaa” + hoge + foo ↓ StringBuilder s$sb = new StringBuilder(); s$sb.append(“aaa”).append(hoge).append(foo); String s = s$sb.toString();
  18. 18. String +のコード生成 ● 将来のJDKでFastestStringBuilderが実装されたら – 過去のJDKでコンパイルされたコード ● StringBuilderに強く依存 ● 将来のJDKで動かしてもFastestStringBuilderが使われない – 実際にこれは過去にあったこと ● StringBufferからStringBuilderに – 全てのコードをコンパイルし直す必要 ● コンパイラのメンテナンスコスト大 – コード生成処理って,地獄・・・
  19. 19. invokedynamicを使う public java.lang.String m(java.lang.String, int); descriptor: (Ljava/lang/String;I)Ljava/lang/String; flags: ACC_PUBLIC Code: stack=2, locals=3, args_size=3 0: aload_1 1: iload_2 2: invokedynamic #5, 0 // InvokeDynamic #0:makeConcatWithConstants:(Ljava/lang/String;I)Ljava/lang/String; 7: areturn
  20. 20. invokedynamicを使う ● ライブラリが文字列連結 ● 将来のJDKでFastestStringBuilderが実装された ら – 過去のJDKでコンパイルされたコード ● FastestStringBuilderが使われる – コンパイルし直す必要なし!
  21. 21. 懸念点 ● Android N未満だと動かなくなるかも? – invokedynamic解釈できない – -XdstringConcat=inline でレガシーバイトコード生成
  22. 22. 8位 匿名クラスにダイアモンド演算子 が使えない!
  23. 23. 匿名クラス+ダイアモンド演算子 List<String> list = new ArrayList<String>() {{ add(“hoge”); }}; // JAX-RS client List<String> res = target.get(new GenericType<String>(){});
  24. 24. 使えるようになります List<String> list = new ArrayList<>() {{ add(“hoge”); }}; // JAX-RS client List<String> res = target.get(new GenericType<>(){});
  25. 25. 7位 Javadocイケてない! 検索もできない! HTML4で時代遅れ!
  26. 26. 検索できるようになります!
  27. 27. 検索できるようになります!
  28. 28. モジュールがトップに表示 ● 頑張ってどのパッケージがどのモジュールに属すか 覚えましょう
  29. 29. 6位ぐらい Deprecated意味ない,情報少ない
  30. 30. @Decprecated @Deprecated public void stop() {…} ● どういうDeprecated??? – いつDeprecatedになったの??? – いつか削除されるの???
  31. 31. @Deprecatedが変わる! @Deprecated( forRemoval = false, // 将来削除される? since = “1.2”) // いつからDepr.に? public void stop() {...}
  32. 32. Changin Depr. In JDK ● add @Deprecated to constructors for boxed primitives (Boolean, Integer, etc.) (JDK-8145468) ● add @Deprecated(forRemoval=true) to the Runtime.traceInstructions and Runtime.traceMethodCalls methods (JDK-8153330) ● add @Deprecated to various java.applet and related classes (JEP 289) ● add @Deprecated to java.util.Observable and Observer (JDK-8154801) ● add @Deprecated(forRemoval=true) to various superseded security APIs, including java.security.acl (JDK- 8157847), javax.security.cert and com.sun.net.ssl (JDK-8157712), java.security.Certificate (JDK-8157707), and javax.security.auth.Policy (JDK-8157848) ● add @Deprecated to "legacy collection" implementations Dictionary, Enumeration, Hashtable, Stack, and Vector (JDK-8145469) ● add @Deprecated to java.util.Timer and TimerTask (JDK-8154799) ● add @Deprecated to the Optional.get method (JDK-8160606) ● add @Deprecated to java.util.Date, Calendar, and related classes (JDK-8164898) ● add @Deprecated to java.lang.Compiler (JDK-4285505) ● add @Deprecated to the java.corba module ● modify already-deprecated methods Thread.destroy(), Thread.stop(Throwable), Thread.countStackFrames(), System.runFinalizersOnExit(), and various disused Runtime and SecurityManager methods to have @Deprecated(forRemoval=true) (JDK-8145468) ● remove @Deprecated from java.awt.Component.show and hide
  33. 33. 警告のルールも変わる! | API declaration site use site | not dep. forRemoval context | false true +---------------------------------- not dep. | 警告 警告 forRemoval=false | 警告 forRemoval=true | 警告
  34. 34. @SuprressWarning ● “deprecation” – forRemoval = falseの警告を抑制 ● “removal” – forRemoval = trueの警告を抑制 ● 両方抑えたかったら – @SuppressWarning({“deprecation”, “removal”})
  35. 35. jdeprscan ● jar内のDeprecatedなAPIの使用を検出
  36. 36. 5位 Collectionのstaticファクトリー無いの不便
  37. 37. 初期値付き不変コレクション生成 ● Arrays.asList(“abc”); ● Set<String> s = Collections.unmodifiableSet( new HashSet<>(Arrays.asList(“abc”))); ● Collections.unmodifiableSet( new HashMap<Integer, String>() {{ put(0, “hoge”); }});
  38. 38. staticファクトリーできました! ● List#of – List.of(“abc”) ● Set#of – Set.of(“abc”) ● Map#of – Map.of(0, “hoge”) – Map.ofEntries(Map.entry(0, “hoge”)) ● それぞれ0〜10要素までオーバロード – それ以上は可変長引数 ● 全てイミュータブル – 変更,追加しようとすると例外
  39. 39. Guava使ってるなら要らない?
  40. 40. 4位 Stream全然便利じゃない!
  41. 41. Infinit Stream Stream.iterate(1, i → i*2+3)... Stream.generate(() → new Hoge())... ● このまま終端操作を実行すると,無限ループに – forEach, collect, reduce – Finite Streamにする必要がある
  42. 42. To Finite Stream ● limit(n) – 先頭からn件の有限Streamに ● これ以外に手段がない! – ある条件を満たすまで,とか
  43. 43. 条件でskip/limitできるように ● takeWhile(Predicate) – 条件でlimit – Stream.iterate(1, i → i*2+3) .takeWhile(i → i < 100)... ● dropWhile(Predicate) – 条件を満たす間skip
  44. 44. for文的Stream生成 ● Stream#iterate(T t, Predicate p, T→T next) – for (T t; p.test(t); t = next.apply(t)) {…} – Stream.iterate(2, i → i<100, i → i*2+3)
  45. 45. StreamとOptionalの相互運用 ● List<Optional<String>> opts = …; ● opts.stream() .filter(Optional::isPresent) .map(Optional::get) .・・・
  46. 46. StreamとOptionalの相互運用 ● List<Optional<String>> opts = …; ● opts.stream() .flatMap(Optional::stream) .・・・
  47. 47. その他 ● Stream<LocalDate> LocalDate.datesUntil( LocalDate endExclusive) ● Stream<LocalDate> LocalDate.datesUntil( LocalDate endExclusive, Period step) ● Stream<String> Scanner.tokens() ● Stream<MatchResult> Scanner.findAll(Pattern pattern) ● Stream<MatchResult> Matcher.results()
  48. 48. 3位 Javaのバージョン意味不明
  49. 49. いままでのJavaバージョン ● JDK 7 Update 55 – ● JDK 7 Update 60 –
  50. 50. いままでのJavaバージョン ● JDK 7 Update 55 – セキュリティーアップデート(CPU) ● JDK 7 Update 60 – マイナーアップデート ● どちらも同じセキュリティーパッチが入っている
  51. 51. バージョンスキームが変わります ● Java $MAJOR.$MINOR.$SECURITY – Java 9.1.3 ● Java9 ● マイナーバージョンアップ1回 ● セキュリティー3回 ● -$PRE+$BUILD-$OPT – -$PRE: eaとかの情報 – +$BUILD: ビルドナンバー – -$OPT: 追加のビルド情報,日付など
  52. 52. Runtime.Versionクラス Runtime.Version version = Runtime.version(); int major = version.major(); int minor = version.minor(); int security = version.security();
  53. 53. バージョンスキームに依存するコードは 動かなくなるかも! ● System.getProperty("java.version") => "9" ● System.getProperty("java.version").charAt(3) – 例外に!!
  54. 54. 2位 ● ちょっとしたAPIの確認面倒くさい! ● もっと気軽にJava書きたい!
  55. 55. jshell; Java REPL Tool来る! jshell> Runtime.version() $8 ==> 9-ea+122 jshell> $8.major() $9 ==> 9 jshell> $8.minor() $10 ==> 0 jshell> $8.pre() $11 ==> Optional[ea] jshell>
  56. 56. 1位 パッケージ管理イケてない!
  57. 57. クラスパス地獄 public is too public
  58. 58. モジュール化(Jigsaw) // module-info.java module mymodule { requires java.compiler; // java.compilerというモジュールを利用 // java.compilerモジュールファイルで // exportされているパッケージ内のpublicクラスが利用可 exports com.mymodule.util; // com.mymodule.util内のpublicクラスを他モジュールが利用可に }
  59. 59. モジュール化すると・・・? ● クラスパスの指定がほぼ要らなくなる – modulepathを指定する ● ディレクトリ1つだけ ● public classの可視性を管理できる ⇔今まで使用してた内部APIにアクセスできなくなる!?
  60. 60. 他にも ● HTTP2.0 ● Compact Strings ● VarHandle ● G1GCデフォルト化 – CMSがDeprecatedに ● javacの-releaseオプション ● Applet APIがDeprecatedに
  61. 61. More Future(Java 10〜) ● ローカル変数でvalが! – val hoge = “hoge”; ● ジェネリクスの特殊化 – List<int> ints; ● 値型 – 構造体みたいなの – メモリ使用量削減 ● Foreign Function Interface

×