リテラル
リテラル:コード中に直接書き込む値
javaには4つのリテラルがある
・整数(int型が整数のデフォルト)
・浮動小数点数(double型が小数のデフォルト)
・真偽(boolean)
・文字(char)
これ以外のリテラルを明示する場合は下記のルールに従い接頭辞、接尾辞を付ける
public class Main {
public static void main(String[] args) {
//整数リテラルの表現方法:10進数以外の表現は下記のルールに従う
System.out.println(255); // 10進数(整数値):普通に表記
System.out.println(0b11111111); // 2進数:先頭0b
System.out.println(0377); // 8進数 :先頭0
System.out.println(0xff); // 16進数:先頭0x
//浮動小数点数リテラルの表現方法
System.out.println(12.33); // 10進数(小数):普通に表記
System.out.println(3e4); // 指数:3.0 × 10の4乗
//文字型リテラルの表現方法
System.out.println('A'); // 1文字:1文字だと''
System.out.println("Hello"); // 複数文字は""で囲う
//Unicodeによる文字表現:世界中の言語に数値が割り振ってある
System.out.println('\u3012'); // u+ 16進数4桁の整数で1文字(0~65535:16bit)
System.out.println('45662'); // 10進数0~65535までの整数でも可能
System.out.println(true); // 論理値:そのまま
}
}
リテラルはデータ型の宣言、代入なしでコード上で使用できる
変数のように値や状態を保持することができない
変数
変数はリテラルと違い代入により処理結果や値を保持できる
保持するデータ型を明示する必要がある
識別子:変数やメソッドの名前
・予約語(Javaの中で既に定められた特別な名前)は識別子として使用不可
・"_"と"$"以外は使用できない
・数字から始めてはいけない
public class Type {
public static void main(String[] args){
byte b = 10; //8bit整数
short s = 20; //16bit整数
int i = 30; //32bit整数(整数値のデフォルト)
long l = 40L; //64bit整数
float f = 1.15F; //32bit単精度浮動小数点数(小数値のデフォルト)
double d = 5.78; //64bit倍精度浮動小数点数
char c = 'A'; //単数文字''で囲う
string s = "string"//複数文字""で囲う
boolean o = true;
// final + 定数名 = 初期値
}
}
変数はデータ型の違いによって2つに大別される
・基本データ型(プリミティブ型):値そのものを扱う
・参照型:値、インスタンスのある場所(データ領域)への参照を扱う
データ型を明示しない場合、整数値、小数値の代入先の変数はそれぞれデフォルトとなる
その際、データ型の容量を超える数値の場合はエラーとなる
桁あふれの検証
public class Ling {
public static void main(String [] args) {
int m = 2147483647;
System.out.println(m + ":int型最大値(32bit)");
m += 1;
System.out.println(m + ":+1して桁あふれ");
long n = 2147483647;
System.out.println(n + ":lomg型最大値(64bit)");
n += 1;
System.out.println(n + ":+1して桁あふれ");
}
}
実行結果
PS C:\Users\Github\Java\05> java Ling
2147483647:int型最大値(32bit)
-2147483648:+1して桁あふれ
2147483647:lomg型最大値(64bit)
2147483648:+1して桁あふれ
Int型(最大32bit)Long型(最大64bit)これを超えるとオーバーフローする。
基本情報技術者の時に仕組みだけ知ったが実践してみると面白い
-に転じるのは負の数を補数表現しているからだと思われる
アンダースコア( _ )
桁数の多いリテラルを見やすくする
・リテラルの先頭、末尾は不可
・記号の前後は不可
null
参照先がない状態を表すリテラルの一種であるため、参照型データにしか代入できない
基本データ型に代入するとエラーとなる
変数のスコープ
変数のスオープ(有効範囲)
・ローカル変数:メソッド内で定義した変数(変数のスコープはメソッド内のみ)
・メンバ変数:クラス定義の直下で宣言した変数(基本的にプログラムのどこでも有効)
修飾子により色々な属性を付加する
ローカル変数の型推論(var)
変数宣言時にデータ型の代わりに"var"を使用すると、右辺の値からデータ型を推論する
変数が初期化されていない状態(空)であったり、nullだとデータ型を特定できない
ローカル変数の宣言でしか使えない(メソッドで宣言する変数)
public class Main {
//var a = 100; // コンパイルエラー
//static var b = 100; // コンパイルエラー
public static void main(String[] args) {
var c = "hello"; // OK
var d = 100; // OK
//var e; // コンパイルエラー
//var f = null; // コンパイルエラー
final var g = 100; // OK
//var final h = 100; // コンパイルエラー
}
}
配列の作り方
public class Array {
public static void main(String[] args) {
// データ型[] 配列名; 配列宣言
// 配列の宣言:設計図の段階(何を入れる、何ていう名前の箱?)
char[] c; //文字データを入れるCという名前の配列の設計図を作製
// 配列の作成:実際に箱を作る段階(その箱の容量はどのくらい?)
c = new char[3]; //cという名前の配列設計図(データ型)から実際に文字が3つ入るcという箱を作製 (領域確保)
// 設計図の名前Cと実際の箱の名前cは必ず一緒になる?
// 配列の宣言と作成を同時に行う
int[] i = new int[3];
//数値を入れるiという名前の箱の設計図に、数字が3つ入る容量を確保した箱を作製
// やはり設計図の名前iと実際の箱の名前iは必ず一緒になるか…
// 各要素へ値の代入
c[0] = 'A'; c[1] = 'B'; c[2] = 'C'; // 各要素へ値の代入
i[0] = 100; i[1] = 200; i[2] = 300;
// iという箱にある3つの区画を指定(配列名[インデックス])して代入
// 宣言と作成と初期化を同時に行う
String str[] = {"Welcome ","to ","Java."};
// strという文字列の入る箱の設計図から3つの区画がある箱を作って、それぞれに初期文字列を設定
System.out.println("strのサイズ: " + str.length);// 配列の要素数
System.out.println("c[0] : " + c[0]);
System.out.println("i[1] : " + i[1]);
}
}
ここはかなり時間をかけました。
jsやphpでは変数の宣言はクラス外でも可能で
変数の宣言とインスタンスの作成は特に意識しなかったです。
Javaではクラスとオブジェクトを明確に分けるために
new を使い、インスタンス化を明示している印象です。
ただし、変数宣言、作成、初期化を一度に実行する最後の公文では newを使わずにインスタンス化している
設計図:クラス(メソッド・プロパティ)
↓
インスタンス:オブジェクト(メソッド・プロパティ)
配列の生成と初期値
public class Main {
public static void main(String[] args) {
int i;
//System.out.println("iの値: " + i); 宣言した時点(設計図段階)ではnullなのでエラー
int[] array = new int[1];
System.out.println("array[0]の値 : " + array[0]);
//インスタンス化した時点で初期値が割り振られるのでエラーにならない
//System.out.println("array[0]の値 : " + array[1]);
//配列のインデックス[1]は存在しないからエラー
}
}
Stringオブジェクト
文字列のデータは文字の抜き出しや連結、検索など他のデータ型と比べ多くの機能が必要
他データ型と異なり、変数の宣言では特別なstringクラスをインスタンス化する
→java.lang.string クラス
string str = "abcde"; //クラスのインスタンス化を明示しない方法
string str = new string("abcd"); //クラスのインスタンス化を明示する方法
クラスのコンストラクタを使用する時以外は、new キーワードを使わない方がメモリ効率が良い
多次元配列
public class Multi {
public static void main(String[] args) {
//基本的には普通の配列と一緒
int[][] array; //設計図の作成
array = new int[3][4]; //設計図から容量3×4の箱を作成(jacaではint型初期値は0)
//int[][] array = new int[3][4]; ←二つを省略してこのようにも書ける
array[0][0] = 100; //インデックスを指定して代入
array[0][3] = 200; //インデックスを指定して代入
System.out.println("array[0][0]の値 : " + array[0][0]);
System.out.println("array[0][3]の値 : " + array[0][3]);
//設計図の作成、配列の作成、値の代入を同時に実行
int[][] array2 = {
{10, 20, 30, 40},
{50, 60, 70, 80},
{100, 200, 300, 400}
};
System.out.println("array2[0][0]の値 : " + array[0][0]);
System.out.println("array2[0][3]の値 : " + array[0][3]);
}
}
多次元配列のイメージはX,Y,Zのグラフをイメージすると分かりやすい。
要素数が不揃いな多次元配列
public class Multi2 {
public static void main(String[] args) {
//array配列のインスタンス作成
//数値の入る箱のx軸を3つに設定、Y軸は未設定
int[][] array = new int[3][];
//array配列のインデックス[0]に対し
array[0] = new int[3]; //X軸[0]にY軸3つの区画を割り当てる
array[1] = new int[5]; //...5つ
array[2] = new int[2]; //...2つ
//この時点で配列arrayのX,Y区画数が決定 → インスタンスとして機能する
// 上記を一括で実行
int[][] array2 = {
{10, 20, 30},
{50, 60, 70, 80, 90},
{100, 200}
};
System.out.println("array2[0][0]の値 : " + array[0][0]);
System.out.println("array2[1][4]の値 : " + array[1][4]);
}
}
要素数のふぞろいな多次元配列のインスタンス化はややこしい。
便宜的にX,Yと表現していますが僕の中のイメージです。
1:配列X軸に対して new を明示し要素数を指定してインスタンス化する
2:要素数を指定した配列のx軸に対して、それぞれ new を明示し要素数を指定する(Y軸)
ややこしいのは 1でインスタンス化(領域確保)した要素はX軸のみで
2でインスタンスしたX軸要素に対して、1次元配列と同じようにY軸のインスタンス化を行う事
完全に僕のイメージです
多次元配列の作成 エラーパターン
public class Multi3 {
public static void main(String[] args) {
int[][] a1 = new int[2][]; // OK
//int[][] a2 = new int[][2]; // コンパイルエラー
//int[] a3 = new int[2]{ }; // コンパイルエラー
//int[] a4 = new int[2]{10, 20}; // コンパイルエラー
int[] a5 = new int[]{10, 20}; // OK
int[] a6 = { }; // OK
int[][] a7 = { }; // OK
int[][] a8 = new int[][]{ }; // OK
//var a9 = {10, 20}; // コンパイルエラー
var a10 = new int[]{10, 20}; // OK
}
}
行数と理由
1.X軸の配列要素のみインスタンス化は可能
2.Y軸の配列要素のみのインスタンス化はできない
3.4:要素数指定と初期化を同時に行えない。
3.一次元配列の要素数を[2]で指定。{}で初期化を同時に行っている。
4.一次元配列の要素数を[2]で指定。{10,20}で初期化を同時に行っている。
5.一次元配列の要素数は指定せず{10,20}で初期は可能。
int[] a5 = {10,20} と同義
6.同じく要素数を指定せず{}(null)で初期化は可能
7.同じく二次元配列の要素は指定せず{}(null)で初期化は可能(初期化しているのはX軸のみ)
8. 7と同義
9.配列の初期化ではデータ型を明示しないと予測する事ができないため
10.データ型が明示されているためOK
コマンドライン引数
public class Comand {
//引数はString[]配列に格納されargsに引き渡される
public static void main(String[] args) {
System.out.println(args[0]);
System.out.println(args[1]);
System.out.println(args[2]);
System.out.println(args[1] + args[2]);
}
}
上記のComandクラスをターミナルで実行する際、一緒に引数を指定する
naito
20
50
2050 ←String型なので足し算されない
main()メソッドの引数String[] argsの使い方がわかった
第2章感想
配列の宣言、作成、初期化の書き方ルールが複雑なので問題を解いて慣れる必要がある
JavascriptやPHPでは何となくでできていた事もJavaでは厳密にルールに沿って記載しなければいけない。