【備忘録】Java本格入門 Part1

はじめに

この記事は「Java本格入門」を読んで 忘れそうなことや重要だったことのメモです。

自分用のメモなのでかなり読みにくいかもしれませんが ご了承ください。

詳しく学びたい方はぜひご購入ください。

Java本格入門 ~モダンスタイルによる基礎からオブジェクト指向・実用ライブラリまで | 谷本 心, 阪本 雄一郎, 岡田 拓也, 秋葉 誠, 村田 賢一郎, Acroquest Technology株式会社 | 工学 | Kindleストア | Amazon



この記事について

この記事では「Java本格入門」のchapter1 ~ chapter3までをまとめてあります。

具体的な内容は

  • Javaの基本的な概念
  • 基本的な書き方
  • 修飾子、クラス、インターフェース

などです。



chapter1 Javaの基本を知ろう ~イントロダクション~


  • 実行される流れ
    1. ソースコードの作成
    2. クラスファイルと呼ばれる中間コードにコンパイル (OSに依存しない)
    3. JavaVMがクラスファイルに記載されたコードを解釈して処理する (OSの違いはここで吸収される)



chapter2 基本的な書き方を身に着ける

  • メソッドはすべてクラスの中に記述する必要がある


全体的にCとかなり似ている...


int num;
num = 1;
System.out.println(num);


  • 演算
int num1 = 1;
int num2 = 1;
System.out.println(num1++); // 1
System.out.println(num1);   // 2

System.out.println(++num2); // 2
System.out.println(num2);   // 2


int num = 1;
boolean is_positive = num >= 0 ? true : false;

System.out.println(is_positive); // true


文字列の結合も簡単!

最後に ;を付けないとコンパイルしてくれない

String message = "Hello" + " World";
message += " and Java!";

//message += " and Java!" 
//Syntax error, insert ";" to complete Statement

System.out.println(message); // Hello World and Java!

ちなみにStringが大文字なのは 参照型だから (記事の後半で説明)


  • if文
int x = 15;

if (x % 2 == 0){
    System.out.println("xは2の倍数");
} else if (x % 3 == 0){
    System.out.println("xは3の倍数");
} else {
    System.out.println("xは2または3の倍数ではありません");
}

// xは3の倍数


  • for, while

for, whileどちらもCと同じ書き方

int sum = 0;
for (int i = 1; i <= 10; i++){
    System.out.println("i = " + i + " : " + (sum+=i));
}

sum = 0;
int i = 1;
while (i <= 10){
    System.out.println("i = " + i + " : " + (sum+=i));
    i++;
}

/*
i = 1 : 1
i = 2 : 3
i = 3 : 6
i = 4 : 10
i = 5 : 15
i = 6 : 21
i = 7 : 28
i = 8 : 36
i = 9 : 45
i = 10 : 55
*/


  • for-each文
    • 変数に入っている要素すべてに対して処理を行う

配列の括弧の位置がCと違う...

int[] arr = {1, 2, 3, 4, 5};
for (int n : arr){
    System.out.println(n);
}

// 1
// 2
// 3
// 4
// 5

この書き方できるのは嬉しい


  • class
    • メソッドの宣言
修飾子 戻り値の型 名前(引数...)


修飾子 説明
アクセス修飾子(publicなど) スコープを限定する
abstract そのクラスやメソッドが抽象的であることを表す
static インスタンス化されてなくてもアクセス可能
final メンバーの上書きを禁止する(対象によって意味が少し変わるので注意)


  • class
    • メソッドのオーバーロード

      • 引数の型や数が違うと、同じ名前のメソッドを定義できる
    • mainメソッド

      • プログラムの起点となるメソッド
      • 修飾子は public static


  • classで遊ぶ
package chapter2;

// クラス
class Student{
    // フィールド
    String name;
    int score;
    static final int MAX_SCORE = 100;

    // コンストラクタ
    Student(String name, int score){
        this.name = name;
        this.score = score;
    }

    // scoreがない場合のコンストラクタ
    Student(String name){
        this(name, 0);
    }

    void addScore(int x){
        this.score += x;
    }

    // オーバーロード
    void addScore(){
        this.score += 1;
    }

    // 1つのフィールドに対する値の取得を行うシンプルなメソッドを
    // getter(ゲッター)という
    String getName(){
        return name;
    }

    // 1つのフィールドに対する値の設定を行うシンプルなメソッドを
    // setter(セッター)という
    void setName(String name){
        this.name = name;
    }

    void printScore(){
        System.out.println(this.name+"のscoreは"+this.score);
    }
    
}

public class Training2 {
    public static void main(String... args){

        Student hoge = new Student("hoge",80);
        Student heno = new Student("heno");

        hoge.printScore(); //hogeのscoreは80
        heno.printScore(); //henoのscoreは0

        System.out.println(hoge.getName()); //hoge
        hoge.setName("hoge2");
        System.out.println(hoge.getName()); //hoge2

        hoge.addScore(); // +1
        hoge.printScore(); //hoge2のscoreは81
        hoge.addScore(5); // +5
        hoge.printScore(); //hoge2のscoreは86
    }
}


名前と点数を持つStudentクラス

getterやsetter、オーバーロードも実装


書き方 説明
@Override メソッドのオーバーライドを示す
@Depracated 非推奨を示す
@SuppressWarnings 警告を出さないようにする


private String name;

//本当にオーバーライドされているかコンパイラがチェックしてくれる
//さらに見ただけでオーバーライドされていることもわかる
@Override
public String toString(){
    return name;
}


オーバーロード(上書き定義) とオーバーライド(多重定義) は名前が似ているが違うので気を付けること

medium-company.com


  • 名前の付け方
    • クラスと変数はキャメルケース
      • クラスは大文字始まりのキャメルケース (StudentObject)
      • 変数は小文字始まりのキャメルケース (name)
    • 定数はスネークケース (MAX_SCORE)
    • 変数は名詞、メソッドは動詞 (isStartedをフィールドとするのは良くない)


詳しく知りたい方は以下を参考に

www.wakuwakubank.com



Chapter3 型を極める

  • Javaの型には大きく分けて2種類
    • プリミティブ型 (基本的なデータ型)
      • int,long,char,boolean...
      • 単なる値でありメソッドを持たない (しかし、ラッパークラスを使うことで値を操作できる)
    • 参照型


int num = 10; //整数リテラル


  • ワイドニング
    • データサイズが大きくなるように変換する場合は互換性が保たれるため、変換可能
short sNum = 100;
int iNum = sNum; //ワイドニングによる自動変換
// short -> int に変換
System.out.println(iNum);


逆にint型の値をshortに代入しようとするとコンパイルエラーになる


上記はキャストを行うことで変換は可能

この変換をナローイングと呼ぶ

ただし、桁があふれて想定しない値になる可能性がある


  • 参照型
    • 参照という値を保持する型
String name = new String("hoge");
// String name = "hoge"; //文字列リテラルからでもインスタンスを生成できる

// 以下のコードはStringクラスのインスタンスへの参照を渡している
// 値そのものを渡しているわけではない
System.out.println(name); //hoge


  • オブジェクトの参照がない状態を表すnullリテラルがある
String name = null;


  • ラッパークラス
    • プリミティブ型に値を操作できる機能を加えた

より詳しく学びたい方は以下の記事を参考にしてください

www.javadrive.jp


  • Java5.0 からはプリミティブ型とラッパークラス間の自動変換が行われる

    • プリミティブ型からラッパークラスの自動変換をオートボクシング
    • ラッパークラスからプリミティブ型の自動変換をアンボクシング
  • 上記は意図しない結果になる場合があるので、基本は明示的に型変換する


  • パッケージ
    • クラスを階層的に整理する


  • 修飾子 (クラス)
修飾子 説明
public ほかのあらゆるクラスから参照可能
指定なし 同一のパッケージ内のクラスから参照可能 (パッケージプライベート)


  • 修飾子 (フィールド、メソッド)
修飾子 説明
public ほかのあらゆるクラスから参照可能
protected 子クラス及び同一パッケージ内のクラスから参照可能
指定なし パッケージプライベート
private 自クラス内部のみアクセス可能 (子クラスからの参照は不可)


  • static修飾子
    • すべてのインスタンスで共通のフィールドの定義
    • インスタンスを生成しなくても呼び出せるメソッドの定義
    • これらをクラスメンバと呼ぶ


  • final修飾子
    • 変数を変更不可にする
    • static と finalの両方を付けたフィールドを一般に定数、またはクラス定数と呼ぶ


  • 継承 (extends)
    • あるクラスをもとにして拡張する形で新たなクラスを定義できる


  • 抽象クラス (abstract)
    • 共通の機能の実装
    • クラスのひな形
    • 抽象メソッドと呼ばれる実装を持たないメソッドを定義できる
    • 「抽象クラスで処理全体を実装し、継承した子クラスで処理の一部のみ実装する」などの分担ができる


  • インターフェース
    • 具体的な実装を切り離して拡張性を高くするために、メソッドのみを定義する
    • メソッドだけでなく定数も定義できる


インターフェースの実装

public interface Foo {
    String say();
}


implementsキーワードを使ってクラス宣言

public class DefaultFoo implements Foo {
    private String message;
    
    public DefaultFoo(String message){
        this.message = message;
    }

    @Override
    public String say(){
        return message;
    }
}


Foo foo = new DefaultFoo("hello,java!");
System.out.println(foo.say()); //hello,java!


  • 匿名クラス
    • クラスの定義とインスタンス化を1つの記述で行える
    • インターフェースで実装した処理などを局所的に使う場合に利用



  • hashCodeメソッド
    • オブジェクトが等価であるかどうかをequalsメソッドより高速に判定できる

より詳しく学びたい方は以下の記事を参考にしてください

pointsandlines.jp


  • 列挙型 (enum)
    • いくつかの定数の集まりを定義する型
    • 型安全が保証される

より詳しく学びたい方は以下の記事を参考にしてください

qiita.com



Stringクラスのオブジェクトしか追加できない

List<String> list = new ArrayList<String>();
list.add("Java");
// list.add(1); //コンパイルエラー
String element = list.get(0);
System.out.println(element);


仮の型であるパラメータEを使ってStackクラスを作成

public class GenericStack<E> {
    private List<E> taskList;
    
    public GenericStack(){
        taskList = new ArrayList<>();
    }

    public boolean push(E task){
        return taskList.add(task);
    }

    public E pop(){
        if (taskList.isEmpty()){
            return null;
        }
        return taskList.remove(taskList.size() - 1);
    }
}


実行してみる

GenericStack<String> stringStack = new GenericStack<>();

stringStack.push("hello");
stringStack.push("world");
stringStack.push("java");
// stringStack.push(1);; //コンパイルエラー

String stringElement = stringStack.pop(); //キャストいらない

if (stringElement != null){
    System.out.println(stringElement); //java
}



GenericStack<Integer> integerStack = new GenericStack<>();

integerStack.push(1);
integerStack.push(2);
integerStack.push(3);
// integerStack.push("hello");//コンパイルエラー

Integer integerElement = integerStack.pop(); //キャストいらない

if (integerElement != null){
    System.out.println(integerElement); //3
}


ちなみに仮型パラメータに制限を加えることも可能

public class NumberStack<E extends Number>{}



感想

本格入門というだけあって、かなり盛り沢山な内容となっていた

プログラミング完全初心者にはハードル高めかも...


次回は

  • 配列
  • StreamAPI
  • 例外処理

について学んでいく