あえて今Java Bronzeを勉強してみた

2022/10/13に公開

最近なんかポンコツ感凄いなと。基礎は雰囲気で実装しているところ強いのではないか。
感覚に頼っている部分の言語化ができるのでは、と思い
凄く今更ながらJavaBronzeのお勉強をしてみました。

一応軽く説いてみた感じだと
実務ではやりすぎると怒られるような書き方だけど、
通ってしまうギリギリの書き方の知見が得られました。
(中括弧{}省略しまくったりとか)

せっかくなので本1冊分から知らなかったことを抜き出してみようと思います。

  1. for文実は凄く省略できた
for(int i=0;i<10;i++) // と書くのが普通なんだけど
for(;i<10;) // という書き方もエラーにならない。式1,3は省略可能
  1. 整数リテラルで0から始まれば8進数、0bから始まれば2進数
  2. 浮動小数点数を指数表記でも表せる
    3e4 = 3.0*10^4 = 30000.0
    普段使わなさそう…使う瞬間が見たい。
  3. エスケープシーケンスの\fはフォームフィード
    印刷用・・・?使う瞬間見たい。
  4. (試験範囲外だけど)java10からvarが使える
  5. クラス名、メソッド名などの識別子の1文字目は$, _も利用可能
    クラス名だけなら数字からも始められるらしい
  6. 配列宣言はint[]だけではなくint arr[]やint []arrでもいいらしい
int[] a = new int[1]; // 全部OK
int b[] = new int[1];
int []c = new int[1];
  1. printlnで配列を引数にしたときの挙動はcharだけちょっと特殊
char[] carr = {'A', 'B', 'C'}
system.out.println(carr); // ABC
int[] iarr = {1,2,3}
system.out.println(iarr); // [I@464867 オブジェクトのハッシュコード
String[] sarr = {'A', 'B', 'C'}
system.out.println(sarr); // [Ljava.lang.String;@g4967467e Lでクラス型、オブジェクトのハッシュコード
  1. charの代入はシングルクオーテーションでしか通らない。
  2. 識別子には英数字の他だと_, $が利用可能
  3. 演算子の"~"ビット演算NOT
  4. 単項演算子のインクリメント・デクリメント配置問題、何気に出題多め
    前につけば計算が先、後ろにつけば代入が先。
int a1 = 10;
int b1 = ++a1; // a1 = 11,  b1 = 11
int a2 = 10;
int b2 = a2++; // a2 = 10,  b2 = 11
int a3 = 10;
int b3 = --a3; // a3 = 9, b3 = 9
int a4 = 10;
int b4 = a4--; // a4 = 9, b4 = 10
  1. switchのdefaultは省略できるだけでなく実はどこにでも書くことができる。
    (それって最初にdefault書いてbreakを書かなかったらエンバグしそう)
  2. if(!b && i++ < 5)みたいな書き方ができる
    とはいえこれもエンバグしそうで書くに書けない。
    もし左辺がfalseなら右辺は実行しないわけで・・・・
  3. ifの中に代入を入れることができる
    これもエンバグだからやらないけど・・・
boolean a = false;
if(a = true)
  // aはtrueになるのでこのブロックは実行される

16,15を受けてつまりこんなのも通ってしまうことを確認

    int i = 10;
    while(i-- > 0) {
      // 先に代入が走るのでi=1のときに判定されても処理を通るので9から始まり0で終わる。
      System.out.println(i);
    }
    
    boolean bool = false;
    while(bool = true) {
      // コンパイルエラーにはならず無限ループ
    }
  1. while(true)は無限ループだが実行可能、しかしwhile(false)はコンパイルエラーになる。
  2. if文と同じくdoのあとの中括弧は省略可能なのでこの書き方も実はOK
    int i = 0;
    do
      System.out.println(i++);
    while (i <= 100);
  1. forの中括弧も省略可能
  2. ネストされたループのcontinueとbreakにはラベルを付けることができる。
    名前が無い場合、ネストの1個外に出るだけだけれど、この方法であれば1回で外側まで抜けられる
    禁止されがちなGOTO文と同じような挙動となるので使わない方が無難かも
label1: // ラベルの宣言。
for(int i=0;i<10;i++){
  for(int j=0;j<5;j++){
    if(i==1 && y==1){
      break label1; // label1のついたfor文から抜ける
    }
  }
}
// break label1の次はここまで飛ぶ

continueの場合はラベルの付いている先頭に戻る

  1. オブジェクトをNULLにするとガベージコレクタの対象にできる
  2. finalのついたメソッド・クラスを作成することが可能。ただし、サブクラスを作れない。メソッドはオーバーライド不可になる。(言われてみれば感あるけど作ったことがない)
  3. コンストラクタにsuper()やthis()がないとき、暗黙的にsuper()の呼び出しが行われる。
    引数のあるコンストラクタだけを定義した場合、暗黙的な引数無しコンストラクタは使用できない(引数無で定義する必要がある)
  4. 抽象クラスは具象抽象混在(正しく認知していなかったのでメモ)で直接newできない
  5. (※bronze範囲外:読んだ書籍ではjava8にinterfaceの新機能があるとだけ言及された)
    defalut句を使用した実装が行えるようになった。多重継承問題が発生する、重複していた場合はサブクラスから見てimplementsしているなから一番近い継承関係にあるインターフェースの処理が採用される。(検索用トピック:菱形継承)
    判断できない場合はコンパイルエラーとなりOverrideする様に勧められる。
    混乱の元だし基本使うことは無いのかなと思っている。
  6. interfaceで変数を宣言すると暗黙的にpublic static finalとなるため、初期化が必須となる。メソッドは暗黙的にpublic abstractになるためpublic以外のアクセス修飾子の定義が不可。どちらもコンパイルエラーになる。
  7. char->intへの変換はキャストは不要で暗黙的に行える

Discussion