JDK7 Quiz …
(まずいお金の使い方)
木村英一(@kimuchi583)
2011/11/14 JavaOne 2011 報告会 at Tokyo 1
2.
Q1. 丈長をご希望ならLサイズを
classBinaryLiteral {
public static void main(String args[]) { 注) 表示の都合上の改行
double d1 = Double.longBitsToDouble(
0B0100_0000_0000_1001_0010_0001_1111_1011 ¥¥
_0101_0100_0100_0100_0010_1101_0001_1000);
System.out.format("d1 = %1$e¥n", d1);
}
} なお、0b0100_0000_0000 … 0001_0000 はπの浮動小数点表現ビットパターン
“javac BinaryLiteral.java; java BinaryLiteral” とすると …
① 3.141593e+00
② 0B01000 … 1000
③ 0x400921FB54442D18
④ その他
2011/11/14 JavaOne 2011 報告会 at Tokyo 2
3.
A1. ④ コンパイルエラー
① 3.141593e+00 ② 0B01000 … 1000 ③ 0x400921FB54442D18 ④ その他
class BinaryLiteral {
public static void main(String args[]) { 注) 表示の都合上の改行
double d1 = Double.longBitsToDouble(
0B0100_0000_0000_1001_0010_0001_1111_1011 ¥¥
_0101_0100_0100_0100_0010_1101_0001_1000); // 64bit !!
System.out.format("d1 = %1$e¥n", d1);
}
}
> javac BinaryLiteral.java
BinaryLiteral.java:4: エラー: 整数
01000000000010010010000111111011010101000100010000101101000110
00が大きすぎます
0b0100_0000_0000_1001_0010_0001_1111_1011_0101_0100_0100_0100_
0010_1101_0001_1000
^
エラー1個
2011/11/14 JavaOne 2011 報告会 at Tokyo 3
4.
A1. 修正案
0B0100_0000_0000_1001_0010_0001_1111_1011
_0101_0100_0100_0100_0010_1101_0001_1000 は
int 型では表現できない。long 型になる。
long 型であることを示す‘L’が必要。
Double.longBitsToDouble()の引数は long 型で問題なし。
class BinaryLiteral {
注) 表示の都合上の改行
public static void main(String args[]) {
double d1 = Double.longBitsToDouble(
0B0100_0000_0000_1001_0010_0001_1111_1011 ¥¥
_0101_0100_0100_0100_0010_1101_0001_1000 L);
System.out.format("d1 = %1$e¥n", d1);
}
}
① 3.141593e+00 ② 0B01000 … 1000 ③ 0x400921FB54442D18 ④ その他
2011/11/14 JavaOne 2011 報告会 at Tokyo 4
5.
Q2. この ASCIIアート は未完成
public class ZeroZeroSeven {
static int bond =
0000_____________0000________0000000000000000__000000000000000000+
00000000_________00000000______000000000000000__0000000000000000000+
000____000_______000____000_____000_______0000__00______0+
000______000_____000______000_____________0000___00______0+
0000______0000___0000______0000___________0000_____0_____0+
0000______0000___0000______0000__________0000___________0+
0000______0000___0000______0000_________000+__0000000000+
0000______0000___0000______0000________0000+
000______000_____000______000________0000+
000____000_______000____000_______00000+
00000000_________00000000_______0000000+
0000_____________0000________000000007;
public static void main(String args[]) {
System.out.format("%1$03o", bond);
}
}
このコード、コンパイルエラーとなります。その理由は ?
① _ が連続している ② 識別子が見つからない
③ 8進数11桁以上のリテラルに ‘L’ がない ④ その他
2011/11/14 JavaOne 2011 報告会 at Tokyo 5
6.
A2. ② 識別子が見つからない
① _ が連続している ② 識別子が見つからない
③ 8進数11桁以上のリテラルに ‘L’ がない ④ その他
public class ZeroZeroSeven {
static int bond =
0000_____________0000________0000000000000000__000000000000000000+
00000000_________00000000______000000000000000__0000000000000000000+
000____000_______000____000_____000_______0000__00______0+
000______000_____000______000_____________0000___00______0+
0000______0000___0000______0000___________0000_____0_____0+
0000______0000___0000______0000__________0000___________0+
0000______0000___0000______0000_________000+__0000000000+
0000______0000___0000______0000________0000+
000______000_____000______000________0000+
000____000_______000____000_______00000+
00000000_________00000000_______0000000+
>javac ZeroZeroSeven.java
0000_____________0000________000000007;
ZeroZeroSeven.java:9: エラー: シンボルを見つけられません
public static void main(String args[]) {
0000______0000___0000______0000_________000+__0000000000+
System.out.format("%1$03o", bond);
^
}
} シンボル: 変数 __0000000000
場所: クラス ZeroZeroSeven
エラー1個
2011/11/14 JavaOne 2011 報告会 at Tokyo 6
7.
A2. 修正案
“+” の直後の “__0000000000” はシンボルと解釈されるので、
“+” を “0” に書き換えるか、
“__0000000000” を “0 __0000000000” に書き換える。
public class ZeroZeroSeven {
static int bond =
0000_____________0000________0000000000000000__000000000000000000+
00000000_________00000000______000000000000000__0000000000000000000+
000____000_______000____000_____000_______0000__00______0+
000______000_____000______000_____________0000___00______0+
0000______0000___0000______0000___________0000_____0_____0+
0000______0000___0000______0000__________0000___________0+
0000______0000___0000______0000_________0000__0000000000+
0000______0000___0000______0000________0000+
000______000_____000______000________0000+
000____000_______000____000_______00000+
00000000_________00000000_______0000000+
0000_____________0000________000000007;
public static void main(String args[]) {
System.out.format("%1$03o", bond); 出典 : The Heads and Tails of Project Coin by Joseph D. Darcy (@jddarcy)
}
}
“007” と出力される
2011/11/14 JavaOne 2011 報告会 at Tokyo 7
8.
Q3. 2つのダイヤモンドは本物 ?
publicclass DiamondTest<T> {
private T value;
public DiamondTest() { }
public DiamondTest(T value) { this.value = value; }
public T getValue() { return value; }
public static void main(String[] args) {
DiamondTest<Number> b1 = new DiamondTest<>();
DiamondTest<Number> b2 = new DiamondTest<>(1);
System.out.format(
"b1=%1$d, b2=%2$d¥n", b1.getValue(), b2.getValue());
}
}
“javac DiamondTest.java; java DiamondTest” とすると …
① b1=null, b2=1
② b1=0, b2=1
③ 実行のたびに結果が変わる
④ その他
2011/11/14 JavaOne 2011 報告会 at Tokyo 8
9.
A3. ④ コンパイルエラー
① b1=null, b2=1 ② b1=0, b2=1 ③ 実行のたびに結果が変わる ④ その他
public class DiamondTest<T> {
private T value;
public DiamondTest() { }
public DiamondTest(T value) { this.value = value; }
public T getValue() { return value; }
public static void main(String[] args) {
DiamondTest<Number> b1 = new DiamondTest<>();
DiamondTest<Number> b2 = new DiamondTest<>(1);
System.out.format(
"b1=%1$d, b2=%2$d¥n", b1.getValue(), b2.getValue());
}
}
> DiamondTest.java
DiamondTest.java:9: エラー: 互換性のない型
DiamondTest<Number> b2 = new DiamondTest<>(1);
^
期待値: DiamondTest<Number>
検出値: DiamondTest<Integer>
エラー1個
2011/11/14 JavaOne 2011 報告会 at Tokyo 9
10.
A3. 修正案
型推論は代入と引数型のコンテキストとのあわせ技で推論するので、
推論させない or 推論結果に合わせる … どちらかに修正する
•メソッド引数の型から推論できない場合-代入先の型
•メソッド引数の型から推論できる 場合-実引数の型
public class DiamondTest<T> {
private T value;
public DiamondTest() { }
public DiamondTest(T value) { this.value = value; }
public T getValue() { return value; }
public static void main(String[] args) {
DiamondTest<Number> b1 = new DiamondTest<>();
DiamondTest<Number> b2 = new DiamondTest<Number>(1); // 明示的に指定 or
// DiamondTest<Integer> b2 = new DiamondTest<>(1); // 推論結果に合わせる
System.out.format(
"b1=%1$d, b2=%2$d¥n", b1.getValue(), b2.getValue());
}
}
① b1=null, b2=1 ② b1=0, b2=1 ③ 実行のたびに結果が変わる ④ その他
2011/11/14 JavaOne 2011 報告会 at Tokyo 10
11.
Q4. 新しいママができて、同居しても …
importjava.io.*;
class MultiCatch {
public static void main(String args[]) {
try { m(); }
catch(Exception e) {
System.out.println("e = " + e.getClass().getName());
}
}
private static void m() throws ClassNotFoundException {
try { Class cls = Class.forName(“Multicatch_Ex”); }
catch(ClassNotFoundException |
ReflectiveOperationException e) {
throw e;
}
}
} なお、Multicatch_Ex.class は存在しないものとする
このコード、コンパイルエラーとなります。その理由は ?
① m() 内の catch の例外パラメータの型の全てが m() の throws 句に書かれていない
② ReflectiveOperationException という例外クラスが見つからない
③ 親子関係にあるクラスが複数例外 catch の例外パラメータに同時に指定されている
④ その他
2011/11/14 JavaOne 2011 報告会 at Tokyo 11
12.
A4. ③ 親子関係の例外が指定された
① m()内の catsh の例外パラメータの型の全てが m() の throws 句に書かれていない
② ReflectiveOperationException という例外クラスが存在しない
③ 親子関係にあるクラスが複数例外 catch の例外パラメータに同時に指定されている
④ その他
import java.io.*;
class MultiCatch {
public static void main(String args[]) {
try { m(); }
catch(Exception e) {
System.out.println("e = " + e.getClass().getName());
}
}
private static void m() throws ClassNotFoundException {
try { Class cls = Class.forName(“Multicatch_Ex”); }
catch(ClassNotFoundException |
ReflectiveOperationException e) {
throw e;
}
}
}
MultiCatch.java:12: エラー: 複数catch文の代替をサブクラス化によって関連付けることはできません
ReflectiveOperationException e) {
^
代替ClassNotFoundExceptionは代替ReflectiveOperationExceptionのサブクラスです
エラー1個
2011/10/17
2011/11/14 JJUG Cross Community Conference 2011 Fall
JavaOne 2011 報告会 at Tokyo 12
Q5. この保険って、保険になっているの ?
classAutoClosableResource implements AutoCloseable {
String name = "[null]";
public AutoClosableResource(String str) { name = str; };
public void close() {System.out.println(name + " is closed NOW !!"); }
}
public class TryWithResource {
public static void main(String... args) {
try(AutoClosableResource r1 = new AutoClosableResource("[R1]");
AutoClosableResource r2 = new AutoClosableResource("[R2]");) {
// ...
} finally {
if(r1 != null) r1.close();
if(r2 != null) r2.close();
}
}
}
“javac TryWithResource.java; java TryWithResource” とすると …
① [R1] is closed NOW !! ② [R2] is closed NOW !! ③ [R2] is closed NOW !! ④ その他
① [R2] is closed NOW !! ② [R1] is closed NOW !! ③ [R1] is closed NOW !! ④ その他
① [R2] is closed NOW !! ② [R1] is closed NOW !! ③ [R1] is closed NOW !! ④ その他
① [R2] is closed NOW !! ② [R1] is closed NOW !! ③ [R2] is closed NOW !! ④ その他
2011/11/14 JavaOne 2011 報告会 at Tokyo 14
15.
A5. ④ コンパイルエラー
① [R1] is closed NOW !! ② [R2] is closed NOW !! ③ [R2] is closed NOW !! ④ その他
class AutoClosableResource implements AutoCloseable {
String name = "[null]";
public AutoClosableResource(String str) { name = str; };
public void close() {System.out.println(name + " is closed NOW !!"); }
}
public class TryWithResource {
public static void main(String... args) {
try(AutoClosableResource r1 = new AutoClosableResource("[R1]");
AutoClosableResource r2 = new AutoClosableResource("[R2]");) {
// ... r1, r2 のスコープは、ここだけ … catch/finally 節には及ばない
} finally {
if(r1 != null) r1.close();
if(r2 != null) r2.close();
}
D:¥javac TryWithResource.java
}
TryWithResource.java:15: エラー: シンボルを見つけられません
}
if(r1 != null) r1.close();
^
シンボル: 変数 r1
場所: クラス TryWithResource
...(割愛)...
エラー4個
2011/11/14 JavaOne 2011 報告会 at Tokyo 15
16.
A5. 修正案
Closeの明示的呼び出しはしないこと
Catch/finally ではリソースにアクセスできない。
try(){...}の()で宣言された順の逆順でcloseが呼ばれる。
class AutoClosableResource implements AutoCloseable {
String name = "[null]";
public AutoClosableResource(String str) { name = str; };
public void close() {
System.out.println(name + " is closed NOW !!");
}
}
public class TryWithResource {
public static void main(String... args) {
try (AutoClosableResource r1 = new AutoClosableResource("[R1]"),
AutoClosableResource r2 = new AutoClosableResource("[R2]"); ) {
}
}
}
① [R1] is closed NOW !! ② [R2] is closed NOW !! ③ [R2] is closed NOW !! ④ その他
① [R2] is closed NOW !! ② [R1] is closed NOW !! ③ [R1] is closed NOW !! ④ その他
① [R2] is closed NOW !! ② [R1] is closed NOW !! ③ [R1] is closed NOW !! ④ その他
① [R2] is closed NOW !! ② [R1] is closed NOW !! ③ [R2] is closed NOW !! ④ その他
2011/11/14 JavaOne 2011 報告会 at Tokyo 16
17.
Q6. ウニの前に出たネタの格好がイマイチ…
public classStringInSwitch {
final static String ss = “¥u3046";
public static void main(String... args) {
switch(args[0]) {
case “あ“+”い” : System.out.println(“あい"); break;
case ("え“) : System.out.println("え"); break;
case "お" : System.out.println("お"); break;
case ss : System.out.println(ss); break;
default : System.out.println("default"); break;
}
}
}
“javac StringInSwitch.java; java StringInSwitch う” とすると …
① う ② default ③ ¥u3046 ④ その他
2011/11/14 JavaOne 2011 報告会 at Tokyo 17
18.
A6. ① う on JDK7 u2
① う ② default ③ ¥u3046 ④ その他
public class StringInSwitch {
final static String ss = "¥u3046"; // "う"
public static void main(String... args) {
switch(args[0]) {
case "あ"+"い" : System.out.println("あい"); break;
case ("え") : System.out.println("え"); break;
case "お" : System.out.println("お"); break;
case ss : System.out.println(ss); break;
default : System.out.println("default"); break;
}
}
} on JDK7 update2(EA) → ① う
>javac StringInSwitch.java; java StringInSwitch う
う
2011/11/14 JavaOne 2011 報告会 at Tokyo 18
19.
A6. ④ コンパイルで“ヌルポ” on JDK7 u1
① う ② default ③ ¥u3046 ④ その他
>javac StringInSwitch.java
コンパイラで例外が発生しました(1.7.0_01)。
Bug Paradeに同じバグが登録されていないことをご確認の上、
Java Developer Connection(http://java.sun.com/webapps/bugreport)で
バグの登録をお願いいたします。レポートには、そのプログラムと下記の診断内容を含めてください。
ご協力ありがとうございます。
java.lang.NullPointerException
at com.sun.tools.javac.comp.Lower.visitStringSwitch(Lower.java:3456)
at com.sun.tools.javac.comp.Lower.visitSwitch(Lower.java:3357)
at com.sun.tools.javac.tree.JCTree$JCSwitch.accept(JCTree.java:959)
at com.sun.tools.javac.tree.TreeTranslator.translate(TreeTranslator.java:58)
at com.sun.tools.javac.comp.Lower.translate(Lower.java:2160)
at com.sun.tools.javac.tree.TreeTranslator.translate(TreeTranslator.java:70)
at com.sun.tools.javac.tree.TreeTranslator.visitBlock(TreeTranslator.java:160)
at com.sun.tools.javac.comp.Lower.visitBlock(Lower.java:3311)
at com.sun.tools.javac.tree.JCTree$JCBlock.accept(JCTree.java:781)
at com.sun.tools.javac.tree.TreeTranslator.translate(TreeTranslator.java:58)
at com.sun.tools.javac.comp.Lower.translate(Lower.java:2160)
at com.sun.tools.javac.tree.TreeTranslator.visitMethodDef(TreeTranslator.java:144)
at com.sun.tools.javac.comp.Lower.visitMethodDefInternal(Lower.java:2619)
at com.sun.tools.javac.comp.Lower.visitMethodDef(Lower.java:2538)
at com.sun.tools.javac.tree.JCTree$JCMethodDecl.accept(JCTree.java:669)
at com.sun.tools.javac.tree.TreeTranslator.translate(TreeTranslator.java:58)
on JDK7 u1 → ④ その他
at com.sun.tools.javac.comp.Lower.translate(Lower.java:2160)
at com.sun.tools.javac.comp.Lower.visitClassDef(Lower.java:2283)
at com.sun.tools.javac.tree.JCTree$JCClassDecl.accept(JCTree.java:591)
at com.sun.tools.javac.tree.TreeTranslator.translate(TreeTranslator.java:58)
at com.sun.tools.javac.comp.Lower.translate(Lower.java:2160)
at com.sun.tools.javac.comp.Lower.translate(Lower.java:2180)
at com.sun.tools.javac.comp.Lower.translateTopLevelClass(Lower.java:3650)
at com.sun.tools.javac.main.JavaCompiler.desugar(JavaCompiler.java:1393)
at com.sun.tools.javac.main.JavaCompiler.desugar(JavaCompiler.java:1271)
at com.sun.tools.javac.main.JavaCompiler.compile2(JavaCompiler.java:870)
at com.sun.tools.javac.main.JavaCompiler.compile(JavaCompiler.java:829)
at com.sun.tools.javac.main.Main.compile(Main.java:417)
こんなときは、バグ登録しましょう !!
at com.sun.tools.javac.main.Main.compile(Main.java:331)
at com.sun.tools.javac.main.Main.compile(Main.java:322)
at com.sun.tools.javac.Main.compile(Main.java:76)
at com.sun.tools.javac.Main.main(Main.java:61)
2011/11/14 JavaOne 2011 報告会 at Tokyo 19
20.
A6. 修正案
(JDK7u2でfixの見込みだけど)
case ラベルを () で括るのは避けましょう。
public class StringInSwitch {
final static String ss = "¥u3046";
public static void main(String... args) {
switch(args[0]) {
case "あ"+"い" : System.out.println("あい"); break;
case "え" : System.out.println("え"); break;
case "お" : System.out.println("お"); break;
case ss : System.out.println(ss); break;
default : System.out.println("default"); break;
}
}
}
①う ② default ③ ¥u3046 ④ その他
2011/11/14 JavaOne 2011 報告会 at Tokyo 20
21.
この高度でB747 ジャンボが
(United Air Line)
ご清聴ありがとうございました。
2011/11/14 JavaOne 2011 報告会 at Tokyo 21