SlideShare a Scribd company logo
Javaチョットデキルへの道
~JavaコアSDKに見る真似したいコード10選~
JJUG CCC 2017 Spring
2017/05/20
#jjug_ccc
#ccc_l7
Made with
エルナナ
自己紹介
• 株式会社ジャストシステム 福嶋 航
• Twitter @fukushiw
• Java歴約20年、JavaでWebサービス作っています
• #Java100 本ノックの人
https://github.com/JustSystems/java-100practices
今日お話しすること
無料でJava力アップ!
JavaコアAPIのソースはまさに宝の山。
Java 100本ノック作者がその中から選りすぐりの
10コードブロックについて、どう優れているのかこれか
ら書くコードに是非採用したくなるような、匠の技を
紹介します。
はじめに
JavaコアAPIとは
• JDKをインストールするとついてくる src.zip
• Java SE Development Kit 8u131
コメント+空行が約53.6%
7,650
1,087,643
1,004,582
251,013
2,343,238
Files
Lines of Code Effective
Lines of Code Comment
Lines of Code Blank
Lines of Code Total
本題
初級編
1~4
1
NullPointer
Exception
ダメ。ゼッタイ。
NullPointerException ダメ。ゼッタイ。
外からやってくるものは必ず null チェック!
例:java.util.Arrays LL.3998-4007
public static int hashCode(char a[]) {
if (a == null)
return 0;
int result = 1;
for (char element : a)
result = 31 * result + element;
return result;
}
NullPointerException ダメ。ゼッタイ。
特にインスタンスを生成するときは上記のように明示的にnullチェックをしておく。
インスタンスは生成できたが、使うときに(インスタンス生成時のnull渡しが原因で)
NullPointerException が発生、となると原因が追いにくくなる。
例:java.time.LocalDateTime LL.373-377
public static LocalDateTime of(LocalDate date, LocalTime time) {
Objects.requireNonNull(date, "date");
Objects.requireNonNull(time, "time");
return new LocalDateTime(date, time);
}
2
ガード節
ガード節
例:java.lang.Thread LL.325-341
public static void sleep(long millis, int nanos)
throws InterruptedException {
if (millis < 0) {
throw new IllegalArgumentException("timeout value is negative");
}
if (nanos < 0 || nanos > 999999) {
throw new IllegalArgumentException(
"nanosecond timeout value out of range");
}
if (nanos >= 500000 || (nanos != 0 && millis == 0)) {
millis++;
}
sleep(millis);
}
典型的なガード節と例外スロー。
その後の処理ロジックで異常な状態を考慮しなくてよいようにす
ることで可読性を向上している。
例外スロー時にちゃんとメッセージを設定しているところも注目。
3
例外メッセージ
は丁寧に
例外メッセージは丁寧に
何がいけないのかをちゃんと説明する
例:java.net.HttpURLConnection LL.237-251
* @throws IllegalStateException if URLConnection is already connected
* or if a different streaming mode is already enabled.
*
* @see #setFixedLengthStreamingMode(int)
* @since 1.5
*/
public void setChunkedStreamingMode (int chunklen) {
if (connected) {
throw new IllegalStateException ("Can't set streaming mode: already connected");
}
if (fixedContentLength != -1 || fixedContentLengthLong != -1) {
throw new IllegalStateException ("Fixed length streaming mode set");
}
chunkLength = chunklen <=0? DEFAULT_CHUNK_SIZE : chunklen;
}
4
メソッドは短く
シンプルに
メソッドは短くシンプルに
例:java.util.ArrayList LL.463-480
/**
* Inserts the specified element at the specified position in this
* list. Shifts the element currently at that position (if any) and
* any subsequent elements to the right (adds one to their indices).
*
* @param index index at which the specified element is to be inserted
* @param element element to be inserted
* @throws IndexOutOfBoundsException {@inheritDoc}
*/
public void add(int index, E element) {
rangeCheckForAdd(index);
ensureCapacityInternal(size + 1); // Increments modCount!!
System.arraycopy(elementData, index, elementData, index + 1,
size - index);
elementData[index] = element;
size++;
}
• コメント半分
• 直接関係ないロジックは
サブルーチン化
1
2
3
4
5
中級編
5~8
5
パフォーマンス
コンシャス
パフォーマンスコンシャス
例:java.lang.String LL.2066-2091
public String replace(char oldChar, char newChar) {
if (oldChar != newChar) {
int len = value.length;
int i = -1;
char[] val = value; /* avoid getfield opcode */
while (++i < len) {
if (val[i] == oldChar) {
break;
}
}
if (i < len) {
char buf[] = new char[len];
for (int j = 0; j < i; j++) {
buf[j] = val[j];
}
while (i < len) {
char c = val[i];
buf[i] = (c == oldChar) ? newChar : c;
i++;
}
return new String(buf, true);
}
}
return this;
}
1. oldChar != newChar で変え
る必要性を確認
2. ループの中でインスタンス変数にア
クセスしない
3. わざわざ oldChar の出現箇所を
探している
※もし出現しない場合は i == len
となるので new char[len] も new
String() もしない。
4. 3のために途中までしたループを無
駄にしない
• 極力newしない
• 極力インスタンス変数にアクセスしない
パフォーマンスコンシャス(拡大1)
public String replace(char oldChar, char newChar) {
if (oldChar != newChar) {
int len = value.length;
int i = -1;
char[] val = value; /* avoid getfield opcode */
1. oldChar != newChar で変える必要性を確認
2. ループの中でインスタンス変数にアクセスしない
パフォーマンスコンシャス(拡大2)
while (++i < len) {
if (val[i] == oldChar) {
break;
}
}
if (i < len) {
char buf[] = new char[len];
for (int j = 0; j < i; j++) {
buf[j] = val[j];
}
3. わざわざ oldChar の出
現箇所を探している
※もし出現しない場合は i
== len となるので new
char[len] も new
String() もしない。
4. 3のために途中までした
ループを無駄にしない
• 極力newしない
• 極力インスタンス変数にアクセスしない
6
CloneNot
Supported
Exception
の処理
CloneNotSupportedExceptionの処理
CloneNotSupportedException は実装次第では絶対に起きない。
(そもそもなぜ checked exception なのか不明)
ここではその例外をキャッチ、起きえないことをコメントで示し、
InternalError をスローすることで対処。
→ assert ができる前の苦肉の策と思われる。他に同様のクラスあり。
例:java.util.Vector LL.672-681
try {
@SuppressWarnings("unchecked")
Vector<E> v = (Vector<E>) super.clone();
v.elementData = Arrays.copyOf(elementData, elementCount);
v.modCount = 0;
return v;
} catch (CloneNotSupportedException e) {
// this shouldn't happen, since we are Cloneable
throw new InternalError(e);
}
ちなみに
http://bugs.java.com/bugdatabase/view_bug.do?bug_id=4220218
JDK-4220218 : Please make
CloneNotSupportedException unchecked
Resolution : Won't Fix
7
デザインパター
ンの適用
デザインパターンの適用
↑Factory Methodパターン
その他GoF23パターンがどのコアAPIで使われているか、↓このまとめが秀逸
http://stackoverflow.com/questions/1673841/examples-of-gof-
design-patterns-in-javas-core-libraries#answer-2707195
例:java.util.Calendar LL.313, 1611-1614 ※説明の便宜上折り返しを追加
public abstract class Calendar
implements Serializable, Cloneable, Comparable<Calendar> {
public static Calendar getInstance()
{
return createCalendar(TimeZone.getDefault(),
Locale.getDefault(Locale.Category.FORMAT));
}
8
サブクラスで
スーパークラスに
定義された型を
狭める
サブクラスでスーパークラスに定義された
型を狭める
UncheckedIOExceptionでは cause に IOException しか取らないように制
限している。 Serializable なので、デシリアライズで変なものが注入されないよう
に、readObject()メソッドでちゃんとガードしている。
同様のガード例として、
java.time.chrono.JapaneseChronology#readObject()メソッドは常に
InvalidObjectException をスローするようになっている、など。
例:java.io.UncheckedIOException LL.82-89
private void readObject(ObjectInputStream s)
throws IOException, ClassNotFoundException
{
s.defaultReadObject();
Throwable cause = super.getCause();
if (!(cause instanceof IOException))
throw new InvalidObjectException("Cause must be an IOException");
}
上級編
9~10
9
立つ鳥跡を
濁さず
立つ鳥跡を濁さず
例:java.util.Timer LL.103-117
/**
* This object causes the timer's task execution thread to exit
* gracefully when there are no live references to the Timer object and no
* tasks in the timer queue. It is used in preference to a finalizer on
* Timer as such a finalizer would be susceptible to a subclass's
* finalizer forgetting to call it.
*/
private final Object threadReaper = new Object() {
protected void finalize() throws Throwable {
synchronized(queue) {
thread.newTasksMayBeScheduled = false;
queue.notify(); // In case queue is empty.
}
}
}; コアAPIの中でも数少ない finalize() のオーバーライド。この
threadReaperはどこからも参照されていないので、このfinalize()が
呼ばれるのはこのTimerインスタンスがお掃除されるとき。このときにちゃ
んと(中で起動している)スレッドを終了させるための仕掛け。
10
final変数への
代入
final変数への代入 ※黒魔術
例:java.math.BigInteger LL.4395-4465
private void readObject(java.io.ObjectInputStream s)
throws java.io.IOException, ClassNotFoundException {
:
// Commit final fields via Unsafe
UnsafeHolder.putSign(this, sign);
:
}
// Support for resetting final fields while deserializing
private static class UnsafeHolder {
private static final sun.misc.Unsafe unsafe;
:
static void putSign(BigInteger bi, int sign) {
unsafe.putIntVolatile(bi, signumOffset, sign);
}
:
} よい子は真似してはいけません!
最後に
お願い
いいものを見つけたら、
Twitter: @fukushiw
まで何卒ご一報下さい!

More Related Content

PPTX
事例で学ぶApache Cassandra
PPTX
日本で DevOps を ロケットスタートする方法
PDF
これからLDAPを始めるなら 「389-ds」を使ってみよう
PDF
第79回 Machine Learning 15minutes ! 生成AIをエンタープライズで活用するWatsonx.aiの紹介
PPTX
JAVA_HOME/binにあるコマンド、いくつ使っていますか?[JVM関連ツール編](JJUGナイトセミナー「Java解析ツール特集」 発表資料)
PPTX
レガシーコード改善のススメ
PDF
Unified JVM Logging
PDF
単なるキャッシュじゃないよ!?infinispanの紹介
事例で学ぶApache Cassandra
日本で DevOps を ロケットスタートする方法
これからLDAPを始めるなら 「389-ds」を使ってみよう
第79回 Machine Learning 15minutes ! 生成AIをエンタープライズで活用するWatsonx.aiの紹介
JAVA_HOME/binにあるコマンド、いくつ使っていますか?[JVM関連ツール編](JJUGナイトセミナー「Java解析ツール特集」 発表資料)
レガシーコード改善のススメ
Unified JVM Logging
単なるキャッシュじゃないよ!?infinispanの紹介

What's hot (20)

PDF
モジュールの凝集度・結合度・インタフェース
PDF
Zaim 500万ユーザに向けて〜Aurora 編〜
PDF
AlmaLinux と Rocky Linux の誕生経緯&比較
PDF
人生がときめくAPIテスト自動化 with Karate
PDF
DSIRNLP #3 LZ4 の速さの秘密に迫ってみる
PDF
Zabbix最新情報 ~Zabbix 6.0に向けて~ @OSC2021 Online/Fall
PDF
AWS で Presto を徹底的に使いこなすワザ
PPTX
NuxtでAPIサーバー立ててみた
PDF
.NET 7期待の新機能
PDF
SQL上級者こそ知って欲しい、なぜO/Rマッパーが重要か?
PDF
JDK 16 で導入された JEP 396 にご注意!! (JJUG CCC 2021 Spring)
PPTX
Cassandra における SSD の活用
PDF
ZOZOTOWNのマルチクラウドへの挑戦と挫折、そして未来
PDF
Apache Spark for RDBMS Practitioners: How I Learned to Stop Worrying and Lov...
PDF
今から始めるUbuntu入門_202307.pdf
PDF
PostgreSQLアンチパターン
PDF
Amazon EKS上の開発体験を最大化するプレビュー環境の作り方
PDF
Kubernetesのしくみ やさしく学ぶ 内部構造とアーキテクチャー
PDF
PHPの今とこれから2021
PDF
Jenkins 2.0 Pipeline & Blue Ocean
モジュールの凝集度・結合度・インタフェース
Zaim 500万ユーザに向けて〜Aurora 編〜
AlmaLinux と Rocky Linux の誕生経緯&比較
人生がときめくAPIテスト自動化 with Karate
DSIRNLP #3 LZ4 の速さの秘密に迫ってみる
Zabbix最新情報 ~Zabbix 6.0に向けて~ @OSC2021 Online/Fall
AWS で Presto を徹底的に使いこなすワザ
NuxtでAPIサーバー立ててみた
.NET 7期待の新機能
SQL上級者こそ知って欲しい、なぜO/Rマッパーが重要か?
JDK 16 で導入された JEP 396 にご注意!! (JJUG CCC 2021 Spring)
Cassandra における SSD の活用
ZOZOTOWNのマルチクラウドへの挑戦と挫折、そして未来
Apache Spark for RDBMS Practitioners: How I Learned to Stop Worrying and Lov...
今から始めるUbuntu入門_202307.pdf
PostgreSQLアンチパターン
Amazon EKS上の開発体験を最大化するプレビュー環境の作り方
Kubernetesのしくみ やさしく学ぶ 内部構造とアーキテクチャー
PHPの今とこれから2021
Jenkins 2.0 Pipeline & Blue Ocean
Ad

Viewers also liked (20)

PDF
Arachne Unweaved (JP)
PPTX
U-NEXT学生インターン、過激なJavaの学び方と過激な要求
PDF
Jjugccc2017spring-postgres-ccc_m1
PPTX
Kotlin is charming; The reasons Java engineers should start Kotlin.
PPTX
Jjug ccc
PDF
VMの歩む道。 Dalvik、ART、そしてJava VM
PDF
2017spring jjug ccc_f2
PDF
Java libraries you can't afford to miss
PDF
Polyglot on the JVM with Graal (English)
PDF
SpotBugs(FindBugs)による 大規模ERPのコード品質改善
PDF
Java Clientで入門する Apache Kafka #jjug_ccc #ccc_e2
PPTX
新卒2年目から始めるOSSのススメ~明日からできるコミットデビュー~
PDF
日本Javaグループ2017年定期総会 #jjug
PPTX
JJUG CCC 2017 Spring Seasar2からSpringへ移行した俺たちのアプリケーションがマイクロサービスアーキテクチャへ歩み始めた
PPTX
データ履歴管理のためのテンポラルデータモデルとReladomoの紹介 #jjug_ccc #ccc_g3
PDF
Java8移行は怖くない~エンタープライズ案件でのJava8移行事例~
PDF
Introduction of Project Jigsaw
PPTX
グラフデータベース入門
PDF
思ったほど怖くない! Haskell on JVM 超入門 #jjug_ccc #ccc_l8
PDF
Java8 コーディングベストプラクティス and NetBeansのメモリログから...
Arachne Unweaved (JP)
U-NEXT学生インターン、過激なJavaの学び方と過激な要求
Jjugccc2017spring-postgres-ccc_m1
Kotlin is charming; The reasons Java engineers should start Kotlin.
Jjug ccc
VMの歩む道。 Dalvik、ART、そしてJava VM
2017spring jjug ccc_f2
Java libraries you can't afford to miss
Polyglot on the JVM with Graal (English)
SpotBugs(FindBugs)による 大規模ERPのコード品質改善
Java Clientで入門する Apache Kafka #jjug_ccc #ccc_e2
新卒2年目から始めるOSSのススメ~明日からできるコミットデビュー~
日本Javaグループ2017年定期総会 #jjug
JJUG CCC 2017 Spring Seasar2からSpringへ移行した俺たちのアプリケーションがマイクロサービスアーキテクチャへ歩み始めた
データ履歴管理のためのテンポラルデータモデルとReladomoの紹介 #jjug_ccc #ccc_g3
Java8移行は怖くない~エンタープライズ案件でのJava8移行事例~
Introduction of Project Jigsaw
グラフデータベース入門
思ったほど怖くない! Haskell on JVM 超入門 #jjug_ccc #ccc_l8
Java8 コーディングベストプラクティス and NetBeansのメモリログから...
Ad

Similar to Javaチョットデキルへの道〜JavaコアSDKに見る真似したいコード10選〜 (20)

PDF
Spock's world
PDF
Trait in scala
KEY
GroovyなAndroidテスト #atest_hack
PDF
Scala EE 7 Essentials
PDF
ClassLoader Leak Patterns
PPT
Apexコアデベロッパーセミナー(Apexコード)071010
PDF
関西Php勉強会のlimeの話
PDF
Apache Torqueについて
PDF
JavaScript 講習会 #1
PDF
基礎から見直す ASP.NET MVC の単体テスト自動化方法 ~ Windows Azure 関連もあるかも~
PDF
React.jsでクライアントサイドなWebアプリ入門
PDF
React Native GUIDE
PPT
Eclipse を使った java 開発 111126 杉浦
PPTX
Selenium 触ってみよう
PDF
R5 3 type annotation
PDF
Java SE 9の紹介: モジュール・システムを中心に
PDF
Javaの進化にともなう運用性の向上はシステム設計にどういう変化をもたらすのか
PDF
⑯jQueryをおぼえよう!その2
PDF
FlexUnit4とMockitoFlex
PDF
from old java to java8 - KanJava Edition
Spock's world
Trait in scala
GroovyなAndroidテスト #atest_hack
Scala EE 7 Essentials
ClassLoader Leak Patterns
Apexコアデベロッパーセミナー(Apexコード)071010
関西Php勉強会のlimeの話
Apache Torqueについて
JavaScript 講習会 #1
基礎から見直す ASP.NET MVC の単体テスト自動化方法 ~ Windows Azure 関連もあるかも~
React.jsでクライアントサイドなWebアプリ入門
React Native GUIDE
Eclipse を使った java 開発 111126 杉浦
Selenium 触ってみよう
R5 3 type annotation
Java SE 9の紹介: モジュール・システムを中心に
Javaの進化にともなう運用性の向上はシステム設計にどういう変化をもたらすのか
⑯jQueryをおぼえよう!その2
FlexUnit4とMockitoFlex
from old java to java8 - KanJava Edition

More from JustSystems Corporation (20)

PDF
Spring Boot の Web アプリケーションを Docker に載せて AWS ECS で動かしている話
PDF
「技術内閣制度」〜2年間やってきて得られた事とこれから〜 #devsumi
PDF
事業に貢献する商品開発と その成長の仕組み作り ~これからのエンジニアに必要とされるスキルとは~
PDF
現役23名のPM:タイプ別マネジメントパターン
PPTX
JavaでインメモリSQLエンジンを作ってみた
PDF
DDDとクリーンアーキテクチャでサーバーアプリケーションを作っている話
PDF
JustTechTalk#11_スマイルゼミ顧客満足度への貢献
PDF
ピュアJavaだと思った?残念androidでした~いつからAndroidをJavaだと錯覚していた?~
PDF
最新のJava言語仕様で見るモジュールシステム #jjug
PPTX
「書ける」から「できる」になれる! ~Javaメモリ節約ノウハウ話~
PDF
JustTechTalk#10 React開発における自動テスト実践
PDF
JustTechTalk#10windowsアプリでのテスト自動化事例
PDF
インパス! あのこれダメッス! ~Javaコードレビューの指摘ポイント10選~
PDF
AWS運用における最適パターンの徹底活用
PPTX
ジャストシステムのDevOps実例 今後の取り組み
PDF
CSSレイアウトでなぜ失敗するか?
PPTX
Selenium WebDriver + python で E2Eテスト自動化
PPTX
TypeScriptの大規模開発への適用
PDF
UX実現に向けた社内の取り組みについて-訴求ファーストによる商品開発-
PDF
「訴求ファースト」と「こだわり駆動開発」~教育、医療、もの書き市場で戦うプロダクトマネージャーの考え方~
Spring Boot の Web アプリケーションを Docker に載せて AWS ECS で動かしている話
「技術内閣制度」〜2年間やってきて得られた事とこれから〜 #devsumi
事業に貢献する商品開発と その成長の仕組み作り ~これからのエンジニアに必要とされるスキルとは~
現役23名のPM:タイプ別マネジメントパターン
JavaでインメモリSQLエンジンを作ってみた
DDDとクリーンアーキテクチャでサーバーアプリケーションを作っている話
JustTechTalk#11_スマイルゼミ顧客満足度への貢献
ピュアJavaだと思った?残念androidでした~いつからAndroidをJavaだと錯覚していた?~
最新のJava言語仕様で見るモジュールシステム #jjug
「書ける」から「できる」になれる! ~Javaメモリ節約ノウハウ話~
JustTechTalk#10 React開発における自動テスト実践
JustTechTalk#10windowsアプリでのテスト自動化事例
インパス! あのこれダメッス! ~Javaコードレビューの指摘ポイント10選~
AWS運用における最適パターンの徹底活用
ジャストシステムのDevOps実例 今後の取り組み
CSSレイアウトでなぜ失敗するか?
Selenium WebDriver + python で E2Eテスト自動化
TypeScriptの大規模開発への適用
UX実現に向けた社内の取り組みについて-訴求ファーストによる商品開発-
「訴求ファースト」と「こだわり駆動開発」~教育、医療、もの書き市場で戦うプロダクトマネージャーの考え方~

Javaチョットデキルへの道〜JavaコアSDKに見る真似したいコード10選〜