著者は、フリーかつオープンソースファンドを、寄付の一環としての寄稿プログラムの一環として選択しました。
紹介
Javaは静的型付けのプログラミング言語です。これは、変数を作成するときにそのデータ型も指定する必要があることを意味します。これは動的型付けの言語とは対照的であり、そのような言語にはPHPが含まれます。動的型付けの言語では、変数のデータ型を指定する必要はなく、それは安心感のように感じられるかもしれません。
しかし、データ型を知り、適切に使用することで、開発者はコードを最適化することができます。なぜなら、各データ型には特定のリソース要件があるからです。また、1つのデータ型を指定して異なる型を保存しようとした場合、間違ってしまう可能性があるため、コンパイルできなくなります。したがって、静的型付けの言語では、テスト前でもエラーを検出することができます。
Javaには2つのデータ型があります:プリミティブ型と参照型(または非プリミティブ型とも呼ばれます)。このチュートリアルでは、Javaプログラムで情報を保存および使用するために変数を使用し、Javaでよく使用されるいくつかのデータ型について学びます。これはすべてのデータ型の包括的な概要ではありませんが、このガイドを使ってJavaで利用可能なオプションに慣れることができます。
前提条件
このチュートリアルを進めるためには、以下が必要です:
-
例に従ってJavaプログラムを実行できる環境。ローカルマシンでこれをセットアップするには、次のものが必要です:
- マシンにインストールされたJava(バージョン11以上)と、Java Development Kit(JDK)によって提供されるコンパイラが必要です。UbuntuとDebianの場合は、当社のチュートリアル「Ubuntu 22.04にAptを使用してJavaをインストールする方法」のオプション1の手順に従ってください。MacやWindowsを含む他のオペレーティングシステムの場合は、Javaインストールのダウンロードオプションをご覧ください。
- コード例のコンパイルと実行には、このチュートリアルではJavaシェルが使用されています。これは、コマンドラインから実行されるRead-Evaluate-Print Loop(REPL)です。JShellを始めるには、「JShellの紹介」ガイドをご覧ください。
-
Javaおよびオブジェクト指向プログラミングに精通していることが必要です。これについては、当社のチュートリアルで確認できます。Javaで最初のプログラムを書く方法。
プリミティブタイプ
Javaのプリミティブタイプは、Javaで最も単純で基本的なデータ型です。数値や文字などの生の値を表します。最もよく使用されるプリミティブデータ型には、int
(整数)、boolean
(ブール値)、およびchar
(文字)があります。残りのデータ型は公式のJavaデータ型のドキュメントで見つけることができます。
整数
整数は負の数と正の整数の両方です。Javaでは、それらを格納するためにint
を使用します。 int
は、ほとんどの目的に十分な大きさの数値を収容できます: -2,147,483,648
から2,147,483,647
まで。
int
の使用例を見てみましょう:
int theAnswer = 42;
プリミティブタイプは常に小文字で始まります(int
)。 Javaの構文ルールでは、まずデータ型(int
)を指定し、その後に変数名(theAnswer
)を指定する必要があります。その後、等号(=
)で値42
を変数に割り当てます。
データ型に関係なく、特殊な文字を前に付けずに変数名を直接指定して使用します。これはJavaが変数として認識できるためです。
注意:このチュートリアルの変数theAnswer
および他のすべての変数の名前は、キャメルケースで記述されています。厳格な要件はありませんが、これはJavaで受け入れられている命名規則です。
変数を宣言した後、次のようにメソッド内で参照して使用することができます:
int theAnswer = 42;
System.out.println("The answer to all questions is " + theAnswer);
2行目では、System.out
パッケージの組み込みメソッドprintln
を使用してコンソールにtheAnswer
を表示します。これは変数が期待どおりに宣言されているかをテストするための最も簡単な方法です。
このコードを実行するには、Javaシェルツールを使用します。Javaをインストールした後、ローカルコンピューターでターミナルまたはコマンドプロンプトを開き、jshell
と入力します:
- jshell
出力は次のようになります:
Output| Welcome to JShell -- Version 11.0.16
| For an introduction type: /help intro
jshell>
このチュートリアルのコード例をコンソールに貼り付けることができます。終了する場合は、jshell
と入力して終了します:/exit
。
int
を宣言して使用するには、次の行をjshell
コンソールに貼り付けます:
- int theAnswer = 42;
- System.out.println("The answer to all questions is " + theAnswer);
次のような出力が表示されます:
OutputtheAnswer ==> 42
The answer to all questions is 42
この出力は、int
型の変数theAnswer
が正しく42に設定されていること(theAnswer ==> 42
)を確認します。また、theAnswer
をメソッドに渡して使用し、メソッドが期待する変数の値を生成しました。
ブール
ブール値はtrue
またはfalse
です。Javaでは、それらを保存するためにboolean
を使用します。たとえば、Javaが楽しいかどうかを定義するboolean
変数を作成しましょう:
boolean isJavaFun = true;
変数isJavaFun
をtrue
として定義します。代替のboolean
値はfalse
です。
上記の変数を使用して、次のように文Java is fun: true
を出力できます:
- boolean isJavaFun = true;
- System.out.println("Java is fun: " + isJavaFun);
jshell
でこれらの行を実行すると、次の出力が生成されます:
OutputisJavaFun ==> true
Java is fun: true
int
の例と同様に、println
メソッドは括弧内で提供された引数を出力します。プラス記号(+
)は文字列「Java is fun:」を変数isJavaFun
と連結または結合するために使用されるので、実際には1つの引数、すなわち文字列Java is fun: true
です。
文字
単一の英数字文字を保存するには、char
を使用します。たとえば:
char firstLetter = 'a';
文字a
が単一引用符で囲まれていることに注意してください。単一引用符はchar
値にのみ使用できます。ダブルクォーテーションは、後で学習するように、文字列に使用されます。
このセクションで見たように、プリミティブ型変数の宣言と使用は、整数などの単純な値を表すため、簡単です。これらの値は使用する準備ができており、オブジェクトの作成、メソッドの呼び出し、などの追加の操作は必要ありません。
参照型
このシリーズの最初のチュートリアルであるJavaで最初のプログラムを書く方法では、Javaコードがクラスに組織され、これらのクラスがオブジェクトを作成するテンプレートとして使用されることを学びました。そのようなオブジェクトが変数に割り当てられると、これらのオブジェクトを指し示すか参照しています。これらの場合、変数は参照型として分類されます。これらの変数は非プリミティブとも呼ばれますが、プリミティブ型の変数はオブジェクトを指すことはできません。
オブジェクトは、高度なプロパティを持ち、メソッドをトリガーすると動作する能力があるため、強力です。しかし、それらにポイントする変数がないと、これらのオブジェクトはアクセスできず、実際には使用できません。これが、参照型変数がJavaとオブジェクト指向プログラミング全体に不可欠である理由です。
注意:参照型はクラスから作成されたオブジェクトを指します。混乱を避けるため、次の例では参照型と作成されたオブジェクトは同じクラスになります。
しかし、複雑なプログラムでは、これがまれです。Javaでは、インターフェイスは特定の動作の要件のグループであり、これらの要件は1つ以上のクラスで満たすことができます。インターフェイスの要件を満たすクラスは、このインターフェイスを実装したと言います。したがって、複雑なプログラムでは、インターフェイスの参照型の変数を宣言することが一般的です。これにより、変数が具体的な動作の実装に結び付けられることなく、変数が示すべき動作を指定できます。これにより、変数が使用される方法を変更せずに、変数が指す実装を簡単に変更できます。この複雑な概念は、Javaシリーズの別のチュートリアルで行われる継承および多様性に関するより高度なトピックの一部です。
ある程度の原始的な型しかない一方で、参照型は事実上無制限です。なぜなら、クラス(およびインターフェース)の数に制限がなく、各クラスが参照型を表しているからです。Javaには基本的な機能を提供する多くの組み込みクラスがあります。最も頻繁に使用されるものは、コアのjava.lang
パッケージにあります。このセクションでは、その中からいくつかを見ていきます。
String
クラス
String
クラスは、文字の組み合わせを表します。String
または他の参照型変数を宣言するには、まずその型を指定してから名前を指定します。その後、等号を使用して値を割り当てます。これまでは原始的な型と同じような操作です。ただし、参照型はオブジェクトを指しますので、まだオブジェクトが作成されていない場合はオブジェクトを作成する必要があります。以下は例です:
String hello = new String("Hello");
hello
は、参照型String
を持つ変数の名前です。これを新しいString
オブジェクトに割り当てます。新しいString
オブジェクトは、new
キーワードとクラスの名前(この場合はString
)を使用して作成されます。クラスString
は大文字で始まります。慣例として、すべてのクラスおよびそれに伴う参照型は大文字で始まります。
各クラスには、新しいオブジェクトを作成するために使用される特別なメソッドがあります。constructorクラス名の末尾に括弧(()
)を追加することで、このコンストラクタを呼び出すことができます。コンストラクタはパラメーターを受け取る場合があります。例えば、"Hello"
パラメーターがString
のコンストラクタに適用される場合です。
hello
変数が期待どおりに動作することを確認するには、println
メソッドに再度渡します。次のようにして:
- String hello = new String("Hello");
- System.out.println(hello);
jshell
でこれらの行を実行すると、次の出力が生成されます:
Outputhello ==> "Hello"
Hello
今回は、出力がhello
変数がHello
に設定されていることを確認します。その後、同じHello
が新しい行に印刷され、println()
メソッドがそれを処理したことが確認されます。
Wrapper Classes
前のセクションでは、頻繁に使用されるString
参照型を扱いました。他の人気のある参照型は、プリミティブ型のラッパーと呼ばれるものです。ラッパークラスは、プリミティブデータをラップまたは含んでいるため、その名前があります。すべてのプリミティブ型にはラッパーの対応があり、ここにいくつかの例があります:wrapper class
Integer
:int
値をラップするために使用されます。Character
:char
値をラップするために使用されます。Boolean
:boolean
値をラップするために使用されます。
これらのラッパーは、単純なプリミティブ値を強力なオブジェクトにアップグレードするために存在しています。各ラッパーには、それが設計された値に関連する使用準備ができたメソッドがあります。
例として、Integer
を探索します。前のセクションでは、new
キーワードを使用してString
オブジェクトを作成しました。ただし、一部のクラスでは、オブジェクトを取得するための特殊なメソッドの使用が提供されており、さらに推奨されています。そして、Integer
もその1つです。 Integer
の場合、特殊なメソッドの使用は主にリソースの最適化に関するものですが、他の場合では複雑なオブジェクトの構築を簡素化するためのものです。
次の例では、valueOf
メソッドを使用して、値42
を持つInteger
変数theAnswer
を作成します。
- Integer theAnswer = Integer.valueOf(42);
- System.out.println(theAnswer);
jshell
で、以下の出力が表示されます:
OutputtheAnswer ==> 42
42
Integer
メソッドvalueOf(42)
を呼び出すことで、Javaにこの値を持つオブジェクトを取得するように指示します。裏側では、Javaは既にその値を持つオブジェクトがキャッシュに存在するかどうかをチェックします。存在する場合、オブジェクトはtheAnswer
変数にリンクされます。存在しない場合、新しいオブジェクトがtheAnswer
変数のために作成されます。
パフォーマンスのために、多くの組み込みクラスがこのようなメソッドを提供しており、使用が推奨されています(必須ではありません)。Integer
の場合は、まだnew
キーワードを使用してオブジェクトを作成することができますが、非推奨の警告が表示されます。
さらに、String
とラッパーに加えて、java.langパッケージの概要で見つけることができる他の便利な組み込み参照型もあります。これらのより高度な参照型を完全に理解するには、追加の説明や事前知識が必要です。そのため、Javaシリーズの次のチュートリアルでいくつかをカバーします。
リテラル
リテラルは、コード内で直接使用できる固定値を表します。そのため、プリミティブ型と参照型の両方に割り当てることができます。いくつかの種類のリテラルがあり、以下のように分類することができます。
プリミティブ型のリテラル
すでにプリミティブ型のセクションでいくつかのリテラルを使用しています。各プリミティブ型には、例えば、42
、'a'
、true
のようなリテラルがあります。 42
のような整数は整数リテラルです。同様に、'a'
のような文字は文字リテラルであり、true
とfalse
はブールリテラルです。
プリミティブ型のリテラルは、参照型の値を作成するためにも使用することができます。 int
リテラルは、Integer.valueOf(42)
のコードで Integer
オブジェクトを作成するために使用されました。これには短縮形もあり、次のように値を直接割り当てることもできます:
Integer theAnswer = 42;
42
は整数リテラルであり、任意の整数のように、追加の文なしで theAnswer
変数に直接割り当てることができます。これは便利なので、Integer
の宣言はよくこのように見られます。
この短縮記法は、他のプリミティブ型リテラルとそれに対応する参照型にも適用されます。たとえば、Boolean
の場合は次のようになります:
Boolean isFun = true;
true
はリテラルであり、Boolean
型の isFun
変数に直接割り当てることができます。同様に、false
リテラルも同じ方法で割り当てることができます。
文字列リテラル
String
参照型には特別なリテラルもあり、その値を囲む二重引用符で認識されます。この例では、"Hello, World!"
です:
String helloWorld = "Hello, World!";
リテラルを使用すると、よりシンプルで短くなりますので、多くのプログラマーがそれを好んで使用します。ただし、参照型のセクションで既に行ったように、新しい String
オブジェクトを使用して String
変数を宣言することもできます。
Nullリテラル
もう1つ重要なリテラルがあります:null
、これは値の欠如またはオブジェクトの非存在を表します。Null
は、オブジェクトを指す代わりにnull
を指す参照型を作成することを可能にします。null
はすべての参照型に使用できますが、任意のプリミティブ型には使用できません。
null
リテラルには1つの注意点があります:変数をそれで宣言できますが、適切な非null値を再代入するまでこれらの変数を使用できません。 null
値を持つ参照型変数を使用しようとすると、エラーが発生します。 以下に例を示します:
- String initiallyNullString = null;
- System.out.println("The class name is: " + initiallyNullString.getClass());
jshell
でこのコードを実行しようとすると、次のようなエラーが表示されます:
OutputinitiallyNullString ==> null
| Exception java.lang.NullPointerException
| at (#4:1)
使用しているオペレーティングシステムとJavaバージョンによって、出力が異なる場合があります。
エラーjava.lang.NullPointerException
がスローされます。これは、変数initiallyNullString
(nullオブジェクトを指す)でString
メソッドgetClass()
(クラス名を返す)を呼び出そうとしているためです。
注意: 簡単のため、java.lang.NullPointerException
をエラーと呼んでいますが、厳密には例外です。 例外とエラーについて詳しくは、チュートリアル「Javaの例外処理」を参照してください。
エラーに対処するには、initiallyNullString
の値を次のように再割り当てする必要があります:
- String initiallyNullString = null;
- initiallyNullString = "not null any longer";
- System.out.println("The class name is: " + initiallyNullString.getClass());
修正された新しいコードは、以下の出力を表示します:
OutputinitiallyNullString ==> null
initiallyNullString ==> "not null any longer"
The class name is: class java.lang.String
上記の出力は、initiallyNullString
が最初にnull
であり、その後"not null any longer"
を含む新しいString
オブジェクトになる様子を示しています。次に、インスタンス化されたオブジェクトに対してgetClass()
メソッドが呼び出されると、java.lang.String
が取得されます。ここで、String
はクラス名であり、java.lang
はそのパッケージです。最後に、完全で意味のあるメッセージが表示されます:"The class name is: class java.lang.String"
。
このようなnull
値の宣言は、古いコードではより一般的です。通常、後で実際の値を割り当てるために使用され、通常は後者を決定するロジックを経ています。ただし、Javaバージョン8以降では、Optionalと呼ばれる新しい参照型があり、通常はnull
が使用されていた場合に適しています。
ローカル変数型推論
ここまで、Javaで変数を定義するために一般的なデータ型を使用してきました。しかし、Java 10では、ローカル変数型推論と呼ばれる新機能が導入されました。これにより、新しい変数の前にキーワードvar
を使用できます。この機能により、Javaはローカルコンテキストからデータ型を(つまり、自動的に推測して)推論します。型推論は、以前に説明した変数の定義の冗長性と対照的であるため、議論の的です。このような機能の利点と欠点は議論の余地がありますが、他の静的型付け言語、例えばC++は型推論をサポートしています。
いずれにせよ、型推論はローカル変数、つまりメソッド内の変数にのみ適用されるため、データ型の使用を完全に置き換えることはできません。var
を使用した例を見てみましょう:
- var hello = "Hello";
- System.out.println(hello);
hello
という変数をvar
キーワードで宣言して、Javaにそのデータ型を検出するよう指示します。その後、通常通りにコンソールに出力して動作を確認します:
Ouputhello ==> "Hello"
Hello
この例は、Javaのインストール(具体的にはJDK)がバージョン10より上である限り動作します。var
キーワードは、古いバージョンではサポートされていません。
型推論はコンパイルプロセス中に行われます。つまり、コードをコンパイルする際に行われます。コンパイルプロセスは、プレーンテキストのソースコードをマシンコードに変換し、型推論を含むさまざまな最適化を適用します。これにより、型推論された変数に必要な正確なシステムメモリ量が利用可能になります。したがって、コンパイル後に実行するマシンコードは、すべてのデータ型を手動で指定したかのように完全に最適化されます。
この例では、変数がローカルであるため、var
キーワードが機能します。また、var
データ型はローカル変数のみで機能します。ローカル変数はメソッド内で定義され、メソッド内でのみアクセス可能です。そのため、「ローカル」と呼ばれています。
ローカル変数以外ではvar
を使用できないことを示すために、次のようにmainメソッドの外に配置してみてください:
- public class Hello {
- var hello = "Hello";
- public static void main(String[] args) {
- // example code
- }
- }
上記のコードをjshell
に貼り付けると、次のエラーが表示されます:
Output| Error:
| 'var' is not allowed here
| var hello = "Hello";
| ^-^
hello
がメソッドの外にあるため、var
はそこでは許可されません。したがって、非ローカル変数では型推論は機能せず、コンテキストを信頼してデータ型を検出することができません。
var
を使用することは難しい場合があり、必須ではありませんが、遭遇することがあるため、知っておくと役立ちます。
予約キーワード
変数を宣言する際、Javaには知っておくべきもう1つの重要なルールがあります。変数名には使用できない予約キーワードがあります。たとえば、int
型のプリミティブをnew
という名前で宣言することはできません:
- int new = 1;
この例を試すと、new
が予約キーワードであるため、コンパイルエラーが発生します。
Output| Error:
| '.class' expected
| int new = 1;
| ^
| Error:
| <identifier> expected
| int new = 1;
| ^
| Error:
| '(' or '[' expected
| int new = 1;
| ^
| Error:
| unexpected type
| required: value
| found: class
| int new = 1;
| ^--^
| Error:
| missing return statement
| int new = 1;
| ^----------^
エラーのリストで最初の部分が最も重要です:
Output| Error:
| '.class' expected
| int new = 1;
| ^
'.class' expected
というエラーは、new
キーワードを使用するときに、Javaがクラスが続くことを期待していることを意味します。この時点では、Javaは文を解釈できず、残りのエラーが続きます。
他の予約キーワード(abstract
、continue
、default
、for
、およびbreak
など)もJavaで特定の意味を持ち、変数名として使用できません。予約キーワードの完全なリストはJava言語のキーワードページで確認できます。予約キーワードを全て覚えていなくても、コンパイルエラーを使用して問題を特定できます。
結論
このチュートリアルでは、Javaのプリミティブおよび参照データ型について学びました。これは複雑ですが重要なトピックです。じっくり練習し、例を何度も確認してください。データ型や値を変更してみてください。エラーが発生するタイミングとしないタイミングに注意して、成功するコードの実行に対する感覚を開発してください。
Javaに関する詳細は、当社のHow To Code in Javaシリーズをチェックしてください。
Source:
https://www.digitalocean.com/community/tutorials/understanding-data-types-in-java