Movatterモバイル変換


[0]ホーム

URL:


S-JIS[2008-06-22/2019-12-08]変更履歴

Javaの定数(リテラル)

固定(不変)の値を表すのが定数


定数値(リテラル)の表現

Javaで定数値(固定の値、即値)を表現するには、以下のようにする。[2003-07-06]

リテラルのデフォルト型
リテラル名形式
整数リテラル
・「0」で始めると八進数
・「0x」で始めると十六進数
・「0b」で始めると二進数(JDK1.7以降)[2012-01-14]
int123
0173
0x7b
0b1111011
・末尾にLを付けるとlong型long123L
浮動小数リテラル小数点付きの数double123.0
eを使う書き方。mEnはm×10n[2019-12-08]1.23e10
十六進浮動小数点リテラル。hPnはh×2n(JDK1.5以降)[2019-12-08]0x1.23p2
・末尾にFを付けるとfloat型
・末尾にDを付けるとdouble型
float
double
123f
123d
文字リテラルシングルクォーテーションで囲む。char'A'
文字列リテラルダブルクォーテーションで囲む。String"abc"
論理値リテラルtrue又はfalsebooleantrue
false
空リテラルnull空型null

JDK1.7では、数値リテラルの途中でアンダーバーを入れられるようになった。[2012-01-14]

int n = 123_456;int n = 0b111_10111;×int n = _123;//先頭に付けると変数扱いになるのは今まで通り×int n = 123_;//末尾に付けるのも駄目

エスケープ文字(エスケープシーケンス)
文字コード機能備考関連
\b08バックスペースback space 
\f0C改ページform feed 
\n0A改行new line/line feedマシン非依存の改行コードの取得方法
\r0D復帰(行頭にカーソルを戻す)carriage return
\t09水平タブhorizontal tab 
\\5C「\」  
\'2C「'」  
\"22「"」  
\ooo 3桁の八進数(000〜377)octal 

Unicodeエスケープ
文字コード機能備考関連
\uhhhh 4桁の十六進数(0000〜FFFF)hexadecimal\uはコンパイルの第一段階(字句解析)で解釈されるので、
エスケープシーケンスとは動作が異なる

エスケープシーケンスUnicodeエスケープは似て非なるもの。[2008-08-30]
処理の差異


 


不変の変数

finalで宣言して初期値を与えた変数は、定数として扱える。[2008-06-22]
なお、定数として扱う場合は、変数名は全て大文字にするのが慣例。

public staticfinal intBASE_YEAR = 1970;

この変数には後から値を代入することが出来ない。(finalが付いていると、代入できなくなる)
代入できない→値が不変(固定)→定数

switch文で使う場合の注意
他言語の定数の定義方法


ただし、オブジェクト(参照型)の場合は、必ずしも固定(不変)というわけではない。

final Map SAMPLE_MAP = new HashMap();

変数SAMPLE_MAPには新しいMapを代入することは出来ない。しかしSAMPLE_MAP内に値をセットするのは自由。

SAMPLE_MAP.put("key", "value");//←問題なしSAMPLE_MAP = new HashMap(); //←これはコンパイルエラーになる

つまり、変数にfinalを付けた場合、あくまでその変数への代入が出来なくなるだけ。
その変数(のクラス)のメソッドやフィールドには普通にアクセスできる。

(すなわち、「finalが付いている」からと言って「不変」というわけではない。この場合は「定数」とは呼び難いので、大文字の変数名にはしない方がいいかも)

StringやInteger等の変更不可能なオブジェクトの場合は、間違いなく定数となる。

final String STR = "abc";final Integer NUMBER = new Integer(1234);

オブジェクトの定数を返すメソッドを作りたい場合は注意が必要。
定数(固定)のつもりで不変でないクラスのオブジェクトを返すと、それが変更されない保証は無い。

class Empty {private static final ListEMPTY_LIST = new ArrayList(0);public ListgetList() {returnEMPTY_LIST;}}
Empty empty = new Empty();List list1 = empty.getList();list1.add("abc");List list2 = empty.getList();System.out.println(list2.size());

このgetList()は、用意しておいた空のリストを返している。
しかしその内容は、呼んだ元が書き換えることが出来る。(書き換えることを阻止できない)
したがって、書き換えられてしまった場合、二度目以降の呼び出しでは、空のリストという役を果たしていない…。

C++では(finalに相当する)constキーワードを使って、呼び出した側で値を変更できないように関数(メソッド)定義側で指定できた。

public:const List* getList() {return EMPTY_LIST;}
const List* list1 = s.getList();list1->add("abc");←「constオブジェクトは変更できない」というコンパイルエラー

Javaで同じように(constに相当する)finalを付けてみると…

publicfinal List getList() {〜}

そのメソッドはオーバーライドできないという意味になってしまう(苦笑)

空のコレクション(EMPTY_LISTやEMPTY_MAP)[2008-07-09]
内容も変更できないコレクション(ListやMap)の作り方[2008-07-09]


switchで使える定数

static finalで定義した変数は定数として使えるので、switch文でも使用できる。[2010-03-06]
のではあるが、値の初期化の仕方によっては使うことが出来ない。

static final int S1 = 1;static final int S2;static final int S3 = func();//メソッド呼び出しによる初期化static {//静的初期化子による初期化S2 = 2;}static int func() {return 3;}
int n = 〜;switch (n) {case S1:System.out.println("S1");break;case S2:System.out.println("S2");break;case S3:System.out.println("S3");break;default:System.out.println("def");break;}

case S1は問題ないが、case S2とS3はコンパイルエラーとなる。

S1は変数宣言と同時に初期値を指定しているので、定数として使用できる。
S2,S3は変数宣言時には初期値が無いので、実行時にクラスがロードされて初期化処理が実行されるまで値が定まらない。
switch文の定数はコンパイル時には定まっていないといけない(と思われる)ので、初期値指定の無いstatic final変数はcaseに指定できない。


S2の初期化方法(final宣言をしているが初期値は与えず、静的初期化子によって初期化する)は、finalの特徴を示している。

C言語/C++におけるconstはまさに「定数」を示すものだが、Javaのfinalは「変更できない」ことを意味する。
つまり、どこかで一度だけ初期化できるが、後からその値を変更することが出来ない。
初期化している箇所がどこにも無いとコンパイルエラーになる。
(staticフィールドの場合は静的初期化子、staticでないフィールドの場合はインスタンス初期化子コンストラクター、ローカル変数の場合は使用するまでに初期化する必要がある)
(実行時は、初期化されるまでの間は便宜的にその型のデフォルト値(プリミティブ型の場合は0、参照型の場合はnull)が入っている)


暗黙に定義されている定数

Javaでは以下のような定数が定義されており、使用することが出来る。[2003-07-06]

Javaの定数
リテラル名定数名説明
論理値リテラルtruebooleanの値。「真」を表す。
falsebooleanの値。「偽」を表す。
空リテラルnullオブジェクトのインスタンスが無い状態を表す。

true, false, nullはリテラル(定数)であって、キーワード(予約語)ではないのだそうだ。[/2007-11-13]
すなわち、true,false,nullはコンパイラーが特殊扱いしているのではなく、暗黙にライブラリーによって(?)final変数(定数)として定義されている、ということ。
その証拠に「null = 0;」や「true = false;」といった代入文をJDK1.4やJDK1.5のjavacでコンパイルしてみると、「final 変数 true に値を代入することはできません。」というコンパイルエラーになる。
int if;」といった予約語を使ったコーディングは別のコンパイルエラーになる)

ちなみにtrue, falseの型は言わずと知れたbooleanだが、nullは空型(null型)と言うんだそうだ。[2008-04-08]


環境依存の値

Javaはマルチプラットフォーム対応を標榜している。[2007-02-08]
そこで、プログラムを実行する/稼動させるマシン(環境)によって変わる値を取得する方法が用意されている(ものもある)。

機種依存の定数
概要取得方法Windowsの値UNIXの値
改行コード[/2012-04-12]System.getProperty("line.separator")
System.lineSeparator() //JDK1.7
"\r\n""\n"
ディレクトリ・ファイル名のパス区切りFile.separator
System.getProperty("file.separator")
"\\""/"
パスの区切り(PATHやCLASSPATH等)File.pathSeparator
System.getProperty("path.separator")
";"":"

システムプロパティー(System#getProperty())でしか取得できない値は、定数として宣言しておくと便利かも。

/** * 改行コード */public staticfinal String LINE_SEPARATOR = System.getProperty("line.separator");
public staticfinal String LINE_SEPARATOR = System.lineSeparator(); //JDK1.7以降

Java目次へ戻る /新機能へ戻る /技術メモへ戻る
メールの送信先:ひしだま

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 


[8]ページ先頭

©2009-2025 Movatter.jp