Java Language
プリミティブデータ型
サーチ…
前書き
byte
、 short
、 int
、 long
、 char
、 boolean
、 float
、 double
の8種類のプリミティブデータ型は、Javaプログラムで最も生の数値データを格納する型です。
構文
int aInt = 8; //このint宣言の定義(数値)部分はリテラルと呼ばれます。
int hexInt = 0x1a; // = 26;リテラルは、接頭辞が0xの 16進値で定義できます。
int binInt = 0b11010; // = 26;バイナリリテラルを定義することもできます。接頭辞は0bです。
長いgoodLong = 10000000000L; //デフォルトでは、整数リテラルはint型です。リテラルの最後にLを追加することによって、リテラルが長いことをコンパイラに伝えます。これがなければ、コンパイラは "Integer number too large"エラーをスローします。
double aDouble = 3.14; //浮動小数点リテラルはデフォルトでdouble型です。
float aFloat = 3.14F; float //デフォルトでは、このリテラルはdouble型( "互換性のない型"エラーが発生していました)ですが、Fを追加することによってコンパイラにfloat型を通知します。
備考
Javaには、 boolean
、 byte
、 short
、 char
、 int
、 long
、 float
、 double
8つのプリミティブデータ型があります。 (他のすべての型が参照型であるこれは、すべての配列型を含み、そしてビルトインJava言語で特別な意味を持っているオブジェクトタイプ/クラス;例えばString
、 Class
とThrowable
およびそのサブクラスを。)
プリミティブ型のすべての演算(加算、減算、乗算、等)の結果は、少なくともあるint
従って追加、 short
へのshort
生成int
追加する場合と同様、 byte
のbyte
、またはchar
するchar
。その結果を同じ型の値に代入したい場合は、それをキャストしなければなりません。例えば
byte a = 1;
byte b = 2;
byte c = (byte) (a + b);
操作をキャストしないと、コンパイルエラーが発生します。
これは、 Java言語仕様§2.11.1の次の部分に起因します。
コンパイラは、コンパイル時または実行時にこれらの値を
int
型の値に符号拡張するJava仮想マシン命令を使用して、byte
型およびshort
型のリテラル値のロードをエンコードします。boolean
とchar
型のリテラル値のロードは、コンパイル時または実行時にリテラルをint
型の値にゼロ拡張する命令を使用してエンコードされます。 [..]。したがって、実際の型boolean
、byte
、char
、short
値に対するほとんどの演算は、計算型int
値を操作する命令によって正しく実行されます。
この背後にある理由は、そのセクションでも指定されています。
Java Virtual Machineの1バイトのオペコードサイズが与えられているので、タイプをオペコードにエンコードすると、命令セットの設計に負担がかかります。各型付き命令がすべてのJava仮想マシンの実行時データ型をサポートしていれば、1
byte
で表現できる命令以上の命令が存在しbyte
。 [...]必要に応じて、サポートされていないデータ型とサポートされているデータ型を変換するために、別々の命令を使用できます。
intプリミティブ
int
ようなプリミティブデータ型は、それを使用している変数に値を直接保持しますが、 Integer
を使用して宣言された変数はその値への参照を保持します。
Java APIによると: "Integerクラスは、オブジェクトのプリミティブ型intの値をラップします。Integer型のオブジェクトには、型がint型の単一のフィールドが含まれています。
デフォルトでは、 int
は32ビット符号付き整数です。 -2 31の最小値と2 31 -1の最大値を格納できます。
int example = -42;
int myInt = 284;
int anotherInt = 73;
int addedInts = myInt + anotherInt; // 284 + 73 = 357
int subtractedInts = myInt - anotherInt; // 284 - 73 = 211
この範囲外の数値を格納する必要がある場合は、代わりにlong
を使用する必要があります。 int
の値の範囲を超えると、整数のオーバーフローが発生し、範囲を超える値が範囲の反対側のサイトに追加されます(正の値は負の値になります)。値は((value - MIN_VALUE) % RANGE) + MIN_VALUE
、 ((value + 2147483648) % 4294967296) - 2147483648
int demo = 2147483647; //maximum positive integer
System.out.println(demo); //prints 2147483647
demo = demo + 1; //leads to an integer overflow
System.out.println(demo); // prints -2147483648
int
の最大値と最小値は次の場所にあります。
int high = Integer.MAX_VALUE; // high == 2147483647
int low = Integer.MIN_VALUE; // low == -2147483648
int
のデフォルト値は0です。
int defaultInt; // defaultInt == 0
短いプリミティブ
short
は16ビットの符号付き整数です。 -2 15 (-32,768)の最小値と、2 15 -1(32,767)の最大値を持ち、
short example = -48;
short myShort = 987;
short anotherShort = 17;
short addedShorts = (short) (myShort + anotherShort); // 1,004
short subtractedShorts = (short) (myShort - anotherShort); // 970
short
の最大値と最小値は次の場所にあります。
short high = Short.MAX_VALUE; // high == 32767
short low = Short.MIN_VALUE; // low == -32768
short
のデフォルト値は0です。
short defaultShort; // defaultShort == 0
長いプリミティブ
デフォルトでは、 long
は64ビットの符号付き整数です(Java 8では、符号付きまたは符号なしのいずれでもかまいません)。符号付きでは、最小値-2 63および最大値2 63 -1を格納でき、符号なしでは最小値0および最大値2 64 -1を格納できます
long example = -42;
long myLong = 284;
long anotherLong = 73;
//an "L" must be appended to the end of the number, because by default,
//numbers are assumed to be the int type. Appending an "L" makes it a long
//as 549755813888 (2 ^ 39) is larger than the maximum value of an int (2^31 - 1),
//"L" must be appended
long bigNumber = 549755813888L;
long addedLongs = myLong + anotherLong; // 284 + 73 = 357
long subtractedLongs = myLong - anotherLong; // 284 - 73 = 211
long
の最大値と最小値は次の場所にあります。
long high = Long.MAX_VALUE; // high == 9223372036854775807L
long low = Long.MIN_VALUE; // low == -9223372036854775808L
デフォルト値のlong
0Lです
long defaultLong; // defaultLong == 0L
注: long
リテラルの末尾に付加された文字 "L"は大文字小文字を区別しませんが、数字と区別しやすいので、大文字を使用することをお勧めします。
2L == 2l; // true
警告:JavaではIntegerオブジェクトのインスタンスが-128〜127の範囲でキャッシュされます。ここでは推論について説明します: https : //blogs.oracle.com/darcy/entry/boxing_and_caches_integer_valueof
次の結果が見つかりました:
Long val1 = 127L;
Long val2 = 127L;
System.out.println(val1 == val2); // true
Long val3 = 128L;
Long val4 = 128L;
System.out.println(val3 == val4); // false
2つのObject Long値を適切に比較するには、次のコードを使用します(Java 1.7以降)。
Long val3 = 128L;
Long val4 = 128L;
System.out.println(Objects.equal(val3, val4)); // true
プリミティブlongをObject longと比較すると、2つのオブジェクトを==で比較するような偽のネガティブは発生しません。
booleanプリミティブ
boolean
値は、 true
またはfalse
2つの値のいずれかを格納できfalse
boolean foo = true;
System.out.println("foo = " + foo); // foo = true
boolean bar = false;
System.out.println("bar = " + bar); // bar = false
boolean notFoo = !foo;
System.out.println("notFoo = " + notFoo); // notFoo = false
boolean fooAndBar = foo && bar;
System.out.println("fooAndBar = " + fooAndBar); // fooAndBar = false
boolean fooOrBar = foo || bar;
System.out.println("fooOrBar = " + fooOrBar); // fooOrBar = true
boolean fooXorBar = foo ^ bar;
System.out.println("fooXorBar = " + fooXorBar); // fooXorBar = true
boolean
値のデフォルト値はfalseです。
boolean defaultBoolean; // defaultBoolean == false
バイトプリミティブ
1 byte
は8ビットの符号付き整数です。 1(127) -これは-2 7(-128)最小値、及び2~7の最大値を記憶することができます
byte example = -36;
byte myByte = 96;
byte anotherByte = 7;
byte addedBytes = (byte) (myByte + anotherByte); // 103
byte subtractedBytes = (byte) (myBytes - anotherByte); // 89
byte
の最大値と最小値は次の場所にありbyte
。
byte high = Byte.MAX_VALUE; // high == 127
byte low = Byte.MIN_VALUE; // low == -128
byte
のデフォルト値は0です。
byte defaultByte; // defaultByte == 0
floatプリミティブ
float
単精度32ビットIEEE 754浮動小数点数です。デフォルトでは、小数は2倍として解釈されます。 float
を作成するfloat
、単に10進リテラルにf
を追加します。
double doubleExample = 0.5; // without 'f' after digits = double
float floatExample = 0.5f; // with 'f' after digits = float
float myFloat = 92.7f; // this is a float...
float positiveFloat = 89.3f; // it can be positive,
float negativeFloat = -89.3f; // or negative
float integerFloat = 43.0f; // it can be a whole number (not an int)
float underZeroFloat = 0.0549f; // it can be a fractional value less than 0
浮動小数点演算は、5つの一般的な算術演算(加算、減算、乗算、除算、モジュラス)を処理します。
注:以下は、浮動小数点エラーの結果として多少異なる場合があります。一部の結果は、わかりやすく読みやすいように丸められています(つまり、追加例の印刷結果は実際には34.600002でした)。
// addition
float result = 37.2f + -2.6f; // result: 34.6
// subtraction
float result = 45.1f - 10.3f; // result: 34.8
// multiplication
float result = 26.3f * 1.7f; // result: 44.71
// division
float result = 37.1f / 4.8f; // result: 7.729166
// modulus
float result = 37.1f % 4.8f; // result: 3.4999971
浮動小数点数が(バイナリ形式で)格納される方法のため、多くの数値は正確な表現を持っていません。
float notExact = 3.1415926f;
System.out.println(notExact); // 3.1415925
ほとんどのアプリケーションでfloat
を使用float
は問題ありませんが、10進数の正確な表現(金額など)、またはより高い精度が要求される数値を格納するには、 float
もdouble
も使用しないでください。代わりに、 BigDecimal
クラスを使用する必要があります。
float
のデフォルト値は0.0fです。
float defaultFloat; // defaultFloat == 0.0f
float
は、正確には1000万分の1の誤差です。
注: Float.POSITIVE_INFINITY
、 Float.NEGATIVE_INFINITY
、 Float.NaN
はfloat
数値です。 NaN
は、2つの無限値の除算など、決定できない操作の結果を表します。さらに、 0f
と-0f
は異なるが、 ==
が成立する。
float f1 = 0f;
float f2 = -0f;
System.out.println(f1 == f2); // true
System.out.println(1f / f1); // Infinity
System.out.println(1f / f2); // -Infinity
System.out.println(Float.POSITIVE_INFINITY / Float.POSITIVE_INFINITY); // NaN
ダブルプリミティブ
double
は、倍精度の64ビットIEEE 754浮動小数点数です。
double example = -7162.37;
double myDouble = 974.21;
double anotherDouble = 658.7;
double addedDoubles = myDouble + anotherDouble; // 315.51
double subtractedDoubles = myDouble - anotherDouble; // 1632.91
double scientificNotationDouble = 1.2e-3; // 0.0012
浮動小数点数が格納される方法のため、多くの数値は正確な表現を持っていません。
double notExact = 1.32 - 0.42; // result should be 0.9
System.out.println(notExact); // 0.9000000000000001
使用している間double
ほとんどのアプリケーションで結構です、どちらもfloat
もdouble
通貨など、正確な数値を格納するために使用する必要があります。代わりに、 BigDecimal
クラスを使用する必要があります
double
のデフォルト値は0.0dです。
public double defaultDouble; // defaultDouble == 0.0
注: Double.POSITIVE_INFINITY
、 Double.NEGATIVE_INFINITY
、 Double.NaN
はdouble
値です。 NaN
は、2つの無限値の除算など、決定できない操作の結果を表します。さらに、 0d
と-0d
は異なりますが、 ==
が-0d
ます。
double d1 = 0d;
double d2 = -0d;
System.out.println(d1 == d2); // true
System.out.println(1d / d1); // Infinity
System.out.println(1d / d2); // -Infinity
System.out.println(Double.POSITIVE_INFINITY / Double.POSITIVE_INFINITY); // NaN
charプリミティブ
char
は単一の16ビットUnicode文字を格納できます。文字リテラルは一重引用符で囲まれています
char myChar = 'u';
char myChar2 = '5';
char myChar3 = 65; // myChar3 == 'A'
\u0000
最小値(10進表記では0、 ヌル文字とも呼ばれます )と\uffff
(65,535)の最大値を\uffff
ます。
char
のデフォルト値は\u0000
です。
char defaultChar; // defaultChar == \u0000
'
value '
文字を定義するためには、エスケープシーケンス(バックスラッシュで始まる文字)を使用する必要があります:
char singleQuote = '\'';
その他のエスケープシーケンスもあります:
char tab = '\t';
char backspace = '\b';
char newline = '\n';
char carriageReturn = '\r';
char formfeed = '\f';
char singleQuote = '\'';
char doubleQuote = '\"'; // escaping redundant here; '"' would be the same; however still allowed
char backslash = '\\';
char unicodeChar = '\uXXXX' // XXXX represents the Unicode-value of the character you want to display
任意のUnicode文字のchar
を宣言できます。
char heart = '\u2764';
System.out.println(Character.toString(heart)); // Prints a line containing "❤".
char
に追加することもできます。たとえば、すべての小文字を繰り返し処理するには、次のようにします。
for (int i = 0; i <= 26; i++) {
char letter = (char) ('a' + i);
System.out.println(letter);
}
負の値表現
Javaおよび他のほとんどの言語は、 2の補数表記と呼ばれる表現に負の整数を格納します。
n
ビットを使用するデータ型の一意のバイナリ表現では、値は次のようにエンコードされます。
最下位のn-1
ビットは、積分表現で正の整数x
格納する。最も重要な値は、値s
ビットを格納します。これらのビットが返す値は
x-s * 2 n-1
すなわち、最上位ビットが1であれば、他のビット( 2 n-2 + 2 n-3 + ... + 2 1 + 2 0 = 2 n-1 - 1
表すことができる数よりも1だけ大きい値2 n-2 + 2 n-3 + ... + 2 1 + 2 0 = 2 n-1 - 1
)からの各値の一意のバイナリ表現可能減算される- 2 n-1個 (S = 1、X = 0) のn-1 2 - 1(S = 0、X = 2 N-1 - 1)。
これには良い副作用があり、バイナリ表現を正の2進数のように追加することができます:
v1 = x1 - s1 * 2n-1 v2 = x2 - s2 * 2n-1
s1 | s2 | x1 + x2オーバーフロー | 加算結果 |
---|---|---|---|
0 | 0 | いいえ | x1 + x2 = v1 + v2 |
0 | 0 | はい | データ型で表現するには大きすぎます(オーバーフロー) |
0 | 1 | いいえ | x1 + x2 - 2n-1 = x1 + x2 - s2 * 2n-1 |
0 | 1 | はい | (x1 + x2) mod 2n-1 = x1 + x2 - 2n-1 |
1 | 0 | * | 上記を参照(サマリを交換) |
1 | 1 | いいえ | データ型(x1 + x2 - 2 n -2 n-1 ;アンダーフロー)で表現するには小さすぎます。 |
1 | 1 | はい | (x1 + x2) mod 2n-1 - 2n-1 = (x1 + x2 - 2n-1) - 2n-1 |
この事実は、加法的逆(すなわち、負の値)の2進表現を容易に見つけることを可能にすることに留意されたい:
数値にビット補数を加えるとすべてのビットが1になることに注意してください。次に、1を加算して値のオーバフローを行い、ニュートラル要素0(すべてのビット0)を取得します。
したがって、数値i
の負の値は、( int
への可能な昇格を無視して)
(~i) + 1
例:負の値0( byte
)を取る:
0
を否定した結果は11111111
です。 1を加えると100000000
(9ビット)の値が得られます。 byte
は8ビットしか格納できないため、一番左の値は切り捨てられ、結果は00000000
元の | プロセス | 結果 |
---|---|---|
0(00000000) | 否定 | -0(11111111) |
11111111 | バイナリに1を加える | 100000000 |
100000000 | 8ビットに切り捨てる | 00000000(-0は0に等しい) |
プリミティブとボックスプリミティブのメモリ消費
プリミティブ | ボックスタイプ | プリミティブ/ボックスのメモリサイズ |
---|---|---|
ブール値 | ブール | 1バイト/ 16バイト |
バイト | バイト | 1バイト/ 16バイト |
ショート | ショート | 2バイト/ 16バイト |
チャー | チャー | 2バイト/ 16バイト |
int | 整数 | 4バイト/ 16バイト |
長いです | 長いです | 8バイト/ 16バイト |
浮く | 浮く | 4バイト/ 16バイト |
ダブル | ダブル | 8バイト/ 16バイト |
ボックス化されたオブジェクトは常に型とメモリの管理に8バイトを必要とし、オブジェクトのサイズは常に8の倍数であるため、ボックス化された型はすべて合計16バイトを必要とします 。 また 、ボックス化オブジェクトの各使用量はJVMとJVMオプションに応じて、別の4つのまたは8バイトを占める参照を格納することを伴います。
データ集約型操作では、メモリ消費量がパフォーマンスに大きな影響を与える可能性があります。配列を使用すると、メモリ消費量はさらに増えますfloat[5]
配列には32バイトしか必要ありません。 5つの別個の非ヌル値を格納するFloat[5]
合計112バイトを必要とします(圧縮ポインタなしの64ビットでは、これは152バイトに増加します)。
ボックス化された値のキャッシュ
ボックス化された型のスペースオーバーヘッドは、ボックス化された値のキャッシュによってある程度軽減できます。ボックス化された型の中には、インスタンスのキャッシュを実装するものがあります。たとえば、デフォルトでは、 Integer
クラスはインスタンスをキャッシュして、 -128
+127
範囲の数値を表します。ただし、メモリの間接的な追加によって発生する追加コストは削減されません。
autoboxingまたは静的なvalueOf(primitive)
メソッドを呼び出すことによってboxed型のインスタンスを作成すると、ランタイムシステムはキャッシュされた値の使用を試みます。アプリケーションがキャッシュされた範囲内の多くの値を使用する場合、ボックス化された型を使用することによるメモリのペナルティが大幅に軽減されます。確かに、 "手作業で"ボックス化されたバリュー・インスタンスを作成する場合は、 new
ではなくvalueOf
を使用する方がよいでしょう。ただし、大部分の値がキャッシュされた範囲にない場合は、 new
を呼び出してキャッシュルックアップを保存する方が速くなる可能性があります( new
操作では常に新しいインスタンスが作成されます)。
プリミティブの変換
Javaでは、整数値と浮動小数点値の間の変換が可能です。また、すべての文字がUnicodeエンコーディングの数値に対応するため、 char
型は整数型と浮動小数点型に変換できます。 boolean
は、他のプリミティブデータ型との間で変換できない唯一のプリミティブデータ型です。
コンバージョンには、コンバージョンの拡大とコンバージョンの 縮小の 2種類があります。
拡大変換は、1つのデータ型の値が、以前のデータ型よりも多くのビットを占める別のデータ型の値に変換される場合です。この場合、データ損失の問題はありません。
これに対応して、1つのデータ型の値が、以前のデータ型よりも少ないビットを占める別のデータ型の値に変換されるとき、 変換が狭くなります。この場合、データの損失が発生する可能性があります。
Javaは自動的に拡大変換を実行します。しかし、 変換を狭くしたい場合は(データが失われないことが確かな場合)、 cast
呼ばれる言語構造を使用してJavaに変換を実行させることができます。
拡大変換:
int a = 1;
double d = a; // valid conversion to double, no cast needed (widening)
ナロー変換:
double d = 18.96
int b = d; // invalid conversion to int, will throw a compile-time error
int b = (int) d; // valid conversion to int, but result is truncated (gets rounded down)
// This is type-casting
// Now, b = 18
プリミティブ型チートシート
すべてのプリミティブ型のサイズと値の範囲を示す表。
データ・タイプ | 数値表現 | 値の範囲 | デフォルト値 |
---|---|---|---|
ブール値 | 該当なし | 偽と真 | 偽 |
バイト | 8ビット符号付き | 1 - -2 7 2〜7 | 0 |
-128〜+127 | |||
ショート | 16ビット符号付き | 1 - 15 -2 15〜2 | 0 |
-32,768〜+ 32,767 | |||
int | 32ビット符号付き | 1 - 31 -2 31〜2 | 0 |
-2,147,483,648〜+ 2,147,483,647 | |||
長いです | 64ビット署名 | 1 - 63 -2 63〜2 | 0L |
-9,223,372,036,854,775,808~9,223,372,036,854,775,807 | |||
浮く | 32ビット浮動小数点 | 1.401298464e-45〜3.402823466e + 38(正または負) | 0.0F |
ダブル | 64ビット浮動小数点 | 4.94065645841246544e-324dから1.79769313486231570e + 308d(正または負) | 0.0D |
チャー | 16ビット符号なし | 0から2 16 - 1 | 0 |
0〜65535 |
ノート:
- Java言語仕様では、符号付き整数型(
byte
からlong
)は2進2進表現を使用し、浮動小数点型は標準IEE 754 2進浮動小数点表現を使用することが義務づけられています。 - Java 8以降では、
int
およびlong
符号なし算術演算を実行するメソッドを提供しています。これらのメソッドでは、プログラムは各タイプの値を符号なしとして扱うことができますが、タイプは符号付きタイプのままです。 - 上に示した最小の浮動小数点は非正規です。つまり、 通常の値よりも精度が劣ります。最小の正規数は1.175494351e-38と2.2250738585072014e-308です
- 通常、
char
はUnicode / UTF-16 コード単位を表します 。 -
boolean
は1ビットの情報しか含まれていませんが、メモリ内のサイズはJava仮想マシンの実装によって異なります( ブール型を参照)。