JDK7 Quiz …
             (まずいお金の使い方)




              木村英一(@kimuchi583)



2011/11/14       JavaOne 2011 報告会 at Tokyo   1
Q1. 丈長をご希望ならLサイズを
 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);
     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
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
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
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
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
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
Q3. 2つのダイヤモンドは本物 ?
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());
     }
}

         “javac DiamondTest.java; java DiamondTest” とすると …
①     b1=null, b2=1
②     b1=0, b2=1
③     実行のたびに結果が変わる
④     その他
2011/11/14                  JavaOne 2011 報告会 at Tokyo            8
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
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
Q4. 新しいママができて、同居しても …
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_Ex.class は存在しないものとする

             このコード、コンパイルエラーとなります。その理由は ?
①     m() 内の catch の例外パラメータの型の全てが m() の throws 句に書かれていない
②     ReflectiveOperationException という例外クラスが見つからない
③     親子関係にあるクラスが複数例外 catch の例外パラメータに同時に指定されている
④     その他
2011/11/14                 JavaOne 2011 報告会 at Tokyo                    11
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
A4. 修正案
             マルチキャッチの例外パラメータには、親子関係にある例外を記述できない。
                JDK7 から ReflectiveOperationException が追加された。
             これは ClassNotFoundException 等リフレクション操作に関連する例外の親クラス
               よって ReflectiveOperationException だけをパラメータに指定する
 import java.io.*;                                         Exception
 class MultiCatch {
                                                              ReflectiveOperationException
   public static void main(String args[]) {
     try { m(); }                                                ClassNotFoundException
     catch(Exception e) {                                        IllegalAccessException
       System.out.println("e = " + e.getClass().getName());
                                                                 InstantiationException
     }
   }                                                             InvocationTargetException
   private static void m() throws ClassNotFoundException {       NoSuchFieldException
     try { Class cls = Class.forName(“Multicatch_Ex”); }
                                                                 NoSuchMethodException
     catch(ReflectiveOperationException e) {
       throw e;
     }
   }
 }                                       なお、Multicatch_Ex.class は存在しないものとする


“e = java.lang.ClassNotFoundException”と表示される。


2011/11/14                          JavaOne 2011 報告会 at Tokyo                            13
Q5. この保険って、保険になっているの ?
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]");) {
         // ...
    } 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
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
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
Q6. ウニの前に出たネタの格好がイマイチ…
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;
    }
  }
}

“javac StringInSwitch.java; java StringInSwitch う” とすると …

     ① う ② default ③ ¥u3046 ④ その他

2011/11/14            JavaOne 2011 報告会 at Tokyo         17
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
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
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
この高度でB747 ジャンボが
                                   (United Air Line)




             ご清聴ありがとうございました。
2011/11/14    JavaOne 2011 報告会 at Tokyo                21

JDK7 Quiz... @ JavaOne報告会 at Tokyo

  • 1.
    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
  • 13.
    A4. 修正案 マルチキャッチの例外パラメータには、親子関係にある例外を記述できない。 JDK7 から ReflectiveOperationException が追加された。 これは ClassNotFoundException 等リフレクション操作に関連する例外の親クラス よって ReflectiveOperationException だけをパラメータに指定する import java.io.*; Exception class MultiCatch { ReflectiveOperationException public static void main(String args[]) { try { m(); } ClassNotFoundException catch(Exception e) { IllegalAccessException System.out.println("e = " + e.getClass().getName()); InstantiationException } } InvocationTargetException private static void m() throws ClassNotFoundException { NoSuchFieldException try { Class cls = Class.forName(“Multicatch_Ex”); } NoSuchMethodException catch(ReflectiveOperationException e) { throw e; } } } なお、Multicatch_Ex.class は存在しないものとする “e = java.lang.ClassNotFoundException”と表示される。 2011/11/14 JavaOne 2011 報告会 at Tokyo 13
  • 14.
    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