OCJP Silver 試験のお勉強

"Oracle Certified Java Programmer, Silver SE 8" という資格の勉強をしてるけど、Java の言語仕様がごちゃごちゃしていて悶絶している。

以下、個人的に疑問符がついたところ 2 つ。

可変長引数の書き方

メソッドの定義でコンパイルエラーとなるのは次のうちどれか、という問題。

  1. void foo(int[] args) { }
  2. void foo(int args[]) { }
  3. void foo(int... args) { }
  4. void foo(int args...) { }

答えはd の foo(int args...) { } なんだけど、b がコンパイルできて d がコンパイルエラーなのは自然じゃないなという感想。 まあ、b は C/C++ の名残で許容されているだけなので、そういう背景を知ったうえで、広い心で Java の言語仕様を受け入れようと思う。

関数式の引数

次のようなプログラムをコンパイルしたらどうなるかという問題。

import java.util.function.Function;

public class Main {
    public static void main(String[] args) {
        int n;

        Function<Integer, Integer>
            succ = n -> n + 1;  // コンパイルエラー
        System.out.println(succ.apply(0));
    }
}

このプログラムはコンパイルできない。 関数式の引数は、まわりのスコープのローカル変数とダブってはいけないということなので。 コンパイラは、"Lambda expression's parameter n cannot redeclare another local variable defined in an enclosing scope." というエラーを吐く。

Java の関数式まわりの仕様は、プログラムを組むときに気をつけなければならないことが結構多い。