SlideShare a Scribd company logo
ピュアJavaだと思った?
残念Androidでした
~いつからAndroidをJavaだと錯覚していた?~
空中清高
空中清高 @soranakk
● 所属:ジャストシステム
○ スマイルゼミ中学生コース
■ ホームアプリ
■ システムアプリ
● Android開発歴:4年半ぐらい
目次
Oracle JavaとAndroid Javaの違い
ArrayListの不思議な現象
ピュアJavaだと思った?残念Androidでした
ArrayListで例外が発生する仕組み
いつからAndroidをJavaだと錯覚していた?
AndroidとJavaはAPIが同じなだけ
その他の事例もあるぞ(先駆者紹介)
目次
Oracle JavaとAndroid Javaの違い
ArrayListの不思議な現象
ピュアJavaだと思った?残念Androidでした
ArrayListで例外が発生する仕組み
いつからAndroidをJavaだと錯覚していた?
AndroidとJavaはAPIが同じなだけ
その他の事例もあるぞ(先駆者紹介)
Oracle JavaとAndroid Javaの違い
Android JavaOracle Java
● javaはclassファイルにされ、さらにdexファ
イルにコンパイルされる
● 実行環境はDalvik or ART
● javaはclassファイルにコンパイルされ
る
● 実行環境はLinux, Mac OS,
WindowsなどのJRE
Oracle Javaの世界
JVM
Java実行環境
rt.jar
● Object
● String
● List   … etc
標準ライブラリ
classjava
Android Javaの世界
Dalvik or ART
android.jar
● Object
● String
● List   … etc
標準ライブラリ
dexclass
java
Oracle JavaとAndroid Javaの違い
Android JavaOracle Java
● buildツール
● バイトコード
● 標準ライブラリ
● 実行マシン
● 実行OS
● etc...
Oracle JavaとAndroid Javaの違い
Android JavaOracle Java
● buildツール
● バイトコード
● 標準ライブラリ
● 実行マシン
● 実行OS
● etc...
今日話すのはココ!
標準ライブラリの違い
Oracle JavaとAndroid Javaの違い
Android JavaOracle Java
rt.jar
● Object
● String
● List   … etc
標準ライブラリ
android.jar
● Object
● String
● List   … etc
標準ライブラリ
VS
目次
Oracle JavaとAndroid Javaの違い
ArrayListの不思議な現象
ピュアJavaだと思った?残念Androidでした
ArrayListで例外が発生する仕組み
いつからAndroidをJavaだと錯覚していた?
AndroidとJavaはAPIが同じなだけ
その他の事例もあるぞ(先駆者紹介)
ArrayListの不思議な現象
List<String> list = new ArrayList<>();
list.add("foo");
list.add("bar");
list.add("baz");
for (String str : list) {
if ("baz".equals(str)) {
System.out.println("find!");
}
System.out.println(str);
}
ArrayListの不思議な現象
> foo
> bar
> find!
> baz
List<String> list = new ArrayList<>();
list.add("foo");
list.add("bar");
list.add("baz");
for (String str : list) {
if ("baz".equals(str)) {
System.out.println("find!");
}
System.out.println(str);
}
for文中にあることをすると・・・おおっと
List<String> list = new ArrayList<>();
list.add("foo");
list.add("bar");
list.add("baz");
for (String str : list) {
if ("baz".equals(str)) {
list.remove(str);
}
System.out.println(str);
}
for文中にあることをすると・・・おおっと
> foo
> bar
> baz
> ConcurrentModificationException
List<String> list = new ArrayList<>();
list.add("foo");
list.add("bar");
list.add("baz");
for (String str : list) {
if ("baz".equals(str)) {
list.remove(str);
}
System.out.println(str);
}
ConcurrentModificationException is 何?
● マルチスレッドで同じArrayListを変更したときなどに発生する例外
● シングルスレッドでもループ文などで発生することがある
● 仕組み(概要)
○ ArrayListは内部的に変更回数を持っている
○ Iteratorで変更回数をチェックしている
○ 変更回数がループ開始時点から変わっていたら例外を投げる
「あるはずの終端が無い!」とか、「終わったと思ったのにまだ残ってる!?」
とかを防ぐための機構。
JavaDocによると、「完全に防げるわけではない、best-effort」
https://docs.oracle.com/javase/9/docs/api/java/util/ConcurrentModificationExc
eption.html
ConcurrentModificationException is 何?
● マルチスレッドで同じArrayListを変更したときなどに発生する例外
● シングルスレッドでもループ文などで発生することがある
● 仕組み(概要)
○ ArrayListは内部的に変更回数を持っている
○ Iteratorで変更回数をチェックしている
○ 変更回数がループ開始時点から変わっていたら例外を投げる
「あるはずの終端が無い!」とか、「終わったと思ったのにまだ残ってる!?」
とかを防ぐための機構。
JavaDocによると、「完全に防げるわけではない、best-effort」
https://docs.oracle.com/javase/9/docs/api/java/util/ConcurrentModificationExc
eption.html
best-effort?
List<String> list = new ArrayList<>();
list.add("foo");
list.add("bar");
list.add("baz");
for (String str : list) {
if ("baz".equals(str)) {
list.remove(str);
}
System.out.println(str);
}
ArrayListの不思議な現象
> foo
> bar
> baz
> ConcurrentModificationException
List<String> list = new ArrayList<>();
list.add("foo");
list.add("bar");
list.add("baz");
for (String str : list) {
if ("bar".equals(str)) {
list.remove(str);
}
System.out.println(str);
}
ArrayListの不思議な現象
List<String> list = new ArrayList<>();
list.add("foo");
list.add("bar");
list.add("baz");
for (String str : list) {
if ("baz".equals(str)) {
list.remove(str);
}
System.out.println(str);
}
> foo
> bar
> baz
> ConcurrentModificationException
ArrayListの不思議な現象
List<String> list = new ArrayList<>();
list.add("foo");
list.add("bar");
list.add("baz");
for (String str : list) {
if ("bar".equals(str)) {
list.remove(str);
}
System.out.println(str);
}
List<String> list = new ArrayList<>();
list.add("foo");
list.add("bar");
list.add("baz");
for (String str : list) {
if ("baz".equals(str)) {
list.remove(str);
}
System.out.println(str);
}
> foo
> bar
> baz
> ConcurrentModificationException
ココが違う
ArrayListの不思議な現象
List<String> list = new ArrayList<>();
list.add("foo");
list.add("bar");
list.add("baz");
for (String str : list) {
if ("bar".equals(str)) {
list.remove(str);
}
System.out.println(str);
}
List<String> list = new ArrayList<>();
list.add("foo");
list.add("bar");
list.add("baz");
for (String str : list) {
if ("baz".equals(str)) {
list.remove(str);
}
System.out.println(str);
}
> foo
> bar
> baz
> ConcurrentModificationException
ココが違う
> foo
> bar
ArrayListの不思議な現象
List<String> list = new ArrayList<>();
list.add("foo");
list.add("bar");
list.add("baz");
for (String str : list) {
if ("bar".equals(str)) {
list.remove(str);
}
System.out.println(str);
}
List<String> list = new ArrayList<>();
list.add("foo");
list.add("bar");
list.add("baz");
for (String str : list) {
if ("baz".equals(str)) {
list.remove(str);
}
System.out.println(str);
}
> foo
> bar
> baz
> ConcurrentModificationException
ココが違う
例外が発生しない!?
> foo
> bar
ArrayListの不思議な現象
● ConcurrentModificationExceptionの発生はbest-effort
● 例外は発生したり、しなかったりする
● たとえばリストの最後から二番目をremoveしたときは発生しない
ArrayListの不思議な現象
● ConcurrentModificationExceptionの発生はbest-effort
● 例外は発生したり、しなかったりする
● たとえばリストの最後から二番目をremoveしたときは発生しない
Javaは不思議だなぁ
Androidでも同じかなぁ?
目次
Oracle JavaとAndroid Javaの違い
ArrayListの不思議な現象
ピュアJavaだと思った?残念Androidでした
ArrayListで例外が発生する仕組み
いつからAndroidをJavaだと錯覚していた?
AndroidとJavaはAPIが同じなだけ
その他の事例もあるぞ(先駆者紹介)
ピュアJavaだと思った?残念Androidでした
List<String> list = new ArrayList<>();
list.add("foo");
list.add("bar");
list.add("baz");
for (String str : list) {
if ("bar".equals(str)) {
list.remove(str);
}
System.out.println(str);
}
List<String> list = new ArrayList<>();
list.add("foo");
list.add("bar");
list.add("baz");
for (String str : list) {
if ("baz".equals(str)) {
list.remove(str);
}
System.out.println(str);
}
ココが違う
ピュアJavaだと思った?残念Androidでした
List<String> list = new ArrayList<>();
list.add("foo");
list.add("bar");
list.add("baz");
for (String str : list) {
if ("bar".equals(str)) {
list.remove(str);
}
System.out.println(str);
}
List<String> list = new ArrayList<>();
list.add("foo");
list.add("bar");
list.add("baz");
for (String str : list) {
if ("baz".equals(str)) {
list.remove(str);
}
System.out.println(str);
}
ココが違う
> foo
> bar
> baz
> 例外発生
Oracle Java
> foo
> bar
Oracle Java
ピュアJavaだと思った?残念Androidでした
> foo
> bar
> baz
List<String> list = new ArrayList<>();
list.add("foo");
list.add("bar");
list.add("baz");
for (String str : list) {
if ("bar".equals(str)) {
list.remove(str);
}
System.out.println(str);
}
List<String> list = new ArrayList<>();
list.add("foo");
list.add("bar");
list.add("baz");
for (String str : list) {
if ("baz".equals(str)) {
list.remove(str);
}
System.out.println(str);
}
ココが違う
> foo
> bar
> baz
> 例外発生
Android JavaOracle Java
> foo
> bar
> 例外発生
> foo
> bar
Android JavaOracle Java
ピュアJavaだと思った?残念Androidでした
> foo
> bar
> baz
List<String> list = new ArrayList<>();
list.add("foo");
list.add("bar");
list.add("baz");
for (String str : list) {
if ("bar".equals(str)) {
list.remove(str);
}
System.out.println(str);
}
List<String> list = new ArrayList<>();
list.add("foo");
list.add("bar");
list.add("baz");
for (String str : list) {
if ("baz".equals(str)) {
list.remove(str);
}
System.out.println(str);
}
ココが違う
> foo
> bar
> baz
> 例外発生
Android JavaOracle Java
> foo
> bar
> 例外発生
> foo
> bar
Android JavaOracle Java
JavaとAndroidで結果が違う
目次
Oracle JavaとAndroid Javaの違い
ArrayListの不思議な現象
ピュアJavaだと思った?残念Androidでした
ArrayListで例外が発生する仕組み
いつからAndroidをJavaだと錯覚していた?
AndroidとJavaはAPIが同じなだけ
その他の事例もあるぞ(先駆者紹介)
ループ開始
ArrayListで例外が発生する仕組み:概要
ループ開始 変更回数をチェック
ArrayListで例外が発生する仕組み:概要
ループ開始 変更回数をチェック あれ?変更回数が違ってる?
ArrayListで例外が発生する仕組み:概要
ループ開始 変更回数をチェック あれ?変更回数が違ってる?
ArrayListで例外が発生する仕組み:概要
もしかするとあるはずの終端が無いかもしれない?
終わったと思ったのにまだ残ってるかもしれない!?
ループ開始 変更回数をチェック
List警察だ!例外を投げる!
あれ?変更回数が違ってる?
ArrayListで例外が発生する仕組み:概要
もしかするとあるはずの終端が無いかもしれない?
終わったと思ったのにまだ残ってるかもしれない!?
ループ開始 変更回数をチェック
List警察だ!例外を投げる!
あれ?変更回数が違ってる?
ArrayListで例外が発生する仕組み:概要
もしかするとあるはずの終端が無いかもしれない?
終わったと思ったのにまだ残ってるかもしれない!?
概要はわかったけど、
まだよくわかんないなぁ
ループ開始 変更回数をチェック
List警察だ!例外を投げる!
あれ?変更回数が違ってる?
ArrayListで例外が発生する仕組み:概要
もしかするとあるはずの終端が無いかもしれない?
終わったと思ったのにまだ残ってるかもしれない!?
やっぱエンジニアだしコード
で理解したい
ArrayListで例外が発生する仕組み
for (String str : list) {
...省略
}
拡張for文は次のように展開されます
https://jcp.org/aboutJava/communityprocess/jsr/tiger/enhanced-for.html
for (Iterator<String> iter = list.iterator(); iter.hasNext(); ) {
String str = iter.next();
...省略
}
ArrayListで例外が発生する仕組み
● ListはmodCountというint値を持っている
● modCountはadd() remove()などでインクリメントされる
● IteratorはmodCountを監視している
Java 9.0.4 java.util.ArrayList.javaより一部抜粋 (872行あたりから)
for (Iterator<String> iter = list.iterator(); iter.hasNext(); ) {
String str = iter.next();
…省略
}
public Iterator<E> iterator() {
return new Itr();
}
class Itr implements Iterator<E> {
int expectedModCount = modCount;
…省略
}
ArrayListで例外が発生する仕組み
class Itr implements Iterator<E> {
int expectedModCount = modCount;
public boolean hasNext() {
return cursor != size;
}
public E next() {
checkForComodification();
int i = cursor;
...省略
cursor = i + 1;
return (E) elementData[lastRet = i];
}
…省略
Java 9.0.4 java.util.ArrayList.javaより一部抜粋 (872行あたりから)
for (Iterator<String> iter = list.iterator(); iter.hasNext(); ) {
String str = iter.next();
…省略
}
ArrayListで例外が発生する仕組み
Java 9.0.4 java.util.ArrayList.javaより一部抜粋 (872行あたりから)
final void checkForComodification() {
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
}
for (Iterator<String> iter = list.iterator(); iter.hasNext(); ) {
String str = iter.next();
…省略
}
class Itr implements Iterator<E> {
int expectedModCount = modCount;
public boolean hasNext() {
return cursor != size;
}
public E next() {
checkForComodification();
int i = cursor;
...省略
cursor = i + 1;
return (E) elementData[lastRet = i];
}
…省略
例外発生の仕組み Oracle Java
List<String> list = new ArrayList<>();
list.add("foo");
list.add("bar");
list.add("baz");
for (String str : list) {
if ("baz".equals(str)) {
list.remove(str);
}
System.out.println(str);
}
例外発生の仕組み Oracle Java
List<String> list = new ArrayList<>();
list.add("foo");
list.add("bar");
list.add("baz");
for (String str : list) {
if ("baz".equals(str)) {
list.remove(str);
}
System.out.println(str);
}
拡張for文が展開される
例外発生の仕組み Oracle Java
List<String> list = new ArrayList<>();
list.add("foo");
list.add("bar");
list.add("baz");
for (Iterator<String> iter = list.iterator(); iter.hasNext(); ) {
String str = iter.next();
if ("baz".equals(str)) {
list.remove(str);
}
System.out.println(str);
}
拡張for文が展開される
例外発生の仕組み Oracle Java
List<String> list = new ArrayList<>();
list.add("foo");
list.add("bar");
list.add("baz");
for (Iterator<String> iter = list.iterator(); iter.hasNext(); ) {
String str = iter.next();
if ("baz".equals(str)) {
list.remove(str);
}
System.out.println(str);
}
拡張for文が展開される
str == "baz"のときcursor = 3
例外発生の仕組み Oracle Java
List<String> list = new ArrayList<>();
list.add("foo");
list.add("bar");
list.add("baz");
for (Iterator<String> iter = list.iterator(); iter.hasNext(); ) {
String str = iter.next();
if ("baz".equals(str)) {
list.remove(str);
}
System.out.println(str);
}
拡張for文が展開される
str == "baz"のときcursor = 3
remove(str)でmodCount++, size = 2
例外発生の仕組み Oracle Java
List<String> list = new ArrayList<>();
list.add("foo");
list.add("bar");
list.add("baz");
for (Iterator<String> iter = list.iterator(); iter.hasNext(); ) {
String str = iter.next();
if ("baz".equals(str)) {
list.remove(str);
}
System.out.println(str);
}
拡張for文が展開される
str == "baz"のときcursor = 3
remove(str)でmodCount++, size = 2
次のhasNext()はcursor != size == true で継続
例外発生の仕組み Oracle Java
List<String> list = new ArrayList<>();
list.add("foo");
list.add("bar");
list.add("baz");
for (Iterator<String> iter = list.iterator(); iter.hasNext(); ) {
String str = iter.next();
if ("baz".equals(str)) {
list.remove(str);
}
System.out.println(str);
}
拡張for文が展開される
str == "baz"のときcursor = 3
remove(str)でmodCount++, size = 2
次のhasNext()はcursor != size == true で継続
next()のcheckForComodification()で
modCount != expectedModCount == true
例外発生の仕組み Oracle Java
List<String> list = new ArrayList<>();
list.add("foo");
list.add("bar");
list.add("baz");
for (Iterator<String> iter = list.iterator(); iter.hasNext(); ) {
String str = iter.next();
if ("baz".equals(str)) {
list.remove(str);
}
System.out.println(str);
}
拡張for文が展開される
str == "baz"のときcursor = 3
remove(str)でmodCount++, size = 2
次のhasNext()はcursor != size == true で継続
next()のcheckForComodification()で
modCount != expectedModCount == true
ん~・・・
例外発生の仕組み Oracle Java
List<String> list = new ArrayList<>();
list.add("foo");
list.add("bar");
list.add("baz");
for (Iterator<String> iter = list.iterator(); iter.hasNext(); ) {
String str = iter.next();
if ("baz".equals(str)) {
list.remove(str);
}
System.out.println(str);
}
拡張for文が展開される
str == "baz"のときcursor = 3
remove(str)でmodCount++, size = 2
次のhasNext()はcursor != size == true で継続
next()のcheckForComodification()で
modCount != expectedModCount == true
変わってる
例外発生の仕組み Oracle Java
List<String> list = new ArrayList<>();
list.add("foo");
list.add("bar");
list.add("baz");
for (Iterator<String> iter = list.iterator(); iter.hasNext(); ) {
String str = iter.next();
if ("baz".equals(str)) {
list.remove(str);
}
System.out.println(str);
}
拡張for文が展開される
str == "baz"のときcursor = 3
remove(str)でmodCount++, size = 2
次のhasNext()はcursor != size == true で継続
next()のcheckForComodification()で
modCount != expectedModCount == true
List警察だ!例外を投げる!
変わってる
例外が発生しない仕組み Oracle Java
List<String> list = new ArrayList<>();
list.add("foo");
list.add("bar");
list.add("baz");
for (String str : list) {
if ("bar".equals(str)) {
list.remove(str);
}
System.out.println(str);
}
例外が発生しない仕組み Oracle Java
List<String> list = new ArrayList<>();
list.add("foo");
list.add("bar");
list.add("baz");
for (String str : list) {
if ("bar".equals(str)) {
list.remove(str);
}
System.out.println(str);
}
拡張for文が展開される
例外が発生しない仕組み Oracle Java
List<String> list = new ArrayList<>();
list.add("foo");
list.add("bar");
list.add("baz");
for (Iterator<String> iter = list.iterator(); iter.hasNext(); ) {
String str = iter.next();
if ("bar".equals(str)) {
list.remove(str);
}
System.out.println(str);
}
拡張for文が展開される
例外が発生しない仕組み Oracle Java
List<String> list = new ArrayList<>();
list.add("foo");
list.add("bar");
list.add("baz");
for (Iterator<String> iter = list.iterator(); iter.hasNext(); ) {
String str = iter.next();
if ("bar".equals(str)) {
list.remove(str);
}
System.out.println(str);
}
拡張for文が展開される
str == "bar"のときcursor = 2
例外が発生しない仕組み Oracle Java
List<String> list = new ArrayList<>();
list.add("foo");
list.add("bar");
list.add("baz");
for (Iterator<String> iter = list.iterator(); iter.hasNext(); ) {
String str = iter.next();
if ("bar".equals(str)) {
list.remove(str);
}
System.out.println(str);
}
拡張for文が展開される
str == "bar"のときcursor = 2
remove(str)でmodCount++, size = 2
例外が発生しない仕組み Oracle Java
List<String> list = new ArrayList<>();
list.add("foo");
list.add("bar");
list.add("baz");
for (Iterator<String> iter = list.iterator(); iter.hasNext(); ) {
String str = iter.next();
if ("bar".equals(str)) {
list.remove(str);
}
System.out.println(str);
}
拡張for文が展開される
str == "bar"のときcursor = 2
remove(str)でmodCount++, size = 2
次のhasNext()はcursor != size == false でループ終了
例外が発生しない仕組み Oracle Java
List<String> list = new ArrayList<>();
list.add("foo");
list.add("bar");
list.add("baz");
for (Iterator<String> iter = list.iterator(); iter.hasNext(); ) {
String str = iter.next();
if ("bar".equals(str)) {
list.remove(str);
}
System.out.println(str);
}
拡張for文が展開される
str == "bar"のときcursor = 2
remove(str)でmodCount++, size = 2
次のhasNext()はcursor != size == false でループ終了
next()は呼ばれないので
checkForComodification()は呼ばれない
例外が発生しない仕組み Oracle Java
List<String> list = new ArrayList<>();
list.add("foo");
list.add("bar");
list.add("baz");
for (Iterator<String> iter = list.iterator(); iter.hasNext(); ) {
String str = iter.next();
if ("bar".equals(str)) {
list.remove(str);
}
System.out.println(str);
}
・・・
拡張for文が展開される
str == "bar"のときcursor = 2
remove(str)でmodCount++, size = 2
次のhasNext()はcursor != size == false でループ終了
next()は呼ばれないので
checkForComodification()は呼ばれない
目次
Oracle JavaとAndroid Javaの違い
ArrayListの不思議な現象
ピュアJavaだと思った?残念Androidでした
ArrayListで例外が発生する仕組み
いつからAndroidをJavaだと錯覚していた?
AndroidとJavaはAPIが同じなだけ
その他の事例もあるぞ(先駆者紹介)
いつからAndroidをJavaだと錯覚していた?
Java 9.0.4 java.util.ArrayList.javaより一部抜粋 (872行あたりから)
final void checkForComodification() {
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
}
for (Iterator<String> iter = list.iterator(); iter.hasNext(); ) {
String str = iter.next();
…省略
}
class Itr implements Iterator<E> {
int expectedModCount = modCount;
public boolean hasNext() {
return cursor != size;
}
public E next() {
checkForComodification();
int i = cursor;
...省略
cursor = i + 1;
return (E) elementData[lastRet = i];
}
…省略
いつからAndroidをJavaだと錯覚していた?
for (Iterator<String> iter = list.iterator(); iter.hasNext(); ) {
String str = iter.next();
…省略
}
class Itr implements Iterator<E> {
protected int limit = ArrayList.this.size;
int expectedModCount = modCount;
public boolean hasNext() {
return cursor < limit;
}
public E next() {
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
int i = cursor;
...省略
cursor = i + 1;
return (E) elementData[lastRet = i];
}
...省略
Android 26 java.util.ArrayList.javaより一部抜粋 (833行あたりから)
class Itr implements Iterator<E> {
protected int limit = ArrayList.this.size;
int expectedModCount = modCount;
public boolean hasNext() {
return cursor < limit;
}
public E next() {
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
int i = cursor;
...省略
cursor = i + 1;
return (E) elementData[lastRet = i];
}
...省略
いつからAndroidをJavaだと錯覚していた?
limitが追加され、
hasNext()の条件が変わっている
listのsizeが変わっても、limitは固
定されているので
hasNext()の動作が変わった!
for (Iterator<String> iter = list.iterator(); iter.hasNext(); ) {
String str = iter.next();
…省略
}
Android 26 java.util.ArrayList.javaより一部抜粋 (833行あたりから)
例外が発生しない仕組み Android Java
List<String> list = new ArrayList<>();
list.add("foo");
list.add("bar");
list.add("baz");
for (String str : list) {
if ("baz".equals(str)) {
list.remove(str);
}
System.out.println(str);
}
例外が発生しない仕組み Android Java
List<String> list = new ArrayList<>();
list.add("foo");
list.add("bar");
list.add("baz");
for (String str : list) {
if ("baz".equals(str)) {
list.remove(str);
}
System.out.println(str);
}
拡張for文が展開される
例外が発生しない仕組み Android Java
List<String> list = new ArrayList<>();
list.add("foo");
list.add("bar");
list.add("baz");
for (Iterator<String> iter = list.iterator(); iter.hasNext(); ) {
String str = iter.next();
if ("baz".equals(str)) {
list.remove(str);
}
System.out.println(str);
}
拡張for文が展開される
例外が発生しない仕組み Android Java
List<String> list = new ArrayList<>();
list.add("foo");
list.add("bar");
list.add("baz");
for (Iterator<String> iter = list.iterator(); iter.hasNext(); ) {
String str = iter.next();
if ("baz".equals(str)) {
list.remove(str);
}
System.out.println(str);
}
拡張for文が展開される
str == "baz"のときcursor = 3
例外が発生しない仕組み Android Java
List<String> list = new ArrayList<>();
list.add("foo");
list.add("bar");
list.add("baz");
for (Iterator<String> iter = list.iterator(); iter.hasNext(); ) {
String str = iter.next();
if ("baz".equals(str)) {
list.remove(str);
}
System.out.println(str);
}
拡張for文が展開される
str == "baz"のときcursor = 3
remove(str)でmodCount++, size = 2だけどlimit = 3のまま
例外が発生しない仕組み Android Java
List<String> list = new ArrayList<>();
list.add("foo");
list.add("bar");
list.add("baz");
for (Iterator<String> iter = list.iterator(); iter.hasNext(); ) {
String str = iter.next();
if ("baz".equals(str)) {
list.remove(str);
}
System.out.println(str);
}
拡張for文が展開される
str == "baz"のときcursor = 3
remove(str)でmodCount++, size = 2だけどlimit = 3のまま
次のhasNext()はcursor < limit == false でループ終了
例外が発生しない仕組み Android Java
List<String> list = new ArrayList<>();
list.add("foo");
list.add("bar");
list.add("baz");
for (Iterator<String> iter = list.iterator(); iter.hasNext(); ) {
String str = iter.next();
if ("baz".equals(str)) {
list.remove(str);
}
System.out.println(str);
}
拡張for文が展開される
str == "baz"のときcursor = 3
remove(str)でmodCount++, size = 2だけどlimit = 3のまま
次のhasNext()はcursor < limit == false でループ終了
next()は呼ばれないので
modCount != expectedModCount はチェックされない
例外が発生しない仕組み Android Java
List<String> list = new ArrayList<>();
list.add("foo");
list.add("bar");
list.add("baz");
for (Iterator<String> iter = list.iterator(); iter.hasNext(); ) {
String str = iter.next();
if ("baz".equals(str)) {
list.remove(str);
}
System.out.println(str);
}
拡張for文が展開される
str == "baz"のときcursor = 3
remove(str)でmodCount++, size = 2だけどlimit = 3のまま
次のhasNext()はcursor < limit == false でループ終了
next()は呼ばれないので
modCount != expectedModCount はチェックされない
・・・
例外発生の仕組み Android Java
List<String> list = new ArrayList<>();
list.add("foo");
list.add("bar");
list.add("baz");
for (String str : list) {
if ("bar".equals(str)) {
list.remove(str);
}
System.out.println(str);
}
例外発生の仕組み Android Java
List<String> list = new ArrayList<>();
list.add("foo");
list.add("bar");
list.add("baz");
for (String str : list) {
if ("bar".equals(str)) {
list.remove(str);
}
System.out.println(str);
}
拡張for文が展開される
例外発生の仕組み Android Java
List<String> list = new ArrayList<>();
list.add("foo");
list.add("bar");
list.add("baz");
for (Iterator<String> iter = list.iterator(); iter.hasNext(); ) {
String str = iter.next();
if ("bar".equals(str)) {
list.remove(str);
}
System.out.println(str);
}
拡張for文が展開される
例外発生の仕組み Android Java
List<String> list = new ArrayList<>();
list.add("foo");
list.add("bar");
list.add("baz");
for (Iterator<String> iter = list.iterator(); iter.hasNext(); ) {
String str = iter.next();
if ("bar".equals(str)) {
list.remove(str);
}
System.out.println(str);
}
拡張for文が展開される
str == "bar"のときcursor = 2
例外発生の仕組み Android Java
List<String> list = new ArrayList<>();
list.add("foo");
list.add("bar");
list.add("baz");
for (Iterator<String> iter = list.iterator(); iter.hasNext(); ) {
String str = iter.next();
if ("bar".equals(str)) {
list.remove(str);
}
System.out.println(str);
}
拡張for文が展開される
str == "bar"のときcursor = 2
remove(str)でmodCount++, size = 2だけどlimit = 3のまま
例外発生の仕組み Android Java
List<String> list = new ArrayList<>();
list.add("foo");
list.add("bar");
list.add("baz");
for (Iterator<String> iter = list.iterator(); iter.hasNext(); ) {
String str = iter.next();
if ("bar".equals(str)) {
list.remove(str);
}
System.out.println(str);
}
拡張for文が展開される
str == "bar"のときcursor = 2
remove(str)でmodCount++, size = 2だけどlimit = 3のまま
次のhasNext()はcursor < limit == true で継続
例外発生の仕組み Android Java
List<String> list = new ArrayList<>();
list.add("foo");
list.add("bar");
list.add("baz");
for (Iterator<String> iter = list.iterator(); iter.hasNext(); ) {
String str = iter.next();
if ("bar".equals(str)) {
list.remove(str);
}
System.out.println(str);
}
拡張for文が展開される
str == "bar"のときcursor = 2
remove(str)でmodCount++, size = 2だけどlimit = 3のまま
次のhasNext()はcursor < limit == true で継続
next()で
modCount != expectedModCount == true
例外発生の仕組み Android Java
List<String> list = new ArrayList<>();
list.add("foo");
list.add("bar");
list.add("baz");
for (Iterator<String> iter = list.iterator(); iter.hasNext(); ) {
String str = iter.next();
if ("bar".equals(str)) {
list.remove(str);
}
System.out.println(str);
}
ん~・・・
拡張for文が展開される
str == "bar"のときcursor = 2
remove(str)でmodCount++, size = 2だけどlimit = 3のまま
次のhasNext()はcursor < limit == true で継続
next()で
modCount != expectedModCount == true
例外発生の仕組み Android Java
List<String> list = new ArrayList<>();
list.add("foo");
list.add("bar");
list.add("baz");
for (Iterator<String> iter = list.iterator(); iter.hasNext(); ) {
String str = iter.next();
if ("bar".equals(str)) {
list.remove(str);
}
System.out.println(str);
}
拡張for文が展開される
str == "bar"のときcursor = 2
remove(str)でmodCount++, size = 2だけどlimit = 3のまま
次のhasNext()はcursor < limit == true で継続
next()で
modCount != expectedModCount == true
変わってる
例外発生の仕組み Android Java
List警察だ!例外を投げる!
List<String> list = new ArrayList<>();
list.add("foo");
list.add("bar");
list.add("baz");
for (Iterator<String> iter = list.iterator(); iter.hasNext(); ) {
String str = iter.next();
if ("bar".equals(str)) {
list.remove(str);
}
System.out.println(str);
}
拡張for文が展開される
str == "bar"のときcursor = 2
remove(str)でmodCount++, size = 2だけどlimit = 3のまま
次のhasNext()はcursor < limit == true で継続
next()で
modCount != expectedModCount == true
変わってる
目次
Oracle JavaとAndroid Javaの違い
ArrayListの不思議な現象
ピュアJavaだと思った?残念Androidでした
ArrayListで例外が発生する仕組み
いつからAndroidをJavaだと錯覚していた?
AndroidとJavaはAPIが同じなだけ
その他の事例もあるぞ(先駆者紹介)
AndroidとJavaはAPIが同じなだけ
Oracle Java
● ConcurrentModificationExceptionの発生はbest-effort
● 例外は発生したり、しなかったりする
● たとえばリストの最後から二番目をremoveしたときは発生しない
Android Java
● ConcurrentModificationExceptionの発生はbest-effort
● 例外は発生したり、しなかったりする
● たとえばリストの最後をremoveしたときは発生しない
AndroidとJavaはAPIが同じなだけ
Oracle Java
● ConcurrentModificationExceptionの発生はbest-effort
● 例外は発生したり、しなかったりする
● たとえばリストの最後から二番目をremoveしたときは発生しない
Android Java
● ConcurrentModificationExceptionの発生はbest-effort
● 例外は発生したり、しなかったりする
● たとえばリストの最後をremoveしたときは発生しない
標準ライブラリが違う!
目次
Oracle JavaとAndroid Javaの違い
ArrayListの不思議な現象
ピュアJavaだと思った?残念Androidでした
ArrayListで例外が発生する仕組み
いつからAndroidをJavaだと錯覚していた?
AndroidとJavaはAPIが同じなだけ
その他の事例もあるぞ(先駆者紹介)
その他の事例もあるぞ(先駆者紹介)
● Java と Android の正規表現の動作の違い
   https://qiita.com/KeithYokoma/items/2915a904a18760ee67c4
○ 正規表現ライブラリの違いに解説されています
● Android Javaの正規表現の落とし穴
   https://www.ecoop.net/memo/archives/regular-expression-problem-o-android-java.html
○ こちらも正規表現ですが、Stringクラスの違いについて解説されています
ご静聴ありがとうございました。
細かい補足
じゃあfor文中にリストから削除したいときはどうしたらいいの?
拡張for文の中でlist#removeは使ってはいけません。
代わりにIteratorでfor文を回して、Iterator#removeを使いましょう。
あるいはKotlinのfilterを使うと良いです。
List<String> list = new ArrayList<>();
list.add("foo");
list.add("bar");
list.add("baz");
for (Iterator<String> iter = list.iterator(); iter.hasNext(); ) {
String str = iter.next();
if ("baz".equals(str)) {
iter.remove();
}
System.out.println(str);
}
細かい補足
Android N 以降はOpen JDKを使っているって聞いたけど?
はい、その通りです。
でも実はAndroidのJavaはOpen JDKからさらに変更を加えています
そのため、今回紹介したArrayListの操作では
Open JDK != Android Java
となります。
Open JDKだと思った?
残念Androidでした
コミットログ
https://android.googlesource.com/platform/libcore/+/b10b2a3ab693cfd6156d06ffe4e00ce69b9c9194
細かい補足
Android N より前はHarmonyを使っているって聞いたけど?
はい、その通りです。
でも実はAndroidのJavaはApache Harmonyからさらに変更を加えています
そのため、今回紹介したArrayListの操作では
Apache Harmony != Android Java
となります。
Apache Harmonyだと思った?
残念Androidでした
コミットログ
https://android.googlesource.com/platform/libcore/+/7de2d41b95fc968b0ccc530c28d66f003ff9ab2a
細かい補足
なんでこんな違いが生まれたの?
コミットコメントやソースコードのコメントを読んでみると
Android側は意図して修正しています。
Open JDKのhasNext()はlistのsizeに依存して
false返したりtrue返したりするので、固定させるために修正したみたいです。
コミットログ
https://android.googlesource.com/platform/libcore/+/b10b2a3ab693cfd6156d06ffe4e00ce69b9c9194
ソースコードのコメント
https://android.googlesource.com/platform/libcore/+/master/ojluni/src/main/java/java/util/ArrayList.jav
a#841
ご静聴ありがとうございました。

More Related Content

What's hot

Terraformで始めるInfrastructure as Code
Terraformで始めるInfrastructure as CodeTerraformで始めるInfrastructure as Code
Terraformで始めるInfrastructure as Code
Takahisa Iwamoto
 
.NETのサポートポリシーのおさらい #csharptokyo
.NETのサポートポリシーのおさらい #csharptokyo.NETのサポートポリシーのおさらい #csharptokyo
.NETのサポートポリシーのおさらい #csharptokyo
Yuta Matsumura
 
IT企業のジャーマネ視点から Power Apps 導入など
IT企業のジャーマネ視点から Power Apps 導入などIT企業のジャーマネ視点から Power Apps 導入など
IT企業のジャーマネ視点から Power Apps 導入など
Teruchika Yamada
 
eBPFを用いたトレーシングについて
eBPFを用いたトレーシングについてeBPFを用いたトレーシングについて
eBPFを用いたトレーシングについて
さくらインターネット株式会社
 
UEFI時代のブートローダ
UEFI時代のブートローダUEFI時代のブートローダ
UEFI時代のブートローダ
Takuya ASADA
 
backlogsでもCI/CDする夢を見る
backlogsでもCI/CDする夢を見るbacklogsでもCI/CDする夢を見る
backlogsでもCI/CDする夢を見る
Takeru Maehara
 
第三回ありえる社内勉強会 「いわががのLombok」
第三回ありえる社内勉強会 「いわががのLombok」第三回ありえる社内勉強会 「いわががのLombok」
第三回ありえる社内勉強会 「いわががのLombok」yoshiaki iwanaga
 
Dockerイメージの理解とコンテナのライフサイクル
Dockerイメージの理解とコンテナのライフサイクルDockerイメージの理解とコンテナのライフサイクル
Dockerイメージの理解とコンテナのライフサイクル
Masahito Zembutsu
 
TRICK 2022 Results
TRICK 2022 ResultsTRICK 2022 Results
TRICK 2022 Results
mametter
 
ELFの動的リンク
ELFの動的リンクELFの動的リンク
ELFの動的リンク
7shi
 
仕事で使うF#
仕事で使うF#仕事で使うF#
仕事で使うF#
bleis tift
 
Docker実践入門
Docker実践入門Docker実践入門
Docker実践入門
hiro nemu
 
C++からWebRTC (DataChannel)を利用する
C++からWebRTC (DataChannel)を利用するC++からWebRTC (DataChannel)を利用する
C++からWebRTC (DataChannel)を利用する
祐司 伊藤
 
HTTP/2, QUIC入門
HTTP/2, QUIC入門HTTP/2, QUIC入門
HTTP/2, QUIC入門
shigeki_ohtsu
 
Java クライント実装におけるAPIスタイル頂上決戦! 野良REST vs GraphQL vs OData vs OpenAPI (Swagger)
Java クライント実装におけるAPIスタイル頂上決戦! 野良REST vs GraphQL vs OData vs OpenAPI (Swagger)Java クライント実装におけるAPIスタイル頂上決戦! 野良REST vs GraphQL vs OData vs OpenAPI (Swagger)
Java クライント実装におけるAPIスタイル頂上決戦! 野良REST vs GraphQL vs OData vs OpenAPI (Swagger)
Kazuya Sugimoto
 
Plan 9のお話
Plan 9のお話Plan 9のお話
Plan 9のお話
Ryousei Takano
 
initとプロセス再起動
initとプロセス再起動initとプロセス再起動
initとプロセス再起動Takashi Takizawa
 
545人のインフラを支えたNOCチーム!
545人のインフラを支えたNOCチーム!545人のインフラを支えたNOCチーム!
545人のインフラを支えたNOCチーム!
Masayuki Kobayashi
 
イケてない開発チームがイケてる開発を始めようとする軌跡
イケてない開発チームがイケてる開発を始めようとする軌跡イケてない開発チームがイケてる開発を始めようとする軌跡
イケてない開発チームがイケてる開発を始めようとする軌跡
NTT Communications Technology Development
 

What's hot (20)

initramfsについて
initramfsについてinitramfsについて
initramfsについて
 
Terraformで始めるInfrastructure as Code
Terraformで始めるInfrastructure as CodeTerraformで始めるInfrastructure as Code
Terraformで始めるInfrastructure as Code
 
.NETのサポートポリシーのおさらい #csharptokyo
.NETのサポートポリシーのおさらい #csharptokyo.NETのサポートポリシーのおさらい #csharptokyo
.NETのサポートポリシーのおさらい #csharptokyo
 
IT企業のジャーマネ視点から Power Apps 導入など
IT企業のジャーマネ視点から Power Apps 導入などIT企業のジャーマネ視点から Power Apps 導入など
IT企業のジャーマネ視点から Power Apps 導入など
 
eBPFを用いたトレーシングについて
eBPFを用いたトレーシングについてeBPFを用いたトレーシングについて
eBPFを用いたトレーシングについて
 
UEFI時代のブートローダ
UEFI時代のブートローダUEFI時代のブートローダ
UEFI時代のブートローダ
 
backlogsでもCI/CDする夢を見る
backlogsでもCI/CDする夢を見るbacklogsでもCI/CDする夢を見る
backlogsでもCI/CDする夢を見る
 
第三回ありえる社内勉強会 「いわががのLombok」
第三回ありえる社内勉強会 「いわががのLombok」第三回ありえる社内勉強会 「いわががのLombok」
第三回ありえる社内勉強会 「いわががのLombok」
 
Dockerイメージの理解とコンテナのライフサイクル
Dockerイメージの理解とコンテナのライフサイクルDockerイメージの理解とコンテナのライフサイクル
Dockerイメージの理解とコンテナのライフサイクル
 
TRICK 2022 Results
TRICK 2022 ResultsTRICK 2022 Results
TRICK 2022 Results
 
ELFの動的リンク
ELFの動的リンクELFの動的リンク
ELFの動的リンク
 
仕事で使うF#
仕事で使うF#仕事で使うF#
仕事で使うF#
 
Docker実践入門
Docker実践入門Docker実践入門
Docker実践入門
 
C++からWebRTC (DataChannel)を利用する
C++からWebRTC (DataChannel)を利用するC++からWebRTC (DataChannel)を利用する
C++からWebRTC (DataChannel)を利用する
 
HTTP/2, QUIC入門
HTTP/2, QUIC入門HTTP/2, QUIC入門
HTTP/2, QUIC入門
 
Java クライント実装におけるAPIスタイル頂上決戦! 野良REST vs GraphQL vs OData vs OpenAPI (Swagger)
Java クライント実装におけるAPIスタイル頂上決戦! 野良REST vs GraphQL vs OData vs OpenAPI (Swagger)Java クライント実装におけるAPIスタイル頂上決戦! 野良REST vs GraphQL vs OData vs OpenAPI (Swagger)
Java クライント実装におけるAPIスタイル頂上決戦! 野良REST vs GraphQL vs OData vs OpenAPI (Swagger)
 
Plan 9のお話
Plan 9のお話Plan 9のお話
Plan 9のお話
 
initとプロセス再起動
initとプロセス再起動initとプロセス再起動
initとプロセス再起動
 
545人のインフラを支えたNOCチーム!
545人のインフラを支えたNOCチーム!545人のインフラを支えたNOCチーム!
545人のインフラを支えたNOCチーム!
 
イケてない開発チームがイケてる開発を始めようとする軌跡
イケてない開発チームがイケてる開発を始めようとする軌跡イケてない開発チームがイケてる開発を始めようとする軌跡
イケてない開発チームがイケてる開発を始めようとする軌跡
 

More from JustSystems Corporation

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

More from JustSystems Corporation (20)

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

ピュアJavaだと思った?残念androidでした~いつからAndroidをJavaだと錯覚していた?~