SlideShare a Scribd company logo
JJaavvaa  PPuuzzzzlleerrss    
AAttttaacckk  ooff  tthhee  OObbjjeecctt##CClloonnee  

櫻庭 祐一  
寺田 佳央
コード中に発生する勘違い  
—  JJaavvaa  プログラミングのパズル  
—  奇妙な振る舞いをする小さなプログラム  
—  複数の選択肢から、何が表示される?  
—  ミステリーの解明  
—  問題の解決方法  
—  教訓
ルール:全て4択です  
public class JavaPuzzlers {

  public static void main(String... args) { "
     http://www.java-users.jp   "
     System.out.println(“Japan Java User Group Presents!”); } "
} "

11)) 
22)) 
33)) 
44)) 

JJaappaann  JJaavvaa  UUsseerrss  GGrroouupp  PPrreesseennttss!!  
JJaavvaa  PPuuzzzzlleerrss  
00xxccaaffeebbaabbee  
その他  

全員参加です
11  問目
1..  FFiinnddRRoooottss      
class Ancestor {"
String name = "祖先”;"
1)  祖先:祖先
String getName() {return name;}"
2)  ⼦子孫:⼦子孫
}"
3)  祖先:⼦子孫
class Descendant extends Ancestor {"
4)  ⼦子孫:祖先
String name = "子孫";"
@Override"
String getName() {return name;}"
}"
"
public class FindRoots {"
public static void main(String argv[]) {"
Ancestor person = new Descendant();"
System.out.println("
person.name + ":" + person.getName());"
}"
}"
正解は
1..  FFiinnddRRoooottss      
class Ancestor {"
String name = "祖先”;"
String getName() {return name;}"
}"
3)  祖先:⼦子孫
class Descendant extends Ancestor {"
String name = "子孫";"
@Override"
String getName() {return name;}"
}"
"
public class FindRoots {"
public static void main(String argv[]) {"
Ancestor person = new Descendant();"
System.out.println("
person.name + ":" + person.getName());"
}"
}"
11.解説  
—  フィールドはコンパイル時に親クラスの情報を引き継ぎます  
—  メソッドは実行時に上書きしたメソッドを呼び出します  
—  仮にどうしても子のフィールドにアクセスしたい場合、   
キャストして取得します
1..  解決方法  
class Ancestor {"
String name = "祖先”;"
String getName() {return name;}"
}"
3)  祖先:⼦子孫
class Descendant extends Ancestor {"
String name = "子孫";"
@Override"
String getName() {return name;}"
}"
"
public class FindRoots {"
public static void main(String argv[]) {"
Ancestor person = new Descendant();"
System.out.println("
((Descendant)person).name + ":" + person.getName());"
}"
}"
1.教訓  
  

—  フィールドは隠蔽し直接アクセスしないようにしてください
22  問目
22.MMaajjoorriittyyVVoottee  

11))  YYEESS  
22))  NNOO  
33))  場合による  
44))  tthhrrooww  EExxcceeppttiioonn  

public class MajorityVote {"
public static void main(String... args) {"
   Random[] randoms = new Random[10];"
    for (int i = 0; i < 10; i++)"
     randoms[i] = new Random(System.currentTimeMillis());"
"
int count = 0;"
    boolean option = randoms[0].nextBoolean();"
    for (int i = 1; i < 10; i++)"
      if (option == randoms[i].nextBoolean()) count++;"
"
    System.out.println((count > 5)? "YES": "NO");"
  }"
}"
正解は
22.MMaajjoorriittyyVVoottee  

11))  YYEESS  

public class MajorityVote {"
public static void main(String... args) {"
   Random[] randoms = new Random[10];"
    for (int i = 0; i < 10; i++)"
     randoms[i] = new Random(System.currentTimeMillis());"
"
int count = 0;"
    boolean option = randoms[0].nextBoolean();"
    for (int i = 1; i < 10; i++)"
      if (option == randoms[i].nextBoolean()) count++;"
"
    System.out.println((count > 5)? "YES": "NO");"
  }"
}"
22.解説  
—  RRaannddoommのコンストラクタは、乱数シードを指定します  
—  ループは11  ミリ秒の間に処理が完了します  
→  乱数シードが全て同一となります  

—  デフォルトコンスタクタはSSyysstteemm..nnaannooTTiimmee(())を使用  
します
22..  解決方法  
public class MajorityVote {"
public static void main(String... args) {"
   Random[] randoms = new Random[10];"
    for (int i = 0; i < 10; i++)"
     randoms[i] = new Random();"
"
int count = 0;"
    boolean option = randoms[0].nextBoolean();"
    for (int i = 1; i < 10; i++)"
      if (option == randoms[i].nextBoolean()) count++;"
"
    System.out.println((count > 5)? "YES": "NO");"
  }"
}"
22.教訓  
  

—  デフォルトのコンストラクタを使用してください  
  

—  テスト時など乱数系列をあえて同一にするテクニックもあり
ます
33  問目
33.CCuuttAAnnddPPaassttee  

11))  112233  
22))  112233445566  
public class CutAndPaste{

33))  コンパイル・エラー  
public static void main(String... argv) {"
44))  ランタイム・エラー  
  

String firstLine = "1,2,3";

  String secondLine = "4,5,6";

   List<String> firstList = "
 

Arrays.asList(firstLine.split(”,"));

List<String> secondList = "

Arrays.asList(secondLine.split(”,"));

   firstList.addAll(secondList);

   for(String data : firstList){

 
System.out.print(data);

   }

  }

}"
正解は
33.CCuuttAAnnddPPaassttee  

  
  
public class CutAndPaste {

  
public static void main(String argv[]){"
44))  ランタイム・エラー  
   String firstLine = "1,2,3";

  String secondLine = "4,5,6";

   List<String> firstList = "
"Arrays.asList(firstLine.split(","));

 
List<String> secondList ="
"Arrays.asList(secondLine.split(","));

   firstList.addAll(secondList);

   for(String data : firstList){

 
System.out.print(data);

   }

  }

}"

UUnnssuuppppoorrtteeddOOppeerraattiioonnEExxcceeppttiioonn  を送出
33..  解説  
—  AArrrraayyss..aassLLiisstt  は固定サイズのリストを生成します  
—  aassLLiisstt(())で取得したリストに対して,,  aadddd,,  aaddddAAllll  等は    
実行できません
33..  解決方法  
public class CutAndPaste {

public static void main(String argv[]) {"
  

String firstLine = "1,2,3";

  String secondLine = "4,5,6";

   List<String> firstList = new ArrayList<>("
 

Arrays.asList(firstLine.split(",")));

List<String> secondList = "

Arrays.asList(secondLine.split(","));

   firstList.addAll(secondList);

   for(String data : firstList){

 
System.out.print(data);

   }

  }

}"

固定サイズのリストから、新たな可変リストを生成
33..  教訓  
—  可変のリストを作成したい場合は、固定サイズのリストより
新たな可変リストのコピーを生成します
4  問目
44..  WWaallttzzRRhhyytthhmm  
public class WaltzRhythm {"
public static void main(String... args) {"
int count = 0;"
for (int i = 0; i < Integer.MAX_VALUE; i += 3) {"
count++;"
}"
System.out.println(count);"
}"
}"
11))  771155882277888822  ((==  IInntteeggeerr..MMAAXX__VVAALLUUEE//33))  
22))  771155882277888833  ((==  IInntteeggeerr..MMAAXX__VVAALLUUEE//33  ++  11))  
33))  無限ループ  
44))  それ以外
正解は
44..  WWaallttzzRRhhyytthhmm  
public class WaltzRhythm {"
public static void main(String... args) {"
int count = 0;"
for (int i = 0; i < Integer.MAX_VALUE; i += 3) {"
count++;"
}"
System.out.println(count);"
}"
}"

44))  それ以外  ((--771155882277888833))
44..  解説  
—  IInntteeggeerr..MMAAXX__VVAALLUUEE  ==  22114477448833664477  
—  ffoorr  ((iinntt  ii  ==  00;;  ii  <<  IInntteeggeerr..MMAAXX__VVAALLUUEE  ;;  ii  ++==  33))  {{  
—    

  ++33  インクリメントし  ccoouunntt  として771155882277888822を期待します  

counter	
 1	
 2	
 3	
 4	
 5	
 6	
 7	
0	
 3	
 6	
 9	
 12	
 15	
18	

i	

715827883	
・・・・・・・・・	
 2147483646	

—  CCoouunntteerr  がオーバフロー  
—  ffoorr  文の終了条件までIInntteeggeerr..MMIINN__VVAALLUUEE  -->>  IInntteeggeerr..MMAAXX__VVAALLUUEE  を繰り返し
ます
44..  解説  
ffoorr  ((iinntt  ii  ==  00;;  ii  <<  IInntteeggeerr..MMAAXX__VVAALLUUEE  ;;  ii  ++==  33))  
counter	
 1	
 2	
 3	
 4	
 5	
 6	
 7	
715827883	
i	

0	
 3	
 6	
 9	
 12	
 15	
18	

・・・・・・・・・	
 2147483646	
MAX_VALUE -1	

counter	
 715827884	
i	

715827885	

2147483642	
 2147483645	
-2147483647	
 -2147483647	
・・・・・・・・・	

MIN_VALUE +2	
counter	
 -2147483647	
 -2147483646	

i	

2147483647	
 -2147483648	

MAX_VALUE -2	
-715827884	
 -715827883	

2147483641	
 2147483644	
-2147483648	
 -2147483645	
・・・・・・・・・	
MIN_VALUE +1
44..  解決方法  
public class WaltzRhythm {"
public static void main(String... args) {"
int count = 0;"
for (int i = 0; i < Integer.MAX_VALUE -3 ; i += 3) {"
count++;"
}"
System.out.println(count);"
}"
}"
44..  教訓  
—  bbyyttee,,  cchhaarr,,  iinntt  ,,  lloonngg  ((プリミティブ型))  を扱う場合、  
桁のオーバフローを考慮した実装が必要です  

—  オーバフローを引き起こさないために  BBiiggIInntteeggeerr  を使う方
法もあります
5  問目
55..  UUppppeerrLLoowweerrMMaattcchh  
public class UpperLowerMatch {"
public static void main(String argv[]){"
Integer a1 = 10; Integer a2 = 129;"
int b1 = 10; int b2 = 129;"
Integer c1 = 10; Integer c2 = 129;"
"
System.out.print((a1==b1));"
System.out.print("t”+(a1==c1));"
"
System.out.print("t”+(a2==b2));"
System.out.println("t”+(a2==c2));" 11))  ttrruuee  ttrruuee  ttrruuee  ttrruuee  
}"
22))  ffaallssee  ttrruuee  ffaallssee  ttrruuee  

33))  ttrruuee  ffaallssee  ttrruuee  ffaallssee  
44))  ttrruuee  ttrruuee  ttrruuee  ffaallssee
正解は
55..  UUppppeerrLLoowweerrMMaattcchh  
public class UpperLowerMatch {"
public static void main(String argv[]){"
Integer a1 = 10; Integer a2 = 129;"
int b1 = 10; int b2 = 129;"
Integer c1 = 10; Integer c2 = 129;"
"
System.out.print((a1==b1));"
System.out.print("t”+(a1==c1));"
"
System.out.print("t”+(a2==b2));"
System.out.println("t”+(a2==c2));"   
}"
  

  
44))  ttrruuee  ttrruuee  ttrruuee  ffaallssee
55..  解説  
—  AAuuttooBBooxxiinngg    
—  プリミティブとオブジェクトの比較は、プリミティブで計算し比較  
—  オブジェクトとオブジェクトの比較は、オブジェクトの参照で比較  

—  JJaavvaa..llaanngg..IInntteeggeerr  は--112288  から  112277  の値の範囲でオブ
ジェクト  IIDDの値をキャッシュしており、その比較を実施し
ます  
—  つまり値が  --112288  から  112277  の範囲か否かで結果が異なります  
Cache to support the object identity semantics of
autoboxing for values between -128 and 127 (inclusive)
as required by JLS. "
キャッシュ範囲は -XX:AutoBoxCacheMax で変更可能"
55..  解決方法  
public class UpperLowerMatch {"
public static void main(String argv[]){"
Integer a1 = 10; Integer a2 = 129;"
int b1 = 10; int b2 = 129;"
Integer c1 = 10; Integer c2 = 129;"
"
System.out.print((a1==b1));"
System.out.print("t” + (a1.intValue()==c1.intValue()));"
"
System.out.print("t” +  (a2==b2));"
System.out.println((a2.intValue()==c2.intValue()));"
}"
55..  教訓  

—  オートボクシングを使え便利になっていますが、      
比較においては、pprriimmiittiivvee  と  OObbjjeecctt  の比較は     
十分に注意してください  

—  IInntteeggeerr  の比較を行う際には  iinnttVVaalluuee(())  での比較をお薦め
します
6  問目
66..  WWrraappWWrraappWWrraapp

11)) 
22)) 
33)) 
44)) 

66  
112233  
CCoommppiillee  EErrrroorr  
tthhrrooww  EExxcceeppttiioonn  

public class WrapWrapWrap<T> {"
String wrap(Collection<?> objs) {"
String result = "";"
for (Object o: objs) result += o;"
return result;"
}
"
int wrap(List<Integer> numbers) {"
int result = 0;"
for (int num: numbers) result += num;"
return result;"
}
"
public static void main(String... args) {"
List<String> strings = Arrays.asList("1", "2", "3");"
System.out.println(new WrapWrapWrap().wrap(strings));"
}"
}"
正解は
66..  WWrraappWWrraappWWrraapp
public class WrapWrapWrap<T> {"
String wrap(Collection<?> objs) {"
44))  tthhrrooww  EExxcceeppttiioonn  
String result = "";"
for (Object o: objs) result += o;"
return result;"
}
"
int wrap(List<Integer> numbers) {"
int result = 0;"
for (int num: numbers) result += num;"
return result;"
}
"
public static void main(String... args) {"
List<String> strings = Arrays.asList("1", "2", "3");"
System.out.println(new WrapWrapWrap().wrap(strings));"
}"
}"
66..  解説  
—  ジェネリクスを指定しない場合、RRaaww  型といいます  
—  RRaaww  型の場合、ジェネリクスの型情報が消失します  
つまり以下のクラスと同様になります  

  
  
  

public class WrapWrapWrap {"
String wrap(Collection objs) {...}
int wrap(List numbers) {...}
"
..."
}"
	

"

—  そのため、SSttrriinngg  のリストでも、iinntt  wwrraapp((LLiisstt  nnuummbbeerrss))が   
実行され、実行時にCCllaassssCCaassttEExxcceeppttiioonnが発生します
66..  解決方法
public class WrapWrapWrap<T> {"
String wrap(Collection<?> objs) {"
String result = "";"
for (Object o: objs) result += o;"
return result;"
}"
int wrap(List<Integer> numbers) {"
int result = 0;"
for (int num: numbers) result += num;"
return result;"
}"
public static void main(String... args) {"
List<String> strings = Arrays.asList("1", "2", "3");"
System.out.println(new WrapWrapWrap<String>().wrap(strings));"
}"
}"
66..  教訓  
—  ジェネリクスのパラメータは正しく指定しましょう  
—  JJaavvaa  SSEE  77  からはダイヤモンド演算子が利用可能です
7  問目
77..  LLoossttAAnnddFFoouunndd    

JJaavvaa  SSEE  6で実行  

public class LostAndFound {"
static int getArticles(List<String> list) { return 100; }"
static long getArticles(List<Integer> list) { return 200; }"
public static void main(String argv[]){"
List<String> listStr = new ArrayList<String>();"
List<Integer> listInt = new ArrayList<Integer>();"
System.out.println(getArticles(listStr));"
System.out.println(getArticles(listInt));"
}"
}"
1)  100  ,  200

2)  200  ,  100
3)  コンパイルエラー
4)  ランタイムエラー
正解は
77..  LLoossttAAnnddFFoouunndd    

JJaavvaa  SSEE  6で実行  

public class LostAndFound {"
static int getArticles(List<String> list){ return 100;}"
static long getArticles(List<Integer> list) { return 200; }"
public static void main(String argv[]){"
List<String> listStr = new ArrayList<String>();"
List<Integer> listInt = new ArrayList<Integer>();"
System.out.println(getArticles(listStr));"
System.out.println(getArticles(listInt));"
}"
}"

4)  ランタイムエラー
77..  解説  
—  TTyyppee  EErraassuurree  ::    
—  ジェネリクスはコンパイル時に解決され、コンパイル後型情報
は消えます。そのためこれをイレイジャ方式と呼びます  

—  JJDDKK  55,,  66  では、同じイレイジャ・シグネチャを持つ、異な
る返り値を持つメソッドの定義が可能でしたが、これは間違
いで、JJDDKK  77  で修正されました。((RRFFEE  ::  66118822995500))
77..  解決策  

JJaavvaa  SSEE  77で実行  

public class LostAndFound {"
static int getArticles(List<String> list) { return 100; }"
static long getArticles(List<Integer> list) { return 200; }"
public static void main(String argv[]){"
List<String> listStr = new ArrayList<>();"
List<Integer> listInt = new ArrayList<>();"
System.out.println(getArticles(listStr));"
System.out.println(getArticles(listInt));"
}"
}"
77..  教訓  
—  JJaavvaa  SSEE  77  へ移行してください  ((コンパイルエラー))  
LostAndFound.java:8: エラー: 名前が競合しています。
getArticles(List<Integer>)とgetArticles(List<String>)は削除後の名前が
同じです	
static long getArticles(List<Integer> list) { return 200; }"
^"
エラー1個	

—  JJaavvaa  のバージョン・アップ時には  JJaavvaa  の互換性・非互換
性情報も必ずご確認ください  
http://www.oracle.com/technetwork/java/javase/
compatibility-417013.html#incompatibilities
JJaavvaa  PPuuzzzzlleerrss    
AAttttaacckk  ooff  tthhee  OObbjjeecctt##CClloonnee  

櫻庭 祐一  
寺田 佳央

More Related Content

PPTX
Java Puzzlers JJUG CCC 2016
PDF
Java SE 8 lambdaで変わる プログラミングスタイル
PDF
Xtend - Javaの未来を今すぐ使う
PDF
Metaprogramming in JuliaLang
PPTX
Junit4
PDF
講座Java入門
PDF
Javaセキュアコーディングセミナー東京第1回演習の解説
PPTX
【java8 勉強会】 怖くない!ラムダ式, Stream API
Java Puzzlers JJUG CCC 2016
Java SE 8 lambdaで変わる プログラミングスタイル
Xtend - Javaの未来を今すぐ使う
Metaprogramming in JuliaLang
Junit4
講座Java入門
Javaセキュアコーディングセミナー東京第1回演習の解説
【java8 勉強会】 怖くない!ラムダ式, Stream API

What's hot (20)

PPTX
C# 式木 (Expression Tree) ~ LINQをより深く理解するために ~
PDF
Shibuya JVM Groovy 20150418
PDF
C# ドキドキ ライブ コーディング!! ~ 小島の分 ~ | BuriKaigi 2020
PPTX
Visual C++で使えるC++11
PDF
Java SE 7 InvokeDynamic in JRuby
PPTX
C# LINQ ~深く知って、使いまくろう~
PDF
Async design with Unity3D
PDF
Xtend30分クッキング
PDF
Xtend30分クッキング やきに駆動
PDF
Juliaで並列計算
PDF
C++14 Overview
PDF
Bluespec @waseda(PDF)
PPTX
非同期処理の基礎
PDF
C++ マルチスレッドプログラミング
PPTX
An other world awaits you
PDF
unique_ptrにポインタ以外のものを持たせるとき
PPTX
C#6.0の新機能紹介
PDF
Java x Groovy: improve your java development life
KEY
Clojure programming-chapter-2
PDF
LINQソースでGO!
C# 式木 (Expression Tree) ~ LINQをより深く理解するために ~
Shibuya JVM Groovy 20150418
C# ドキドキ ライブ コーディング!! ~ 小島の分 ~ | BuriKaigi 2020
Visual C++で使えるC++11
Java SE 7 InvokeDynamic in JRuby
C# LINQ ~深く知って、使いまくろう~
Async design with Unity3D
Xtend30分クッキング
Xtend30分クッキング やきに駆動
Juliaで並列計算
C++14 Overview
Bluespec @waseda(PDF)
非同期処理の基礎
C++ マルチスレッドプログラミング
An other world awaits you
unique_ptrにポインタ以外のものを持たせるとき
C#6.0の新機能紹介
Java x Groovy: improve your java development life
Clojure programming-chapter-2
LINQソースでGO!
Ad

Viewers also liked (10)

PDF
【18-C-2】オラクル統合後の Java の今後について
PPTX
Microsoft Love Java & OSS
PDF
Grizzly1.9.3x
PDF
おまえらこのライブラリ使ってないの? m9 (2013-07)
PDF
オープンデータ動向 2013年8月
PDF
じっくりコトコト煮込んだJavaスープ
PDF
5分で作るMySQL Cluster環境
PPTX
Hadoop and Storm - AJUG talk
PPTX
Java EE 7 multi factor authentiaction with Microsoft Azure AD
PPTX
ChordアルゴリズムによるDHT入門
【18-C-2】オラクル統合後の Java の今後について
Microsoft Love Java & OSS
Grizzly1.9.3x
おまえらこのライブラリ使ってないの? m9 (2013-07)
オープンデータ動向 2013年8月
じっくりコトコト煮込んだJavaスープ
5分で作るMySQL Cluster環境
Hadoop and Storm - AJUG talk
Java EE 7 multi factor authentiaction with Microsoft Azure AD
ChordアルゴリズムによるDHT入門
Ad

Similar to Java puzzlers 2013 at JavaFesta Japan (20)

PPTX
PPTX
Meeting5
PDF
Javaプログラミング入門
PPTX
Apg4b 2.0.1 2重for文のコード解説
PDF
たのしい関数型
PDF
Javaセキュアコーディングセミナー東京第2回演習の解説
PDF
人工無脳バトル 1st STEP 回答と解説
PDF
プログラミングコンテストでの乱択アルゴリズム
PDF
Javaセキュアコーディングセミナー東京第4回講義
PDF
Javaセキュアコーディングセミナー東京第2回演習
PPTX
Meeting10
PDF
20150302 java8 第一回_ラムダ式(1)
PDF
実践・最強最速のアルゴリズム勉強会 第二回講義資料(ワークスアプリケーションズ & AtCoder)
PPTX
ジェネリックプログラミング入門
PDF
(R1-1) いまさら Coin, されど Coin @ JJUG CCC 2012 Fall
PDF
F#入門 ~関数プログラミングとは何か~
PPTX
Javaプログラミング入門【第3回】
PDF
Java勉強会2017.3.17
Meeting5
Javaプログラミング入門
Apg4b 2.0.1 2重for文のコード解説
たのしい関数型
Javaセキュアコーディングセミナー東京第2回演習の解説
人工無脳バトル 1st STEP 回答と解説
プログラミングコンテストでの乱択アルゴリズム
Javaセキュアコーディングセミナー東京第4回講義
Javaセキュアコーディングセミナー東京第2回演習
Meeting10
20150302 java8 第一回_ラムダ式(1)
実践・最強最速のアルゴリズム勉強会 第二回講義資料(ワークスアプリケーションズ & AtCoder)
ジェネリックプログラミング入門
(R1-1) いまさら Coin, されど Coin @ JJUG CCC 2012 Fall
F#入門 ~関数プログラミングとは何か~
Javaプログラミング入門【第3回】
Java勉強会2017.3.17

More from Yoshio Terada (20)

PDF
Azure OpenAI と LangChain4j を使用した LLM Java エンタープライズ・アプリケーションの 構築方法の紹介
PDF
Introduction of Azure Container Apps for Java Developers
PDF
AI-Java-for-Financial.pdf
PDF
Java-Virtual-Thread-LT.pdf
PPTX
Cloud Native Architecture ことはじめ 最適な実行環境を選ぶポイント
PPTX
Jakarta EE Microproile Update JJUG 2020 May
PPTX
Azure RedHat OpenShift - Red Hat Forum 2019
PPTX
JakartaOne 2020 Japan Announce
PPTX
Jjug CCC 2019 Fall Azure Spring Cloud
PPTX
Sapporo Developer Festa 2019
PPTX
AKS (k8s) Hands on Lab Contents
PPTX
Java on Azure 2019
PPTX
Java on Azure 2019
PPTX
Oisix ra Daichi Microservice with Kubernetes
PPTX
Virtual Kubelet and Virtual Node
PPTX
Japan Container Day 2018
PPTX
Java on Kubernetes on Azure
PPTX
The Experience of Java on Kubernetes with Microservices from HackFest
PPTX
Application Development Vision
PPTX
How to face the Kubernetes ?
Azure OpenAI と LangChain4j を使用した LLM Java エンタープライズ・アプリケーションの 構築方法の紹介
Introduction of Azure Container Apps for Java Developers
AI-Java-for-Financial.pdf
Java-Virtual-Thread-LT.pdf
Cloud Native Architecture ことはじめ 最適な実行環境を選ぶポイント
Jakarta EE Microproile Update JJUG 2020 May
Azure RedHat OpenShift - Red Hat Forum 2019
JakartaOne 2020 Japan Announce
Jjug CCC 2019 Fall Azure Spring Cloud
Sapporo Developer Festa 2019
AKS (k8s) Hands on Lab Contents
Java on Azure 2019
Java on Azure 2019
Oisix ra Daichi Microservice with Kubernetes
Virtual Kubelet and Virtual Node
Japan Container Day 2018
Java on Kubernetes on Azure
The Experience of Java on Kubernetes with Microservices from HackFest
Application Development Vision
How to face the Kubernetes ?

Java puzzlers 2013 at JavaFesta Japan

  • 1. JJaavvaa PPuuzzzzlleerrss AAttttaacckk ooff tthhee OObbjjeecctt##CClloonnee 櫻庭 祐一 寺田 佳央
  • 2. コード中に発生する勘違い —  JJaavvaa プログラミングのパズル —  奇妙な振る舞いをする小さなプログラム —  複数の選択肢から、何が表示される? —  ミステリーの解明 —  問題の解決方法 —  教訓
  • 3. ルール:全て4択です public class JavaPuzzlers {
   public static void main(String... args) { "     http://www.java-users.jp   "     System.out.println(“Japan Java User Group Presents!”); } " } " 11))  22))  33))  44))  JJaappaann JJaavvaa UUsseerrss GGrroouupp PPrreesseennttss!! JJaavvaa PPuuzzzzlleerrss 00xxccaaffeebbaabbee その他 全員参加です
  • 5. 1.. FFiinnddRRoooottss class Ancestor {" String name = "祖先”;" 1)  祖先:祖先 String getName() {return name;}" 2)  ⼦子孫:⼦子孫 }" 3)  祖先:⼦子孫 class Descendant extends Ancestor {" 4)  ⼦子孫:祖先 String name = "子孫";" @Override" String getName() {return name;}" }" " public class FindRoots {" public static void main(String argv[]) {" Ancestor person = new Descendant();" System.out.println(" person.name + ":" + person.getName());" }" }"
  • 7. 1.. FFiinnddRRoooottss class Ancestor {" String name = "祖先”;" String getName() {return name;}" }" 3)  祖先:⼦子孫 class Descendant extends Ancestor {" String name = "子孫";" @Override" String getName() {return name;}" }" " public class FindRoots {" public static void main(String argv[]) {" Ancestor person = new Descendant();" System.out.println(" person.name + ":" + person.getName());" }" }"
  • 8. 11.解説 —  フィールドはコンパイル時に親クラスの情報を引き継ぎます —  メソッドは実行時に上書きしたメソッドを呼び出します —  仮にどうしても子のフィールドにアクセスしたい場合、    キャストして取得します
  • 9. 1.. 解決方法 class Ancestor {" String name = "祖先”;" String getName() {return name;}" }" 3)  祖先:⼦子孫 class Descendant extends Ancestor {" String name = "子孫";" @Override" String getName() {return name;}" }" " public class FindRoots {" public static void main(String argv[]) {" Ancestor person = new Descendant();" System.out.println(" ((Descendant)person).name + ":" + person.getName());" }" }"
  • 10. 1.教訓 —  フィールドは隠蔽し直接アクセスしないようにしてください
  • 12. 22.MMaajjoorriittyyVVoottee 11))  YYEESS 22))  NNOO 33)) 場合による 44)) tthhrrooww EExxcceeppttiioonn public class MajorityVote {" public static void main(String... args) {"    Random[] randoms = new Random[10];"     for (int i = 0; i < 10; i++)"      randoms[i] = new Random(System.currentTimeMillis());" " int count = 0;"     boolean option = randoms[0].nextBoolean();"     for (int i = 1; i < 10; i++)"       if (option == randoms[i].nextBoolean()) count++;" "     System.out.println((count > 5)? "YES": "NO");"   }" }"
  • 14. 22.MMaajjoorriittyyVVoottee 11))  YYEESS public class MajorityVote {" public static void main(String... args) {"    Random[] randoms = new Random[10];"     for (int i = 0; i < 10; i++)"      randoms[i] = new Random(System.currentTimeMillis());" " int count = 0;"     boolean option = randoms[0].nextBoolean();"     for (int i = 1; i < 10; i++)"       if (option == randoms[i].nextBoolean()) count++;" "     System.out.println((count > 5)? "YES": "NO");"   }" }"
  • 15. 22.解説 —  RRaannddoommのコンストラクタは、乱数シードを指定します —  ループは11 ミリ秒の間に処理が完了します → 乱数シードが全て同一となります —  デフォルトコンスタクタはSSyysstteemm..nnaannooTTiimmee(())を使用   します
  • 16. 22.. 解決方法 public class MajorityVote {" public static void main(String... args) {"    Random[] randoms = new Random[10];"     for (int i = 0; i < 10; i++)"      randoms[i] = new Random();" " int count = 0;"     boolean option = randoms[0].nextBoolean();"     for (int i = 1; i < 10; i++)"       if (option == randoms[i].nextBoolean()) count++;" "     System.out.println((count > 5)? "YES": "NO");"   }" }"
  • 17. 22.教訓 —  デフォルトのコンストラクタを使用してください —  テスト時など乱数系列をあえて同一にするテクニックもあり ます
  • 19. 33.CCuuttAAnnddPPaassttee 11)) 112233 22)) 112233445566 public class CutAndPaste{
 33)) コンパイル・エラー public static void main(String... argv) {" 44)) ランタイム・エラー    String firstLine = "1,2,3";
   String secondLine = "4,5,6";
    List<String> firstList = "   Arrays.asList(firstLine.split(”,"));
 List<String> secondList = " Arrays.asList(secondLine.split(”,"));
    firstList.addAll(secondList);
    for(String data : firstList){
   System.out.print(data);
    }
   }
 }"
  • 21. 33.CCuuttAAnnddPPaassttee public class CutAndPaste {
 public static void main(String argv[]){" 44)) ランタイム・エラー    String firstLine = "1,2,3";
   String secondLine = "4,5,6";
    List<String> firstList = " "Arrays.asList(firstLine.split(","));
   List<String> secondList =" "Arrays.asList(secondLine.split(","));
    firstList.addAll(secondList);
    for(String data : firstList){
   System.out.print(data);
    }
   }
 }" UUnnssuuppppoorrtteeddOOppeerraattiioonnEExxcceeppttiioonn を送出
  • 22. 33.. 解説 —  AArrrraayyss..aassLLiisstt は固定サイズのリストを生成します —  aassLLiisstt(())で取得したリストに対して,, aadddd,, aaddddAAllll 等は     実行できません
  • 23. 33.. 解決方法 public class CutAndPaste {
 public static void main(String argv[]) {"    String firstLine = "1,2,3";
   String secondLine = "4,5,6";
    List<String> firstList = new ArrayList<>("   Arrays.asList(firstLine.split(",")));
 List<String> secondList = " Arrays.asList(secondLine.split(","));
    firstList.addAll(secondList);
    for(String data : firstList){
   System.out.print(data);
    }
   }
 }" 固定サイズのリストから、新たな可変リストを生成
  • 24. 33.. 教訓 —  可変のリストを作成したい場合は、固定サイズのリストより 新たな可変リストのコピーを生成します
  • 26. 44.. WWaallttzzRRhhyytthhmm public class WaltzRhythm {" public static void main(String... args) {" int count = 0;" for (int i = 0; i < Integer.MAX_VALUE; i += 3) {" count++;" }" System.out.println(count);" }" }" 11)) 771155882277888822 ((== IInntteeggeerr..MMAAXX__VVAALLUUEE//33)) 22)) 771155882277888833 ((== IInntteeggeerr..MMAAXX__VVAALLUUEE//33 ++ 11)) 33)) 無限ループ 44)) それ以外
  • 28. 44.. WWaallttzzRRhhyytthhmm public class WaltzRhythm {" public static void main(String... args) {" int count = 0;" for (int i = 0; i < Integer.MAX_VALUE; i += 3) {" count++;" }" System.out.println(count);" }" }" 44)) それ以外 ((--771155882277888833))
  • 29. 44.. 解説 —  IInntteeggeerr..MMAAXX__VVAALLUUEE == 22114477448833664477 —  ffoorr ((iinntt ii == 00;; ii << IInntteeggeerr..MMAAXX__VVAALLUUEE ;; ii ++== 33)) {{ —  ++33 インクリメントし ccoouunntt として771155882277888822を期待します counter 1 2 3 4 5 6 7 0 3 6 9 12 15 18 i 715827883 ・・・・・・・・・ 2147483646 —  CCoouunntteerr がオーバフロー —  ffoorr 文の終了条件までIInntteeggeerr..MMIINN__VVAALLUUEE -->> IInntteeggeerr..MMAAXX__VVAALLUUEE を繰り返し ます
  • 30. 44.. 解説 ffoorr ((iinntt ii == 00;; ii << IInntteeggeerr..MMAAXX__VVAALLUUEE ;; ii ++== 33)) counter 1 2 3 4 5 6 7 715827883 i 0 3 6 9 12 15 18 ・・・・・・・・・ 2147483646 MAX_VALUE -1 counter 715827884 i 715827885 2147483642 2147483645 -2147483647 -2147483647 ・・・・・・・・・ MIN_VALUE +2 counter -2147483647 -2147483646 i 2147483647 -2147483648 MAX_VALUE -2 -715827884 -715827883 2147483641 2147483644 -2147483648 -2147483645 ・・・・・・・・・ MIN_VALUE +1
  • 31. 44.. 解決方法 public class WaltzRhythm {" public static void main(String... args) {" int count = 0;" for (int i = 0; i < Integer.MAX_VALUE -3 ; i += 3) {" count++;" }" System.out.println(count);" }" }"
  • 32. 44.. 教訓 —  bbyyttee,, cchhaarr,, iinntt ,, lloonngg ((プリミティブ型)) を扱う場合、   桁のオーバフローを考慮した実装が必要です —  オーバフローを引き起こさないために BBiiggIInntteeggeerr を使う方 法もあります
  • 34. 55.. UUppppeerrLLoowweerrMMaattcchh public class UpperLowerMatch {" public static void main(String argv[]){" Integer a1 = 10; Integer a2 = 129;" int b1 = 10; int b2 = 129;" Integer c1 = 10; Integer c2 = 129;" " System.out.print((a1==b1));" System.out.print("t”+(a1==c1));" " System.out.print("t”+(a2==b2));" System.out.println("t”+(a2==c2));" 11)) ttrruuee ttrruuee ttrruuee ttrruuee }" 22)) ffaallssee ttrruuee ffaallssee ttrruuee 33)) ttrruuee ffaallssee ttrruuee ffaallssee 44)) ttrruuee ttrruuee ttrruuee ffaallssee
  • 36. 55.. UUppppeerrLLoowweerrMMaattcchh public class UpperLowerMatch {" public static void main(String argv[]){" Integer a1 = 10; Integer a2 = 129;" int b1 = 10; int b2 = 129;" Integer c1 = 10; Integer c2 = 129;" " System.out.print((a1==b1));" System.out.print("t”+(a1==c1));" " System.out.print("t”+(a2==b2));" System.out.println("t”+(a2==c2));" }" 44)) ttrruuee ttrruuee ttrruuee ffaallssee
  • 37. 55.. 解説 —  AAuuttooBBooxxiinngg —  プリミティブとオブジェクトの比較は、プリミティブで計算し比較 —  オブジェクトとオブジェクトの比較は、オブジェクトの参照で比較 —  JJaavvaa..llaanngg..IInntteeggeerr は--112288 から 112277 の値の範囲でオブ ジェクト IIDDの値をキャッシュしており、その比較を実施し ます —  つまり値が --112288 から 112277 の範囲か否かで結果が異なります Cache to support the object identity semantics of autoboxing for values between -128 and 127 (inclusive) as required by JLS. " キャッシュ範囲は -XX:AutoBoxCacheMax で変更可能"
  • 38. 55.. 解決方法 public class UpperLowerMatch {" public static void main(String argv[]){" Integer a1 = 10; Integer a2 = 129;" int b1 = 10; int b2 = 129;" Integer c1 = 10; Integer c2 = 129;" " System.out.print((a1==b1));" System.out.print("t” + (a1.intValue()==c1.intValue()));" " System.out.print("t” + (a2==b2));" System.out.println((a2.intValue()==c2.intValue()));" }"
  • 39. 55.. 教訓 —  オートボクシングを使え便利になっていますが、       比較においては、pprriimmiittiivvee と OObbjjeecctt の比較は      十分に注意してください —  IInntteeggeerr の比較を行う際には iinnttVVaalluuee(()) での比較をお薦め します
  • 41. 66.. WWrraappWWrraappWWrraapp 11))  22))  33))  44))  66 112233 CCoommppiillee EErrrroorr tthhrrooww EExxcceeppttiioonn public class WrapWrapWrap<T> {" String wrap(Collection<?> objs) {" String result = "";" for (Object o: objs) result += o;" return result;" } " int wrap(List<Integer> numbers) {" int result = 0;" for (int num: numbers) result += num;" return result;" } " public static void main(String... args) {" List<String> strings = Arrays.asList("1", "2", "3");" System.out.println(new WrapWrapWrap().wrap(strings));" }" }"
  • 43. 66.. WWrraappWWrraappWWrraapp public class WrapWrapWrap<T> {" String wrap(Collection<?> objs) {" 44)) tthhrrooww EExxcceeppttiioonn String result = "";" for (Object o: objs) result += o;" return result;" } " int wrap(List<Integer> numbers) {" int result = 0;" for (int num: numbers) result += num;" return result;" } " public static void main(String... args) {" List<String> strings = Arrays.asList("1", "2", "3");" System.out.println(new WrapWrapWrap().wrap(strings));" }" }"
  • 44. 66.. 解説 —  ジェネリクスを指定しない場合、RRaaww 型といいます —  RRaaww 型の場合、ジェネリクスの型情報が消失します つまり以下のクラスと同様になります public class WrapWrapWrap {" String wrap(Collection objs) {...} int wrap(List numbers) {...} " ..." }" " —  そのため、SSttrriinngg のリストでも、iinntt wwrraapp((LLiisstt nnuummbbeerrss))が    実行され、実行時にCCllaassssCCaassttEExxcceeppttiioonnが発生します
  • 45. 66.. 解決方法 public class WrapWrapWrap<T> {" String wrap(Collection<?> objs) {" String result = "";" for (Object o: objs) result += o;" return result;" }" int wrap(List<Integer> numbers) {" int result = 0;" for (int num: numbers) result += num;" return result;" }" public static void main(String... args) {" List<String> strings = Arrays.asList("1", "2", "3");" System.out.println(new WrapWrapWrap<String>().wrap(strings));" }" }"
  • 46. 66.. 教訓 —  ジェネリクスのパラメータは正しく指定しましょう —  JJaavvaa SSEE 77 からはダイヤモンド演算子が利用可能です
  • 48. 77.. LLoossttAAnnddFFoouunndd JJaavvaa SSEE 6で実行 public class LostAndFound {" static int getArticles(List<String> list) { return 100; }" static long getArticles(List<Integer> list) { return 200; }" public static void main(String argv[]){" List<String> listStr = new ArrayList<String>();" List<Integer> listInt = new ArrayList<Integer>();" System.out.println(getArticles(listStr));" System.out.println(getArticles(listInt));" }" }" 1)  100  ,  200 2)  200  ,  100 3)  コンパイルエラー 4)  ランタイムエラー
  • 50. 77.. LLoossttAAnnddFFoouunndd JJaavvaa SSEE 6で実行 public class LostAndFound {" static int getArticles(List<String> list){ return 100;}" static long getArticles(List<Integer> list) { return 200; }" public static void main(String argv[]){" List<String> listStr = new ArrayList<String>();" List<Integer> listInt = new ArrayList<Integer>();" System.out.println(getArticles(listStr));" System.out.println(getArticles(listInt));" }" }" 4)  ランタイムエラー
  • 51. 77.. 解説 —  TTyyppee EErraassuurree :: —  ジェネリクスはコンパイル時に解決され、コンパイル後型情報 は消えます。そのためこれをイレイジャ方式と呼びます —  JJDDKK 55,, 66 では、同じイレイジャ・シグネチャを持つ、異な る返り値を持つメソッドの定義が可能でしたが、これは間違 いで、JJDDKK 77 で修正されました。((RRFFEE :: 66118822995500))
  • 52. 77.. 解決策 JJaavvaa SSEE 77で実行 public class LostAndFound {" static int getArticles(List<String> list) { return 100; }" static long getArticles(List<Integer> list) { return 200; }" public static void main(String argv[]){" List<String> listStr = new ArrayList<>();" List<Integer> listInt = new ArrayList<>();" System.out.println(getArticles(listStr));" System.out.println(getArticles(listInt));" }" }"
  • 53. 77.. 教訓 —  JJaavvaa SSEE 77 へ移行してください ((コンパイルエラー)) LostAndFound.java:8: エラー: 名前が競合しています。 getArticles(List<Integer>)とgetArticles(List<String>)は削除後の名前が 同じです static long getArticles(List<Integer> list) { return 200; }" ^" エラー1個 —  JJaavvaa のバージョン・アップ時には JJaavvaa の互換性・非互換 性情報も必ずご確認ください http://www.oracle.com/technetwork/java/javase/ compatibility-417013.html#incompatibilities
  • 54. JJaavvaa PPuuzzzzlleerrss AAttttaacckk ooff tthhee OObbjjeecctt##CClloonnee 櫻庭 祐一 寺田 佳央