【Java】型変換について第1弾

# 初めに
今度は型変換を中心に見ていく。少しややこしいところもあるので、実際にソースを実行しながら確認していく。

## int型からlong型への変換

```ruby:Java(Main.java)
public class Main {
	public static void main(String[] args) {
		int num = 10;
		long num_l = num;
		System.out.println(num_l);
	}
}
```

結果
```
10
```
上記ではint型の変数numをlong型の変数num_lに代入する処理である。特にエラーなども発生していない。

## int型からshort型への変換
では以下の場合はどうだろうか？実行してみよう。

```ruby:java(Main.java)
public class Main {
	public static void main(String[] args) {
		int num = 10;
		short num_s = num;
		System.out.println(num_s);
	}
}
```

結果
```
Exception in thread "main" java.lang.Error: Unresolved compilation problem: 
	型の不一致: int から short には変換できません

	at Main.main(Main.java:5)
```
なんとエラーが出てしまった。この原因について説明する。
まず以下の図を見てみよう。ここではint型の変数に128を格納しているイメージだ。例えばこの変数をbyte型に変換するとしよう。
byte型は第1弾で見たように-128~127の範囲しか数値を持つことができない。つまり、仮にここで代入したとしても範囲外の数値を持つことになる。そのようなことが生じないよう、上記のようにエラーが出る。

確かにbyte型では128という値を格納することはできないが、ソースの10はshort型に格納することは可能である。どうしても格納したい時は**キャスト演算子**を使おう。

キャスト演算子は変換先の型を()でくくり、代入する値の前に記載すれば良い。
```ruby:Java(Main.java)
public class Main {
	public static void main(String[] args) {
		int num = 10;
		short num_s = (short)num;
		System.out.println(num_s);
	}
}
```

```
10
```

今度はエラーにならずに済んだ。そうなるとint型の変数に格納した値128も同じようにbyte型の変数に格納できるのでは？一度やってみよう。

```ruby:Java(Main.java)
public class Main {
	public static void main(String[] args) {
		int num = 128;
		byte num_b = (byte)num;
		System.out.println(num_b);
	}
}
```

```
-127
```

あれ？エラーにはならなかったけど全く違う値が出たぞ…。

実はint型の値である128をbyte型にキャストしているのだが、byte型の範囲を超える値を格納するとオーバーフローが発生する。そのためbyte型の範囲の-127が表示される。ちなみにint型129はbyte型-127になる。少しややこしいが、short型でも同じことが起きた。

## int型からString型への変換
今度は数値から文字列に変換してみる。以下を実施してみよう。

```ruby:Java(Main.java)
public class Main {
	public static void main(String[] args) {
		int num = 32769;
		String str = (String)num;
		System.out.println(str);
	}
}
```

```
Exception in thread "main" java.lang.Error: Unresolved compilation problem: 
	int から String へキャストすることはできません

	at Main.main(Main.java:5)
```

キャスト演算子を使ったがエラーになってしまった。実は文字列と整数での変換は決まった書き方がある。以下で実施してみよう。

```ruby:Java(Main.java)
public class Main {
	public static void main(String[] args) {
		int num = 32769;
		String str = String.valueOf(num);
		System.out.println(str);
	}
}
```

```
32769
```

これだと問題無く実行できた。文字列から整数には**String.valueOf**、整数から文字列には**Integer.parseInt**を使うとそれぞれ変換が可能である。

## doubleからStringの変換
以下は実行できた。
```ruby:Java(Main.java)
	public class Main {
		public static void main(String[] args) {
			double num = 1.1;
			String str = String.valueOf(num);
			System.out.println(str);
		}
	}
```
```
1.1
```

## Stringからdoubleの変換
これは実際にやってみるとNumberFormatException例外が発生する。

```ruby:java(Main.java)
	public class Main {
		public static void main(String[] args) {
			String str = "1.1";
			double num_d = Integer.parseInt(str);
			System.out.println(str);
		}
	}
```

```
Exception in thread "main" java.lang.NumberFormatException: For input string: "1.1"
	at java.base/java.lang.NumberFormatException.forInputString(NumberFormatException.java:67)
	at java.base/java.lang.Integer.parseInt(Integer.java:668)
	at java.base/java.lang.Integer.parseInt(Integer.java:786)
	at Main.main(Main.java:4)
```

これはInteger.parseIntが整数にしか使えないからである。使用時は要注意。

## charからintへの変換

問題です、以下は実行できるでしょうか？ここではchar型の変数aをint型のnumに代入しているソースである。

```ruby:Java(Main.java)
	public class Main {
		public static void main(String[] args) {
			char a ='a';
			int num = a;
			System.out.println(num);
		}
	}
```

これまでの知識だとキャスト演算子も使っていないし、数値と文字の間は変換できないのでは？となると思う(私もそうだった)。結果を見てみよう。

```
97
```

このように数値に変換されている。実はchar型の値はUnicode値に基づいてint型に変換可能で、以下のように数値と文字は対応している。

a~Z→97~122
A~Z→65~90

ここはかなり間違えやすいので覚えておこう。

## intからcharへの変換
では逆はどうだろうか。以下を実行する。

```ruby:Java(Main.java)
	public class Main {
		public static void main(String[] args) {
			int num = 98;
			char a = num;
			System.out.println(a);
		}
	}
```

結果
```
Exception in thread "main" java.lang.Error: Unresolved compilation problem: 
	型の不一致: int から char には変換できません

	at Main.main(Main.java:4)
```

このようにエラーが発生する。ではキャスト演算子を使用してみる。
```ruby:Java(Main.java)
	public class Main {
		public static void main(String[] args) {
			int num = 98;
			char a = (char)num;
			System.out.println(a);
		}
	}
```

結果
```
b
```
今度は正しく結果が表示された。このことから、整数からchar型への変換にはキャスト演算子が必要なことが分かる。

## まとめ
* int型からlong型など、より範囲の大きい型に変換する時は代入のみでOK
* int型からshort型など、より範囲の小さい型に変換する時はキャスト演算子が必要
* キャスト演算子による型変換を実施した場合、範囲を超える値を格納するとオーバーフローが発生する(エラーではない)
* 整数や小数からString型への変換にはString.valueOfを使用する
* String型から整数への変換にはInteger.parseIntを使用する
* char型から整数への変換は代入のみでOK
* 整数からchar型への変換はキャスト演算子が必要