Javaの変数宣言や初期化、型について

##はじめに
この記事はこれからJavaを勉強する方に向けた私自身の理解している内容の記録です。

私の記事では下記のようにJavaの主要な機能を下記リストにまとめています。

・変数と型、型変換 現在ページ
・[変数のスコープ](https://qiita.com/pitan109/items/b30589bc4c2e8169734c)
・文字列の操作（準備中）
・配列の操作（準備中）
・演算子（準備中）
・条件分岐（準備中）
・繰り返し処理（準備中）
・[例外処理](https://qiita.com/pitan109/items/c9910edddc007126df41)
・クラスについて（準備中）
・抽象クラス（準備中）
・インターフェース（準備中）
・カプセル化（準備中）
・モジュールについて（準備中）

また、この記事を記載する上で、以下の記事を参考にしています。
https://www.sejuku.net/blog/22805


## 変数を宣言する
Javaで変数を宣言する時は、どのデータ型の変数かを記載する必要があります。

記入例

```java
int suuzi; // 数値型
boolean dotti; // boolean型 trueかfalseか
String mozi; // 文字型

System.out.println(mozi); //moziの中をみようとする
```

ただこの記載は宣言であり、初期化はできていません。Javaでは初期化できていない変数があるとエラーになります。

エラー文

```
エラー: 変数moziは初期化されていない可能性があります
```

##初期化

```java
int suuzi; // 数値型
boolean dotti; // boolean型 trueかfalseか
String mozi; // 文字型

suuzi = 10;
dotti = true;
mozi = "文字";

System.out.println(suuzi); //suuziの中をみようとする
System.out.println(dotti); //dottiの中をみようとする
System.out.println(mozi); //moziの中をみようとする
```

上記の用に中身をセットすると初期化となり、参照しようとしてもエラーにならなくなります。

実行

```
10
true
文字
```

##宣言+初期化
上記2つの工程はまとめて書くのも可能です。

```java
int suuzi = 10; // 数値型
boolean dotti = true; // boolean型 trueかfalseか
String mozi = "文字"; // 文字型

System.out.println(suuzi); //suuziの中をみようとする
System.out.println(dotti); //dottiの中をみようとする
System.out.println(mozi); //moziの中をみようとする
```
上記の用に 型 変数名 ＝ 中身 と記載すると、宣言と初期化が同時に行えます

実行

```
10
true
文字
```

## 型について
ここまでは宣言や初期化についてでしたが、ここからは型について記載していこうと思います。型は大きく分けて基本型と参照型の2つの種類があります。それぞれを見ていきましょう。

## 基本型

整数型
整数データを扱っています。サイズが多いほど多くの数値を扱えると思っていただければわかりやすいです。

| データ型 | サイズ | 値の範囲 |
|:--|:--|:--|
| byte | 1byte | -128～127 |
| short | 2byte | -32768～32767 |
| int | 4byte | -2147483648～2147483647 |
| long | 8byte | -9223372036854775808～9223372036854775807 |

この表を見るとサイズが大きいlongだけ使えばいいという意見もあると思いますが、表に記載されているbyte数の量を値の大きさ関係なく使用するので、少ない値が入るのがわかって入ればできるだけ小さいbyte数で抑えたいですね。私が記載するときはintぐらいが多いです。足りないのがわかって入ればlongにする感じです。byteやshortだと少なくて、値が入らない等のエラーが起きることもあると思います。

浮動小数点型
小数点を含む数値です。

| データ型 | サイズ | 値の範囲 |
|:--|:--|:--|
| float | 4byte | ±3.40E38～±1.40E45 |
| double | 8byte | ±4.94E-324～±1.79E+308 |

文字型
文字を扱っています。基本型のcharでは1文字を扱うのに使われています。

| データ型 | サイズ | 値の範囲 |
|:--|:--|:--|
| char | 2byte | 2byte の文字コード |

ブール型(boolean型)
真偽の論理情報を扱っています。trueかfalseのどちらかが入っています。

| データ型 | サイズ | 値の範囲 |
|:--|:--|:--|
|boolean|	1bit|	true または false|

この4つに分類されています。また基本型の特徴として、変数自身に値が入っているというのがあります。

## 参照型
上記以外の型で、基本は
String
配列
クラス
が対象となっています。こちらは基本型と違い、変数自身に値が入っているのではなく、入っている場所が入っています。参照型の例えは配列で考えるのがわかりやすいと思うので、
https://www.javadrive.jp/start/array/index3.html
上記リンクのコードを見て追っていきましょう。

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

        n = new int[2];
        System.out.println(n);

        n[0] = 10;

        m = n;
        System.out.println(m);
        System.out.println("n[0] = " + n[0]);
        System.out.println("m[0] = " + m[0]);
    }
}
```

実行すると

```
[I@69379752
[I@69379752
n[0] = 10
m[0] = 10
```

と表示されます。上2つで表示されているのは参照型でいう入っている場所が書いてあります。それが同じということは同じものを見ているので、nとmは同じ配列を見ていることになります。

基本型、参照型については以上です。次はキャストについて記載していきます。

## 型キャスト(型変換)
これらのデータ型は変換して渡してあげることもできます。実際に記載して見ました。

```java
int i = 30;

System.out.println(i);
```

上記の記載だと

```
30
```

と表示されますが、

```java
int i = 30;

System.out.println((double)i);
```

で実行すると

```
30.0
```

となります。整数型に小数点がついているので、浮動小数点型(double)に変わっています。

ただ変換できない例もあるので注意しましょう。

```java
class Main{
    public static void main(String args[]){
        String str = "文字";

        System.out.println((int)str);
    }
}
```

実行すると

```
エラー: 不適合な型: Stringをintに変換できません:
        System.out.println((int)str);
                                ^
```

と表示されます。参照型を基本型にするのは基本的にはできません。

数値型で言えば、大小関係にも関わってきます。

```java
class Main{
    public static void main(String args[]){
        int i = 2147483647; // intの最大値

        System.out.println(i);

        i += 1;

        System.out.println(i);
    }
}
```

実行すると

```
2147483647
-2147483648
```

となり、intの最大値を超えたのでオーバーフローしています。それを

```java
class Main{
    public static void main(String args[]){
        int i = 2147483647; // intの最大値

        System.out.println(i);

        System.out.println((long)i + 1);
    }
}
```

ここでiをキャストして、多い数値が入るlongにしてから1を足しています。これを実行すると

```
2147483647
2147483648
```

のようにオーバーフローせず、1が加算できています。

##昇格(プロモーション)
こちらも突然意図していないエラーになったりすることもあるので、こちらも解説を記載します。
byteやshortの型を計算したときは、なんとint型に突然なってしまいます。

```java
class Main{
    public static void main(String args[]){
        byte b1 = 10;
        byte b2 = 10;

        byte kekka = b1 * b2;
        System.out.println(kekka);
    }
}
```

```
test.java:8: エラー: 不適合な型: 精度が失われる可能性があるintからbyteへの変換
        byte kekka = b1 * b2;
                        ^
```

特にコードではintに変換等の記載はしていないのに、intからbyteへ変換のエラーが出ています。型が本当に変わっているのか、受け取るkekka変数の型をintに変えて見ましょう。

```java
class Main{
    public static void main(String args[]){
        byte b1 = 10;
        byte b2 = 10;

        int kekka = b1 * b2;
        System.out.println(kekka);
    }
}
```

```
100
```

出力できました。byteとbyteで計算していますが、その結果がintになっているのがわかると思います。数値を受け取るときには気をつけましょう。


##終わりに
この記事では型についてを多く掘り下げています。型についてはJavaの記載には常についてくるので、理解を怠らないようにしたいですね。