# Java講習会資料
## 基礎の基礎の基礎の用語
- **プログラミング** : コードを書くこと
- **プログラミング言語(Language, Lang)** : コードの規格の種類(RubyとかJavaとか)
- **ソースコード(Source Code)** : ソースとも言われる。誰かが書いたコードのこと
今回はJavaという名前の(プログラミング)言語を使って説明していく。
## 何故Javaなのか
そもそもこの講習の目的は以下の通り。
- 部員のプログラミングについての理解度の底上げをする
- (日常生活において会話する上で)最低限の用語の理解を得る
~~つまりぶっちゃけ言語は何でもいい~~
(今回はメインでは扱わないが,`C++`という言語の入門に[APG4b](https://atcoder.jp/contests/apg4b)という素晴らしいものがある。
これは常設のコンテスト形式で,暇があるなら全員参加するべきだと思う。)
## Javaとは
- 1995年にSun Microsystemsから最初にリリースされた
- コンパイル型言語
- オブジェクト指向型言語
- クロスプラットフォーム対応
- (静的な強い型付け)
- **JavaScriptとはまったく違う**(メロンとメロンパンくらい違う)
### 余談 : 静的な強い型付け?
- **型システム** : 偉い人が研究している計算機科学の一分野([Wikipedia](https://ja.wikipedia.org/wiki/%E5%9E%8B%E3%82%B7%E3%82%B9%E3%83%86%E3%83%A0))
- **型** : 値の種類のこと
- **静的な型付け** : プログラムが実際に実行される前に,いろんな値の**型が決定されている**こと(つまり,コンパイル時に型が決まる)
- **強い型付け** : 型を忖度して**自動で変換しない**こと(整数と文字の足し算ができない等)
ちなみに,**動的**な**強い**型付けの言語に`Python`がある。
Pythonの場合,具体的には
- 型 : `int`や`char`など
- 動的型付け : 実行中に臨機応変に型が決まる(型を書かなくてもエラーにならない)
という感じになる。
## コンパイルとは
簡単に言うと**ソースコード(人間が書いたコード)を機械語に翻訳すること**
当たり前だがパソコンは人間の言葉を理解することはできない。そのため,
ソースコードをパソコンに読ませたところで(゚Д゚)ハァ?となるだけである。
そこで,ソースコードをパソコンが理解できるように翻訳する必要がある。
コンパイルを行うことによってソースコードは文字列から機械が読めるようなバイナリへと変換される。
パソコンはそのバイナリデータを読みとってその指示通り計算などの動作をするわけである。
ちなみにコンパイル言語にはJava以外にもC, C++, D, Goなどの言語がある。
## 環境構築
閑話休題,早速コードを書いて実行してみよう!
……という訳にはいかないので,先にJavaのコードを実行できる環境を整える。
### 講習時
口頭で説明する。
### Linux(WSL)
Debian系のシステムを前提に進める。
まずパッケージリストの更新
```shell
sudo apt-get update
```
Javaが入っているか確認
```shell
java -version
```
Javaが入っていない場合このような出力が出るので
```shell
Command 'java' not found, but can be installed with:
なんちゃらかんちゃら
```
次のコマンドを実行して、デフォルトのJRE(Javaの実行環境) をインストールします。これにより、JREがインストールされます。
```shell
sudo apt install default-jre
```
Javaが入っているか確認
```shell
java -version
```
これでバージョンが出力されたらJREのインストールは完了です。
しかし,これだけではコンパイルできません。
コンパイルにはJDK(Javaの開発環境)が必要になります。
次のコマンドを実行してJDKをインストールしましょう。
```shell
sudo apt install default-jdk
```
最後にインストールされているか確認
```shell
javac -version
```
これでバージョンが出力されれば成功です。
### Windows
ネイティブのWindowsでプログラミングを行うことは多大な労苦を伴う。
[WSL](https://docs.microsoft.com/ja-jp/windows/wsl/about)の[セットアップガイド](https://d3bu.net/wsl2-setup)に従ってLinuxの環境を整えることを強くお勧めする。
#### それでも僕は<!--M$に魂を売った-->[ドザー](https://wa3.i-3-i.info/word18559.html)だし……
WSLならWindowsの環境を破壊せずにLinuxの環境を共存させることが可能。
情報基礎でLinuxの基本的な使い方は習ったはずだし,今からでも遅くない。Linuxを使おう。
……どうしてもWindowsしか使えない状況下にあるのなら,[ここ](https://docs.oracle.com/javase/jp/11/install/installation-jdk-microsoft-windows-platforms.html)
のドキュメントを読みながら環境構築をしよう。
## プログラミングをする方法
時は満ち,いよいよJavaをソースコードから実行する材料が全て揃った。
### 方法: コマンドライン
予め作成したソースコードのパスを`javac`コマンドの引数(コマンド名の他に渡す文字列)に渡してやると,そのソースコードがコンパイルされる。
```shell
javac ./hogehoge.java
```
コンパイルが終わったら,```hogehoge.class```などの拡張子が```.class```のファイルが
生成される。
これを実行するには```hogehoge.class```の拡張子を抜いた形で
```shell
java hogehoge
```
とするとJavaのソースコードが実際に動く。
これが実行の一連の流れだ。
## 基礎の基礎の用語
さて,ここは超重要。
プログラミングにおいて基本的な用語を一気に説明をする。
- **値** : 文字や数字などといったデータのこと(例: `1234`, `'a'`)
- **変数** : 値を保存するメモリのようなもの
- **評価** : 式(後述)の中に出てくる値を元に,その式自体の値を計算すること(例: `1+1`という演算式を評価すると`2`という値になる)
- **式** : 自身を評価することによって値に置き換えられるもの(例: 演算式, 条件式, 関数の呼び出し)
- **関数** : 値を受け取って新たな値を返すもの(例: べき乗を計算する`Math.pow`関数)
- **文** : 式を構成する要素で,それ自身は値を返さない(例: `if`文, `while`文)
巨大なプロジェクトの巨大なソースコードも,1つ1つ分解していけばこのようなものから成り立っていることがわかる。
----
## 文法 基礎編
Javaを書く上で避けては通れない必須の文法を説明する。
### Main関数
Javaはmain関数の中にある処理から実行されます。
とりあえず最初のうちはこう書きましょう。
```java=
public class Main {
public static void main(String[] args){
//ここに処理を書く
}
}
```
### セミコロン
Javaは1文(1つの処理)の終わりに必ずセミコロンをつけなければならない。
ここに一例を示す。
```java=
System.out.println("Hello, World!") //これはコンパイルエラーになる(セミコロン忘れ)
System.out.println("Hello, World!"); // Hello, World!と出力される
```
最初のうちはセミコロンを忘れてコンパイルエラーになることが非常に多いので気をつけよう。
### 値の種類
唐突だが,[基礎の基礎の用語](#基礎の基礎の用語)で説明した通り,**値**には種類(**型**)がある。
その中でも,知っておかないと話が始まらないものを説明する。
<!-- <small>※ちなみにその「種類」のことを型と呼ぶ。</small> -->
#### int
本名はInteger。意味は**整数**。2進,8進,10進,16進の整数が含まれる。
値が何進数で表されたものなのかくらいPython側が察して欲しいものだが,そういう訳にもいかないので,接頭辞(Prefix)をつけることでそれぞれを区別する。
マイナスの値を表現するときは,接頭辞の前に`-`をつける。
##### int: 2進数
接頭辞は`0b`。`0`と`1`のみが使われる。
例: `0b1010`
##### int: 8進数
紹介したは良いものの,実際に使う機会はほぼ無い。
接頭辞は`0o`で,`0-7`が使われる。
例: `0o7654`
##### int: 10進数
現実世界で大流行している表現。
接頭辞は無く,`0-9`が使われる。
例: `9876`
##### int: 16進数
整数の域で究極に情報量を高めた形。
接頭辞は`0x`で,`0-9`と`a-f`が使われる(`0,1,2,……8,9,a,b,……e,f,10,11,……`の順番)。
例: `0xfeba9876`
#### String
JavaにおいてString型の値はダブルクォート(`"`)で囲んだ文字列のこと。
(他のプログラミング言語と違い頭は大文字で書く必要がある)
なお,JavaのString型はint型のようなプリミティブ型ではなくそのラッパークラスとなっている。(詳しく知りたい人は[この記事](https://qiita.com/hiroki-harada/items/cb6fa4affffab2019cde)を読んでみてもいいかも)
#### boolean
真偽値のこと。
```true```が真で```false```が偽。
Cなどのプログラミング言語と違って型名が```bool```ではなく```boolean```となっていることに注意。
### 式
<!-- 詳しい人お願いします... -->
### 文とブロックとインデント
プログラミングにおける文とは何らかの処理をする1ステップのことです。
文には主にこの2つがあります。
##### 式文
式が文になったものを式文といいます。
```java
int a = 1 + 1; //1つの式がそのまま文となる
```
##### ブロック文
if文やfor文のように複数の処理を行う文をブロック文といいます。
この文は例外でセミコロンはつけません。
```java
{
//こういうやつ
}
if(条件){
//これもブロック文
}
```
##### インデント
インデントとはコードを見やすくするために半角スペース2個または4個をコードの中に入れることです。エディタにもよりますが基本的に```Tabキー```を押してインデントします。
Javaにおいてインデントは必須ではありませんが,インデントを付けないとコードがとても読みづらくなるので必ず付けましょう。
```java
int a = 1;
if(a > 0){
System.out.println("aは正の数");
a++;
}
```
こんな風にインデントを付けないと処理がブロックの外にあるのか中にあるのかとてもわかりにくいです。
```java
int a = 1;
if(a > 0){
System.out.println("aは正の数");
a++;
}
```
このようにインデントを付けるだけでコードの読みやすさは段違いになります。
エディタによっては保存時に自動でインデントを付ける機能があったりするので,慣れないうちは使用していきましょう。
#### スコープ
変数や関数を参照できる範囲のこと
詳しくは後述
### 変数の使い方
変数とは簡単に言うとデータを格納する箱のことである。
Javaでは```型名 変数名```で宣言する。
```java=
int a; // 変数の宣言
a = 1; // 変数の初期化
int b = 2; // 宣言と初期化は同時にできる
```
文字列も値なのでこのように宣言できる。
```java=
String a = "hogehoge";
// これで値「hogehoge」がaに代入される
```
また、変数への代入(上書き)は最小限にしよう。
### 四則演算
#### 演算子
基本的にどのプログラミング言語でも四則演算ができる。それぞれの演算記号は次のようになっている。
| 計算 | 数学 | Java |
| :----: | :----: | :----:|
| 足し算 | + | + |
| 引き算 | - | - |
| かけ算 | × | * |
| 割り算 | ÷ | / |
| 余り | mod | % |
ちなみに計算の順番は数学と同じである。また,()をつけると()の中が優先される。
```java
a = 1 + 3 * 4; // => 13
a = (1 + 3) * 4; // => 16
```
#### 複合代入演算子
Javaには変数への計算と代入が同時できる演算子がある。これはそれぞれ次のような形式で書く。
| 計算 | 実際の動き | 複合代入演算子 |
| :----: | :----: | :----:|
| 足し算 | a = a + b | += |
| 引き算 | a = a - b | -= |
| かけ算 | a = a * b | *= |
| 割り算 | a = a / b | /= |
| 余り | a = a % b | %= |
これは変数を加算したりするときに使われる。
```java
int a = 3;
a += 5; // a == 8
a -= 2; // a == 6
a *= 3; // a == 18
a /= 6; // a == 3
a %= 2; // a == 1
```
#### インクリメント,デクリメント
プログラミングでは変数に1を加算する,減算するといった処理がよく使われる。
そのため複合代入演算子よりも簡単に書ける式がある。
| 計算 | 実際の動き | 記号 |
| :----: | :----: | :----:|
| 1を足す | a += 1 | a++ |
| 1を引く | a -= 1 | a-- |
### 条件分岐
特定の条件によって処理内容を変えたい場合の方法などについて説明する。
#### boolean
真偽値のこと。
```true```が真で```false```が偽。
Cなどのプログラミング言語と違って型名が```bool```ではなく```boolean```となっていることに注意。
#### if文
条件式が真の場合,それ以外の場合に処理を実行する。
```java=
if(条件式1){
条件式1がtrueの場合に実行する
}else if(条件式2){
条件式1がfalseかつ条件式2がtrueの場合に実行する
}else {
条件式1,2がどちらもfalseの場合に実行する
}
```
#### 比較演算子
```java=
aとbは等価 a == b // "="は二つ!!!!
aはbではない a != b
aはb以上、aはbより大きい a >= b, a > b
aはb以下、aはbより小さい a <= b, a < b
```
#### 論理演算
二つ以上の条件式が全て真でないと真にならない(and)
二つ以上の条件式の中の一つでも真であれば真になる(or)
```java=
aが正の数でbも正の数(&&) a > 0 && b > 0
aかbのどちらかが正の数(||) a > 0 || b > 0
cではない(!) !c
```
### ループ処理
ここでは繰り返し処理をする記述について解説する。
#### while
条件式が真の場合のみ処理を繰り返し実行する。
```java=
while(条件式){
条件式がtrueの間実行され続ける
}
```
使用例
```java=
int i = 0
while(i > 10){
System.out.println(i);
i++;
}
```
#### for
決められた回数だけ処理を実行する。
```java=
for(int i = 0; i < 10; i++){
//実行文(10回実行される)
}
```
どういうことか解説する。
```java=
int i = 0;
```
これはループの回数を記録するための変数を定義している。
なお,プログラミングの世界では基本的に整数は0から始まることに注意。
```java=
i > 10;
```
これはループを続ける条件を示している。これが```true```の間ループし続ける。
```java=
i++
```
これは1回のループが終わる毎にする処理をここに書いている。
- **でも途中で抜け出したいときもある!**
そんなときは,`break`を使おう!
```java=
while(条件文){
実行文
if(条件式){
break;
}
}
#上の命令でこの while から脱出!
```
- **でも条件によってはもう一度戻りたい…**
でも大丈夫
`continue`を使おう!
```java=
for(int i = 0; i < 10 i++){
if(i % 2 == 1){
continue;
}
}
#この命令でforの次の行まで戻る
```
---
<small>これにより,メインプログラムを無限実行とかも可能ですよね。</small>
<small>例(応用):</small>
```java=
while(true){
実行文
//ここで何かを入力したり,描画しよう
// 脱出するためには
if(条件式){
break; //こう書くだけでok
}
}
```
### メソッド
いくつかの処理を一つにまとめたものをメソッドと言い、メソッドは一度定義してしまえば何度でもそのコード内で使えるので便利である。メソッドは以下のように定義する。なお,メソッドは必ずクラスの中に定義する。
```java=
int sum(int a, int b){
return a + b;
}
System.out.println(sum(2,4)) //6と出力される
```
まず最初に戻り値(ここでは```a + b```)の型を宣言する。
次にメソッド名を宣言する。
そして,```()```を付け,中に引数(関数の中で使う変数)の名前,型を宣言する。(引数は省略可能)
次にブロックの中に処理を書いていく。
最後にそのメソッドの呼び出し元に返すものを```return```の後に続けて書く。
これでメソッドが定義できる。
このとき,メソッドは
```java=
sum(1, 2) // 3
```
のようにして実行できる。
```return```の後に書いたものが返される(ここでは3)。
### 配列
配列とは複数のデータを一緒に扱う時に利用される。
配列を宣言するときは,中に入るデータの型,要素数を指定する必要がある。
```java=
int[] a = new int[3];
```
このコードは要素数が3のint型の配列を宣言している。
また,配列のそれぞれの要素にアクセスするには```配列名[添字]```としてアクセスできる。
このとき,添字は0から始まるので注意
```java=
a[0] = 1;
a[1] = 2;
a[2] = 3;
// a[3] = 4; これは範囲外参照でエラーになる
```