Java学習ノート_140707（mainメソッド、入力プログラム）

# `public static void main(String[] args) `の意味
`String[] args` は文字列の配列で変数名argsを引数に持つ、ということ。
値返さないのなら、引数書かなくても大丈夫なのかと思って省略してみたり、intの配列を渡したりしてみたのだが、下記のようなエラーが出る。

> エラー: メイン・メソッドがクラスSampleで見つかりません。次のようにメイン・メソッドを定義してください。
   public static void main(String[] args)
またはJavaFXアプリケーション・クラスはjavafx.application.Applicationを拡張する必要があります

* [Javaの冒頭で始められる 「public static void main (String\[\] args)」 の用途...]
(http://detail.chiebukuro.yahoo.co.jp/qa/question_detail/q1436745054;_ylt=A2RAEE6r5rlTDWoA0d3i_vN7?pos=1&ccode=ofv)

* [javaのプログラミングの先頭に記述をする、 「public static void main(String\[ \]...](http://detail.chiebukuro.yahoo.co.jp/qa/question_detail/q1112451076;_ylt=A2RAEExc5rlTwU8AdQji_vN7?pos=1&ccode=ofv)

* [What is “String args[]”? in Java
](http://stackoverflow.com/questions/890966/what-is-string-args-in-java)

コマンドラインで実行時に引数を渡せて、その引数がString型の配列というのはわかるのだけど、検索しても、なぜ配列の引数が必要なのかは特に書かれていないし、知恵袋は見当違いのことでみんな説教したり回答してる気がする。その点、stackoverflowはプログラミングで困ったことをシェアして解決するのが目的なので雰囲気やさしい感じ（でもよくわからない）。

# Javaで定義されている変数の範囲外の値の扱い

変数の持つ値はその数を超えるとループする

```java:VarLoop.java
byte b = 127;
b++;
System.out.println(b); // -128
```

こう書いてもエラーになる。

```java:
System.out.println((byte)128); //-128
```
最小値⇔最大値。ウケる。

# 文字（列）入力プログラム

`System.out.print`や`System.out.println`が出力としたときに、入力のプログラムは`System.in.read`。入力プログラムの書き方はJavaのバージョン（1.4/1.5以降）によって違う。

## JDK 1.4以前

```java:InputSample.java
import java.io.IOException;

public class InputSample {
    public static void main(String[] args){
        try{
            int moji;
            moji = System.in.read();
            System.out.println(moji);
        }
        catch(IOException e){
            System.out.println("error");
        }
    }
}
```

半角1文字の入力をうけてUnicodeのint値を返す。

Eclipse/コマンドプロンプトでコンパイル・実行後、コンソールに入力する。プロンプトが特に出ないのでわかりづらい（Eclipseでわかんなすぎてコマンドプロンプトで実行した）。`try{...}catch{...}`は例外処理がある場合は書く。`import java.io.IOException;`はJavaのライブラリ。

```java:InputSample3.java
import java.io.IOException;
import java.io.InputStreamReader;

public class InputSample3 {

	public static void main(String[] args) {
		try{
			int moji;
			InputStreamReader input;

			System.out.println("コンソールに何か1つ文字を入力してください");

			input = new InputStreamReader(System.in);
			moji = input.read();
			System.out.println(moji);
		}
		catch(IOException e){
			System.out.println("error");
		}
	}
}

```
わかりづらいので、`System.out.println`でプロンプトみたいなもの表示した。全角で文字コードが表示されるようになった（前のサンプルでも入力はできるみたいだけど、正しい文字コードではない）。

「あ」が「 12354 (0x3042)」になる。が、このままだとなんだかわかんない。

> Javaではデータの入出力にストリームという概念を用います。
ストリームを直訳すると【流れ】です。
InputStreamは【入力データの流れ】という意味です。
InputStreamReaderは【入力データの流れを読み取る存在（クラス）】と解釈できます。
キーボードを押下すると、入力された情報がプログラムへと流れていきます。
そして、その情報を読み取れという命令としてreadが使われます。

次が複数文字の入力を受け取って、コンソールに表示するサンプル。

```java:InputSample4.java
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.BufferedReader;

public class InputSample4 {
	public static void main(String[] args) {
		try{
			String str;
			BufferedReader reader;

			System.out.println("コンソールに何か文章を入力してください");

			reader = new BufferedReader(new InputStreamReader(System.in));
			str = reader.readLine();
			System.out.println(str);
		}
		catch(IOException e){
			System.out.println("error");
		}
	}
}

```

importが増えてるのと、newがnewの中に入ってるのが変な感じ。`BufferedReader`と`InputStreamReader`は、[コアAPIドキュメント](http://docs.oracle.com/javase/jp/8/api/)で確認した。個別のストリームをバッファリングして貯めこむイメージなのか。

```java:
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
```

は定形の書き方っぽい。

# 数値入力プログラム

```java:InputSample.java

public class InputSample {

	public static void main(String[] args) {
		try{
			String s = "156";
			int value = Integer.parseInt(s);
			System.out.println(value * 2);
		}
		catch(NumberFormatException e){
			System.out.println("数値変換に失敗しました。");
		}
	}
}
```

大体一緒。Integer.parseInt以外にもDouble.parseDoubleとかほぼあるっぽい。

BMIを計算するプログラム。

```java:BMIsample.java
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class BMISample {

	public static void main(String[] args) {
		try{
			//身長を確認する
			System.out.println("あなたの身長をcmで入力してください");
			BufferedReader value1 = new BufferedReader(new InputStreamReader(System.in));
			String str1 = value1.readLine();
			double height = Double.parseDouble(str1)/100;

			//体重を確認する
			System.out.println("あなたの体重を入力してください");
			BufferedReader value2 = new BufferedReader(new InputStreamReader(System.in));
			String str2 = value2.readLine();
			double weight = Double.parseDouble(str2);

			//計算して表示
			double bmi = weight / (height * height);
			System.out.println(bmi);
		}
		catch(IOException e){
			System.out.println("文字入力エラーです。");
		}
		catch(NumberFormatException e){
			System.out.println("数値変換に失敗しました。");
		}
	}
}
```
`BuffreredReader.readline();`の処理を忘れがち。変数整理したりしたものが下。BufferedReaderは入力の器なので、基本的に一度作ったら使いまわしていいようだ。

```java:BMISample2.java
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class BMISample2 {

	public static void main(String[] args) {
		try{

			BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));

			//身長を確認する
			System.out.println("あなたの身長をcmで入力してください");
			String s = reader.readLine();
			double height = Double.parseDouble(s)/100;

			//体重を確認する
			System.out.println("あなたの体重を入力してください");
			s = reader.readLine();
			double weight = Double.parseDouble(s);

			double bmi = weight / (height * height);

			//計算して表示
			System.out.println("あなたのBMIは、" + bmi +  "です。");

		}
		catch(IOException e){
			System.out.println("文字入力エラーです。");
		}
		catch(NumberFormatException e){
			System.out.println("数値変換に失敗しました。");
		}
	}

}

```

## JDK 1.5以降

Scannerクラスが使える。

```java:ScannerSample.java
import java.util.Scanner;

public class ScannerSample {

	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);

		System.out.println("名前を入力してください。");
		String text = sc.next();
		System.out.println("こんにちは、 " + text + " さん。");

		System.out.println("何か数値を入力してください。");
		float num = sc.nextFloat();
		System.out.println("値を2倍すると" +  num * 2 + "ですね。" );
	}
}

```

`try{...}catch{...}`の構文が不要（いいのか悪いのか、よくわからない）。

#### Scannerクラスのメソッド

* next(); //文字列入力
* nextInt(); //整数値入力
* nextDouble(); //double値入力

他、float long short byteもあり。



# 参考書籍、Windowsなど

## カッとなって 

* [半年くらい仕事でAndroidアプリ開発していて役に立った本](http://qiita.com/shikato/items/5e03a086fc1b42936d7c)

買った。有用だし、アフィリエイトIDつけてもいいと思う。

## WindowsとMacで

キーボードの配列が違いすぎて、いちいち文字変換で手間取ってしまう。日本語入力か直接入力であればそれほどつまらないんだけど、どうしたものか。打鍵音静かなBluetoothキーボードとかあったら買ってしまいそう。







★┷┓
┃も┃
┃っ┃
┃と┃
┃Ｊ┃
┃ａ┃
┃ｖ┃
┃ａ┃
┃が┃
┃書┃
┃け┃
┃る┃
┃よ┃
┃う┃
┃に┃
┃な┃
┃り┃
┃ま┃
┃す┃
┃よ┃
┃う┃
┃に┃
┗━★