Print Friendly, PDF & Email

新人エンジニアが最初に知っておきたい変数とデータ型の使い方

なぜ、変数とデータ型が重要なのか、その理由。

この記事では、弊社の新人エンジニア研修の参考にJava8を解説します。

前回はJava言語の特徴を解説しました。

今回は、変数とデータ型について解説します。

変数はデータに名前(ニックネーム)を付けたものだと思ってください。

変数を使うことでプログラミングではいろいろなことができるようになります。

プログラミングに限った話ではありませんが、"名前"というものはすごい発明ですね。

もしも、名前というものがなければ世の中どれだけ不便になることでしょうか?

良い名前付けがプログラマーの仕事だという説もあるくらいです。

コンピュータの本質は計算機です。

計算機の役割は、データを処理することです。

その際、データを一時的に保管する場所が必要なのです。

その場所に名前を付けたものを変数(へんすう)といいます。

実際には、メインメモリ上にデータの保管場所が用意されるのですが、その場所を指定するのにメモリのアドレスを使用するとしたら大変です。

なぜなら、人間にとってアドレス表記は分かりやすいとはいえないからです。

そこで、分かりやすい変数名を付けて扱うのです。

例えるなら変数とは、引っ越しの荷物を入れるダンボール箱のようなものです。

新人エンジニア研修で変数をダンボール箱に例える

引っ越しのダンボールにはラベルを張っておかないと何だか分からなくて困りますね。

そのラベルが、変数名です。

また、段ボール箱は何を入れるかをあらかじめ決めておきますね。

食器と電化製品を一緒に入れたりはしないとおもいます。

同様に変数には何を入れるかあらかじめ決めておく必要があります。

これがデータ型です。

データ型により後でデータを取り出すときに間違いがなくなるのです。

変数というのは変わる数と書きます。

その名の通り、中身は変わっていく可能性があります。

それに対して変わらない数を定数(ていすう)といいます。

ここでは、変数、定数の順で学びます。

1.変数とは

次のプログラムを実行してみましょう。

ポイントは、文字型はシングルクォーテーション ’ で囲うところです。

後で見る文字列がダブルクオーテーション " で囲うのと区別してください。

どちらも何かで囲わないと変数名と区別がつかないから囲うのですね。

public class Example05 {

    public static void main(String[] args) {
        int data1 = 10;
        double data2 = 8.0;
        boolean flag = false;
        char c = 'C';
        System.out.println(data1);
        System.out.println(data2);
        System.out.println(flag);
        System.out.println(c);
    }
}

<結果を表示>

10
8.0
false
C

変数を作成することを「変数の宣言」といいます

例えば、以下のようにデータ型を明示して宣言します。

int data1;

変数に値を入れることを「値の代入」といいます

イコール記号を使います。

data1 = 10;

なお、変数の宣言と値の代入は以下のように1文に書くこともできます。

int data1 = 10;

変数に入っている値を見ることを「値の参照」といいます

System.out.println(data1);

今回ご紹介した変数はローカル変数といいます。

ローカル変数は、使用できる範囲(scope)が一番狭い変数で、{ }(ブロック)の中だけで有効です

ちなみに、英語のscopeには望遠鏡などから覗いた範囲という意味があります。

このあと、インスタンス変数、クラス変数という別種の変数が出てきますから混同しないようにしましょう。

なお、

int data1;
System.out.println(data1);

のようなプログラムを書くと

(中略)Uncompilable source code - 変数data1は初期化されていない可能性があります

と出力されます。

ローカル変数は初期化してから使わないといけません

初期化とは、そろばんで言えば「ご破算」のようなもので、変数の値をクリアしてから使うために必要な処理です。

ちなみに、直接記述される定数値のことを「リテラル」といいますので、あわせて覚えてください。

上記プログラムの10、8.0、false、Cはいずれもリテラルです。

Javaには整数、浮動少数点数、真偽、文字の4つのリテラルがあります。

Literary「文字通り」という英語表現を聞いたことのある新人エンジニアの方もいらっしゃるのではないでしょうか?

2.変数の宣言

変数の宣言では、変数に入れる値の型(type)をはじめに指定する必要があります

これが静的型付け言語のJavaの特徴です

<構文>

型名 変数名;

Javaでは変数やメソッド、クラスなどの名前のことを識別子と呼びます。

識別子は数字から始めてはいけないことは覚えておきましょう。

また、使える記号はアンダースコア(_)とドル記号($)のみです。

※余談ですが、Webアプリケーションの世界で存在感を誇っているPHPという言語は変数名の頭に$マークを必ず付けなければいけません。読む分には変数だということがすぐ分かって良いのですが、キーボードで打つには少し苦労をするようです。

良い名前付けは本当に大切です。

codic: プログラマーのためのネーミング辞書

では、手軽に日本語に適切な英語の変数名等をつけてくれますので是非活用してみてください。

また、英語の名詞には単数形と複数形がありますのでこれもうまく変数名に利用して下さい。

numとnumsでは意味するものが違うことをしっかり読み取るようにして下さい。

さらに、名前付けはユーザーが業務で実際に使用している名前を使うと確実です。

さらに、以下の予約語とリテラルは特別な意味のために予約されており、識別子には使えません。

これはつまり、intという名前の変数を作りたくてもできないということです。

もしも、

int int = 0;

のような書き方ができるとすると、以後、プログラム中に出てくる「int」という文字列がint型の宣言なのか、intという変数名なのか、分からなくなってしまうのですね。

以下は、Java8の予約語とリテラルの一覧です。今は覚えなくてよいですが、研修終了時には8割がた目にしたことがある状態になっているはずです。

abstract assert   boolean   break   byte   case   catch   char   class   const   continue   default   do   double   else   enum   extends   final   finally   float   for   goto   if   implements   import   instanceof   int   interface   long   native   new   package   private   protected   public   return   short   static   strictfp   super   switch   synchronized   this   throw   throws   transient   try   void   volatile   while

Java8のリテラル一覧

true false null

なお、予約語やリテラルはIDE上で特別な色で表示されますので、それと知ることができます。

3.Javaで使用できる型

Javaで使用できる型をまとめました。

データ型
booleantrue or false
byte8ビット整数 -128~127
char16ビットUnicode文字 ¥u0000~¥uFFFF
short16ビット整数 -32,768~32,767
int32ビット整数 -2,147,483,648~2,147,483,647
long64ビット整数 -9,223,372,036,854,775,808~9,223,372,036,854,775,807
float32ビット単精度浮動小数点数 -1.4E-45〜約340澗
double64ビット倍精度浮動小数点数 -4.9E-324〜約1.7澗

覚え方としては以下の通りです。

booleanはブール代数から来ています。当社の研修の場合、真理値表は別カリキュラムで聞いているはずです。

byteは8ビットなので名前通りです。

charは文字を意味するcharacterから。文字コードを表現しますからマイナスの範囲はありません。世界中の文字を一つの文字コード体系(Unicode)で表現しようとしているため、16ビットです。

intは整数を意味するintegerから来ています。

数値リテラルはデフォルトでint型の値として解釈されるので整数を表すときには最もよく使われます。

このintを基準にビット数を半分にしたのがshort、倍にしたのがlongです。

2進数で考えると名前の意味がよくわかりますね。

floatは浮動小数点数を意味するfloating point numberから。

そして、floatの2倍のビット数があるからdoubleです。

一般的に実数(の近似)を表現するときにはdoubleを使います。

データ型はとても大切な考え方です。

なぜなら、その変数に入る値の範囲がデータ型で決まるからです。

例えば、byte型の変数に128は入れられないのです。

また、人間にとっては整数の1も実数の1.0も同じですが、すべてを2進数で表現するコンピュータでは以下のような違いがあります。

10進数表現2進数表現(32ビット)
整数の10000 0000 0000 0000 0000 0000 0000 0001
実数の1.0f ※0011 1111 1000 0000 0000 0000 0000 0000

※floatとdoubleでも2進数表現は違います。したがってfloatの場合には数値の後ろにfをつける必要があります。doubleの場合には数値の後ろにdを付けることができますが、省略することが一般的です。

このように全くの別物です。

このことは、後で型変換(キャスト)という考えを学ぶときに必要になりますからここで理解しておきましょう。

ゆくゆくは全ての型を覚えたいですが、まずは、真偽値のboolean、整数値のint、浮動小数点数のdoubleの3つは最低限、覚えましょう

4.なぜ、変数を使うのか?

変数はなぜ必要なのでしょうか?

その答えを一言で言えば、変数を使うとデータに意味を与えることができ、変数の中身を使いまわすことができるのです。

以下のサンプルプログラムを見てください。

public class Example06 {

    public static void main(String[] args) {
        int yourAge = 22;

        System.out.println("あなたは今" + yourAge + "才です");
        System.out.println("あなたは10年後" + (yourAge + 10) + "才です");
        System.out.println("あなたは20年後" + (yourAge + 20) + "才です");
        System.out.println("あなたは30年後" + (yourAge + 30) + "才です");
        System.out.println("あなたは40年後" + (yourAge + 40) + "才です");
        System.out.println("あなたは50年後" + (yourAge + 50)+ "才です");
    }
}

<結果を表示>

あなたは今22才です
あなたは10年後32才です
あなたは20年後42才です
あなたは30年後52才です
あなたは40年後62才です
あなたは50年後72才です

yourAgeが年齢であるというのはその名前から明らかです。

これが「22」という数値ですと、何なのか分かりませんね。

このように名前のついていないリテラルをマジックナンバー(magic number:魔法の数値)と呼んで使用を戒めています。

変数yourAgeが使いまわされていますね。

もし、一つ年齢を重ねたとしたらどうでしょうか?

変数yourAgeを23で初期化すれば良いですね。

このように、変数を使うとデータに意味を与えることができ、変数の中身を使いまわすことができるのです。

なお、今回の"yourAge"のような変数名の書き方をラクダに見立ててキャメルケースといいます。

新人エンジニア研修

次のスネークケースとの対比で覚えましょう。

さらに長い変数名でもIDEを使っていれば入力補完(Ctrl + スペースキー)が効きますので入力は楽です。

5.定数を使うとき

変わりうるデータに付けた名前、それが変数でした。

一方、定数はその名の通り宣言時に決めた値をコードの中で後から変更することができないデータです。

変わらない(変わりにくい)データに付けた名前です。

したがって次のようなことはできません。

public class Example07 {

    public static void main(String[] args) {
        final int ADULT_AGE;

        ADULT_AGE = 20;

        ADULT_AGE = 18;
    }
}

それ以外は変数と同じと思っていただいて結構です。

例えば、次のサンプルプログラムを見てください。

public class Example08 {

    public static void main(String[] args) {
        final int ADULT_AGE = 20;

        System.out.println("成人年齢は" + ADULT_AGE + "才です");
        System.out.println("今年の成人は10年後" + (ADULT_AGE + 10) + "才です");
        System.out.println("今年の成人は20年後" + (ADULT_AGE + 20) + "才です");
        System.out.println("今年の成人は30年後" + (ADULT_AGE + 30) + "才です");
        System.out.println("今年の成人は40年後" + (ADULT_AGE + 40) + "才です");
        System.out.println("今年の成人は50年後" + (ADULT_AGE + 50) + "才です");
    }
}

<結果を表示>

成人年齢は20才です
今年の成人は10年後30才です
今年の成人は20年後40才です
今年の成人は30年後50才です
今年の成人は40年後60才です
今年の成人は50年後70才です

まず、定数にはfinal:「最後の」という修飾子を付けます。

そしてすべて大文字にして単語と単語の間はアンダーバーでつなぐのがJavaプログラマの慣習です。

アンダーバーでつなぐ定数名の書き方をスネークケースといいます。

新人エンジニア研修にスネークケースを説明

6.char型は整数であるということ

次のサンプルプログラムを見てください。

public class Example09 {

    public static void main(String[] args) {
        char a = 'A';
        a += 32;
        System.out.println(a);
    }
}

<結果を表示>

a

char型のA(ラージA)に対して32を足すとa(スモールa)になりました。

char型が整数(文字コード)だからできることです。

大文字と小文字を相互に変換したり、英数記号でランダムなパスワードを生成したり、平文(ひらぶん)を暗号化して読めなくしてまた戻したり、といった処理をすることがありますが、それができるのもchar型が整数だからなのですね.

ぜひ、リンク先のアスキーコードでAとaには32の差があることを確認して下さい。

7.クラスはパッケージに入れて管理する

今まで作成してきたJavaファイルがどこにあるかを確認します。

そうすると<デフォルトパッケージ>(別名:無名パッケージ)というところにあります。

実は、これはあまり良い保管場所とは言えません。

Javaファイルもファイルですから、一般的なコンピュータファイルと同様、何らかの分類基準を持ったフォルダで管理するのが良いのです。

そのフォルダのことをJavaではパッケージ(package)といいます。

また、パッケージごとに区切ることで別パッケージであれば、同じ名前のクラスを複数作ることができます。

この考え方を名前空間といいます。

みなさんも、拡張子まで含めると全く同じ名前のファイルを作れないことはご存知だと思います。

今はあまり実感が無いかもしれませんが、クラス名が重複してしまうということは良くあることです。

さらに、パッケージ管理することで、別のクラスからは見られないクラスやフィールド、メソッドを作ることができるのです。

前回オブジェクト指向では、モノの世界と同じようにプログラムの部品を組み合わせるというお話をしました。

部品Aと部品Bがつながるとまずい、ということもあるわけです。

たとえば車でも発火プラグとガソリンタンクが直接つながると大爆発ですね。

さらにパッケージ管理することで分かりやすいクラス体系になります。

つまり、パッケージ管理の目的を3つ挙げると以下のようになります。

①わかりやすい分類整理
②名前空間の提供
③不必要なものを公開しないことができる

③に関しては後ほどカプセル化のところでまとめていますのでそこでお話しますが、ここでも少し触れておきます。

Javaはセキュリティに強いとよく言われます。

その理由は、アプリケーションとOSとの直接のやり取りを禁じて、JVM経由でやり取りさせる点が一つ、そして、この③不必要なものを公開しないことができる、こともJavaのセキュリティ強化に役立っているのです。

この強力なパッケージ管理の仕組みがJavaが企業の大規模システム開発で採用されている理由の一つです。

ということでここからはクラスをパッケージに入れることにしたいと思います。

こんな風に。

package chap02;

public class Example01 {

    public static void main(String[] args) {
        char a = 'A';
        a += 32;
        System.out.println(a);
    }
}

1行目の「package chap02; 」がこのクラスの所属するパッケージを示しています。

パッケージの名前は同じものがあってはいけません。

全く同じ名前のパッケージがあると区別ができないからです。

そのため、例えば会社で作成するクラスの場合は自社のドメイン名を逆向きにした名前を使うのが一般的です。

例えば、当社の場合ですと

package jp.co.saycon.chap2;

のようになります。

しかし、みなさんは、新人エンジニア研修中ですからそこまでの配慮は結構です。

パッケージ名は講師の指示に従ってください。

パッケージを分けたため、過去に使用したExample01というクラス名が再び使用できています。

これ以降は、章ごとのパッケージにクラスファイルを作成するようにします。

8.別パッケージのクラスを呼び出して使用する

では、別のパッケージにあるクラスを使用してみましょう。

今の日時を表示してみます。

package chap02;

public class Example02 {

    public static void main(String[] args) {
        java.time.LocalDateTime d = java.time.LocalDateTime.now();
        System.out.println(d);
    }
}

<結果の例を表示>

2021-01-07T16:45:55.276

※Tは日付と時間の区切り記号です。

OSから取得した現在のシステム時刻が表示されました。

javaパッケージの中のtimeパッケージの中のLocalDateTimeクラスのnowメソッドを実行しています。

LocalDateTimeクラスは文字通り、あなたのOSが使っているローカルな日時のクラスです。

このようなクラスの指定方式を完全修飾クラス名(fully qualified class name:FQCN)といいます。

例えるなら、名字と名前を呼んで個人を特定するようなものです。

しかし、毎回、完全修飾クラス名を使うのは冗長に感じますね。

そこでこんな書き方ができます。

package chap02;

import java.time.LocalDateTime;

public class Example03 {

    public static void main(String[] args) {
        System.out.println(LocalDateTime.now());
    }
}

3行目にimportと書いて完全修飾クラス名が書いてありますね。

これで、クラス内ではクラス名だけを書けば良くなります。

クラス内では友達の下の名前だけを呼びたいものです。

新人エンジニアによくある勘違いとして、importの語感から「ここでクラスを読み込んで使えるようにしている」という誤解があります。

そうではなく、完全修飾クラス名を使わなくて済むためのimport記述です。

今後は、基本的にimport文を書いていくことにします。

また、IDEを使っているとクラスを簡単にインポートすることができますので、やり方を講師から聞いてください。

なお、

import java.time.*;

とアスタリスクを使うことでtimeパッケージのすべてのクラスをインポートすることができます。

ただし、インポートされるのはクラスだけでパッケージはインポートされません。

つまり、

import java.time.*;

と書いても、

java.time.chrono.JapaneseDate(和暦表示のためのクラス)などはインポートされませんので、ご注意ください。

import java.time.*;
import java.time.chrono.*;

と書くことで両方のパッケージをインポートすることができます。

※ただし、省略表記は非推奨です。クラス名まで特定してインポートすべきです。

※「import java.lang.*;」という記述は省略できます。いままでSystemクラスをインポートせずに使えたのもSystemクラスがjava.langパッケージに含まれるからです。java.langパッケージに含まれる主なクラスとしては他に文字列のString、便利な計算道具があるMathなどがあります。Javaの標準APIのクラスが多すぎてどこから手を付けていけばいいかわからないという人は、このjava.langパッケージかjava.utilパッケージあたりから学ぶと良いでしょう。ちなみに"util"はutility「便利な道具」といった意味です。

今回はJavaの変数とデータ型について見てきました。

次回は、演算子を学んでプログラムで様々な計算をさせてみましょう。

<まとめ:隣の人に正しく説明できたらチェックを付けましょう>

□文字型はシングルクォーテーション ’ で囲い、文字列はダブルクオーテーション " で囲うのは変数名と区別するためである

□変数を作成することを「変数の宣言」といい、変数に値を入れることを「値の代入」、変数に入っている値を見ることを「値の参照」という

□ローカル変数は、使用できる範囲(スコープといいます)が一番狭い変数であり、初期化してから使う

□変数の宣言では、変数に入れる値の型をはじめに指定する必要があり、それを静的型付けという

□まず最初に真偽値のboolean、整数値のint、浮動小数点数のdoubleの3つの型は最低限覚える

□パッケージ管理の目的は①わかりやすい分類整理②名前空間の提供③不必要なものを公開しないことができる、の3つ

まとめができたら、アウトプットとして演習問題にチャレンジしましょう。

問題2.変数とデータ型

0.処理の順番 以下のプログラムの実行結果を答えなさい。またその理由を説明しなさい 1.変数の初期化 以下のプログラムの実行結果を答えなさい。またその理由を説明しなさ…

【今回の復習Youtube】
 

JavaSE8の解説に戻る

最後までお読みいただきありがとうございました。

新人エンジニア研修のプログラムを見てみる

当社はJava講師を募集中です(サブ講師のため未経験者可)