JavaのBinary Literalsが空気を読んでくれたりくれなかったり

d.hatena.ne.jp

を読んで。面白いなーと思って。
プリキュア見ながら実際にコードを書いて確かめてみてる間に解決してたようで良かった。

んでも、byteへのキャストが必要な原因はどこだろう?って思って。

Stream<Byte> sb = Stream.of((byte)0b0000_0001, (byte)0b0000_0010);

Stream特有?

→違う。Stream特有ってわけじゃない。

例えば、こんなん書くとコンパイルエラーになる。

    List<Byte> bs = Arrays.asList(0b0001_0010);
SampleTest.java:16: エラー: 不適合な型: 推論変数Tには、不適合な境界があります
    List<Byte> bs = Arrays.asList(0b0001_0010);
                                 ^
    等価制約: Byte
    下限: Integer
  Tが型変数の場合:
    メソッド <T>asList(T...)で宣言されているTはObjectを拡張します

0b0001_0010 ってByteに入れられない?

入る。コンパイルエラーにならない。

    Byte b = 0b0001_0010;

0b0001_0010 ってbyteに入れられない?

まぁ、入る。コンパイルエラーにならない。

    byte b = 0b0001_0010;

ふむ。

0b0001_0010 ってbyteパラメータとして渡せる?

渡せない!コンパイルエラーになる。

  @Test
  public void test(){
    sample(0b0001_0010);
  }

  private byte sample(byte b){
    return b;
  }
SampleTest.java:19: エラー: 不適合な型: 精度が失われる可能性があるintからbyteへの変換
    sample(0b0001_0010);
           ^

あ。ふむ。そうか。

0b0001_0010 ってbyteの範囲を超えるとエラーになる?

うん。なる。

byte b = 0b1_0001_0010;
SampleTest.java:19: エラー: 不適合な型: 精度が失われる可能性があるintからbyteへの変換
    byte b = 0b1_0001_0010;
             ^

まとめ

0b0001_0010 ってintだけど、直接byteに入れる場合は、いい具合にコンパイラが変換してくれるってことなのかな。

こう書くと・・・

    byte b = 0b0001_0010;

こんな風になるってことか。

    byte b = (byte)0b0001_0010;

だけど、メソッドのパラメータとしてbyteを渡すときは、intで渡されることになって、そうなるとコンパイル時には判断できないってことか。

だから、これはコンパイルエラーになるけど

  @Test
  public void test(){
    sample(0b0001_0010);
  }

  private byte sample(byte b){
    return b;
  }

これはならないってことね

  @Test
  public void test(){
    byte b = 0b0001_0010;
    sample(b);
  }

  private byte sample(byte b){
    return b;
  }

空気読んでくれても良さそうだけど。仕組み上そういうわけにもいかないってことなのかな?

ふーん。面白かった。

Binary Literals

2015-07-06追記

スッキリ!