質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.84%

  • Java

    12487questions

    Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Java:変数が初期化されていない

解決済

回答 2

投稿

  • 評価
  • クリップ 0
  • VIEW 122

akamarukun

score 4

public static void main(String[] args) {
        // TODO 自動生成されたメソッド・スタブ

        int time = new java.util.Scanner(System.in).nextInt();
            String greeting;
        String message = ("ただ今の時刻は" + time + "時です");

        if (time >= 4 && time <=10) {
            greeting = "おはようございます";
        } else if (time >= 11 && time <= 17) {
            greeting = "こんにちは";
        } else if (time == 18) {
                greeting = "こんばんは";
        } else if ((time >= 19 && time <= 23) || (time >= 0 && time <= 3)) {
            greeting = "おやすみなさい";
        }

        System.out.println(greeting);
        System.out.println(message);

    }

以上のコードで実行すると、greetingが初期化されていない旨のコンパイルエラーがでます。
自分的には、しているつもりなんですが、どこがおかしいんでしょうか?
初心者なので、よろしくお願いいたします。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 2

+3

どの条件も成立しなかった場合は未設定の状態になり得ます。例えば間違って25と入れたら・・・

Javaでは変数の値は「必ず設定されていることがコンパイラーが納得しない限りは参照できません」コンパイラーを納得させるためには以下のようにしましょう。

String greeting;

if (...) {
  greeting = ...;
} else if (...) {
  greeting = ...;
} else if (...) {
  ...
} else {
  greeting = ...; // どの条件にも合致しなくても必ず値が設定されるようにしておく
  // or
  return ...;     // これ以降の実行を止めることを明示する
  // or
  throw ...;      // これ以降の実行を止めることを明示する
}
System.out.println(greeting); // 必ず設定されている保証の元で参照する

追記:本件に直接関係ないですが、mts10806さんがコメントくださった点について少し追記してみます。以前似たようなQ&Aがあったかと思いますが、自分は「変数のとりあえずの初期化」は避けます。理由はなるべく変数をfinalとして扱いたい(つまり途中で値が変わる変数にはしたくない)からです。

途中で値が変化する変数ももちろん使いますが使わずに済ませられることも多いです。Javaの仕様はいくぶん厳格でfinalでない変数は内側のスコープからアクセスさせてやんないという仕様なのでそういう点からもなるべくfinalにしておこうと考えます。(本末転倒な論理ですね。本来は極力finalにしようってのが本質だと思います。)

String greeting; // (A)
if (...) {
  greeting = ...;
} else if (...) {
  greeting = ...;
} else {
  greeting = ...;
}
Button button = new Button("Hi");
button.setOnAction(ev -> System.out.println(greeting)); // <= (B)

例えば上のコードだとgreetingはfinalと見做してくれるためラムダ式の本体(B)で参照できます。これを(A)で「とりあえず初期化」としてしまうとfinalではなくなるため(B)で参照できなくなるという「面白くないこと」になります。

この辺り言語によって違うようですが、JavaScript, Python, Scala, C#などだとfinalじゃなきゃ内側のスコープで参照できないという制約はありません。どうも大半のモダンな言語はそういう制約は課してないようです。しかしこれがJavaだと「副作用を持たない行儀良いコードだけ外側のスコープの変数をアクセスさせてやる」といった気難しいオジイチャンのような仕様です。

「finalでないものがアクセスできないなんて言語機能が足りてないんじゃないの?」と思ったこともありますが、「まぁまぁそういわずfinalにすることを意識する方がいいと捉えよう」と前向きに考えるようにしました。

(finalじゃない変数しか内側からアクセスできないってのはJavaぐらいかも知れません。実際は行儀良いコードにだけ内側からのアクセスを許すという意図があるのか、単に実装がめんどかったのでまぁできなくていいよねぐらいのノリなのか本当のところは自分には分かりません。ただ変更可能なローカル変数を内側のスコープからアクセスできるようにするとそれなりの性能的代償があるとは思います。ScalaやC#はその代償をプログラマーが意識していない実装の中でこっそり支払っています。そうした細かい点を気にせず制限なく使える言語がいいのか、制約がある理由を把握した上で使う方がよいのか・・・自分には何とも言えません。)

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/05/29 11:06

    解決いたしました。ご丁寧にありがとうございます。

    キャンセル

  • 2018/05/29 11:15

    個人的に回答者さんにお聞きしたいのですが、
    elseを用意して必ずどこか通るようにするのと、先に初期値を入れておくのと どちらがベターでしょうか?
    要件次第とはなると思うのですけど。
    そういえば、初期値を入れた上でもelseを設置するケースもありますね。

    キャンセル

  • 2018/05/29 15:48

    追記ありがとうございます。大変参考になりました。

    キャンセル

checkベストアンサー

0

そのif文全部に合致しない場合、初期化されませんね。
そのため、そのエラー(ワーニング?)がでています

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/05/29 11:05

    意味が分かりました。ありがとうございます。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.84%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

  • 解決済

    Java エラー 初心者

    public class part01 { public static void main( String[] args ) { String name =

  • 解決済

    java コンパイルエラーについて

    初投稿ですjavaを勉強しはじめて一週間程度です 発生している問題・エラーメッセージ elseへのifがありませんというエラーへの対処法 該当のソースコード class

  • 解決済

    会員情報システム(Java)での作り方

    javaで会員情報システムのようなものを作りたいです。 下記の実行結果(コマンドプロンプトで実行)になるような、登録プログラムを作成したいのですが、作成方法が分かりませんので、教

  • 解決済

    初期化メソッドのスマートな書き方

    現在,プログラム内に次のような,int型配列とdouble型配列の全ての要素に0を入れる(初期化する)というメソッドを書いています. 見てわかる通り,非常に冗長な書き方です.簡潔

  • 受付中

    javaの文字型を日付型に変えたい

    Dec 26, 2016 という文字列をdata型に変換したいです どうすればできますか?

  • 解決済

    javaでのgetInt

    javaでhsqldbに接続しています。 statement = getConnection().createStatement(); ResultSet resultSet

  • 解決済

    引数なしで実行するとエラーになる原因がわかりません

    前提・実現したいこと Javaで引数あり・引数なしでも実行できるようなプログラムを書きました 発生している問題・エラーメッセージ 「java.lang.ArrayInde

  • 受付中

    ジャンケンゲーム

    ジャンケンゲームを作ってます。 <ルール> コンピュータに3回負けたらゲーム終了! 負けるまでゲームは続く! 数字を入力するとループが止まりません。 あと、winlo

同じタグがついた質問を見る

  • Java

    12487questions

    Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。