수색…


소개

byte , short , int , long , char , boolean , floatdouble 과 같은 8 개의 기본 데이터 유형은 Java 프로그램에서 가장 기본적인 원시 데이터를 저장하는 유형입니다.

통사론

  • int aInt = 8; //이 int 선언의 정의 (숫자) 부분을 리터럴이라고합니다.

  • int hexInt = 0x1a; // = 26; 16 진수 값 앞에 접두사가 0x 인 리터럴을 정의 할 수 있습니다.

  • int binInt = 0b11010; // = 26; 바이너리 리터럴을 정의 할 수도 있습니다. 접두사는 0b 입니다.

  • long goodLong = 10000000000L; // 기본적으로 정수 리터럴은 int 유형입니다. 리터럴의 끝에 L을 추가하면 리터럴이 길다는 것을 컴파일러에 알리는 것입니다. 이 옵션이 없으면 컴파일러는 "정수 값이 너무 큼"오류를 발생시킵니다.

  • double aDouble = 3.14; // 부동 소수점 리터럴은 기본적으로 double 유형입니다.

  • float aFloat = 3.14F; // 기본적으로이 리터럴은 double이었고 "호환되지 않는 유형"오류가 발생했습니다. 그러나 F를 추가하여 컴파일러에게 float임을 알려줍니다.

비고

Java에는 boolean , byte , short , char , int , long , floatdouble 등 8 개의 기본 데이터 유형이 있습니다 . (다른 모든 타입은 참조 타입이다. 이것은 모든 배열 타입과 String , Class , Throwable 및 그 서브 Class 와 같이 자바 언어에서 특별한 의미를 갖는 내장 객체 타입 / 클래스를 포함한다.)

기본 유형의 모든 조작 (더하기, 빼기, 곱하기 등)의 결과는 적어도 인 int 따라서 추가 short (A)에 short 생성 int 추가 마찬가지로, byte A와 byte 또는 char A와 char . 그 결과를 동일한 유형의 값에 지정하려면,이를 유형 변환해야합니다. 예

byte a = 1;
byte b = 2;
byte c = (byte) (a + b);

조작을 캐스팅하지 않으면 컴파일 오류가 발생합니다.

이는 Java 언어 스펙 §2.11.1 의 다음 부분에 기인합니다.

컴파일러는 컴파일 타임 또는 런타임에 이러한 값을 유형 int 의 값으로 부호 확장하는 Java Virtual Machine 명령어를 사용하여 byteshort 유형의 리터럴 값로드를 인코딩합니다. booleanchar 유형의 리터럴 값로드는 컴파일 타임 또는 런타임에 리터럴을 int 유형의 값으로 제로 확장하는 명령어를 사용하여 인코딩됩니다. [..]. 따라서 boolean , byte , charshort 와 같은 실제 유형의 값에 대한 대부분의 연산은 int 유형의 연산 유형에 대한 연산을 통해 올바르게 수행됩니다.

이것에 대한 이유는 또한 해당 섹션에 명시되어 있습니다.

자바 가상 머신의 1 바이트 연산 코드 크기를 감안할 때, 타입을 연산 코드로 인코딩하면 명령어 세트의 디자인에 부담을줍니다. 형식화 된 각 명령어가 모든 Java 가상 머신의 런타임 데이터 유형을 지원하면 byte 로 표현할 수있는 것보다 많은 명령어가있을 것입니다. [...] 필요에 따라 지원되지 않는 데이터 형식과 지원되는 데이터 형식간에 변환하는 데 별도의 지침을 사용할 수 있습니다.

int 프리미티브

int 와 같은 기본 데이터 유형은 값을 사용하는 변수에 직접 값을 보유하는 반면 Integer 사용하여 선언 된 변수는 값에 대한 참조를 보유합니다.

Java API 에 따르면 : "Integer 클래스는 객체의 기본 유형 int 값을 래핑합니다. Integer 유형의 객체에는 유형이 int 인 단일 필드가 들어 있습니다."

기본적으로 int 는 32 비트 부호있는 정수입니다. 1 - 이는 -2 (31)의 최소값 및 2 (31)의 최대 값을 저장할 수있다.

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의 최소값과 64 (2)의 최대 값을 저장할 수있는 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

a의 기본값 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 개의 오브젝트를 == does와 비교하는 것 같은 false negative가되지 않습니다.

불리언 프리미티브

booleantrue 또는 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

byte 프리미티브

byte 는 8 비트 부호있는 정수입니다. (127) 1 - 7은 -2 (-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 high = Byte.MAX_VALUE;        // high == 127
byte low = Byte.MIN_VALUE;         // low == -128

byte 의 기본값은 0입니다.

byte defaultByte;    // defaultByte == 0

float 프리미티브

float 는 단 정밀도 32 비트 IEEE 754 부동 소수점 숫자입니다. 기본적으로 소수는 double로 해석됩니다. float 을 만들려면 단순히 십진수 리터럴에 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 소수점의 정확한 표현 (화폐 금액과 같은) 또는 더 높은 정밀도가 필요한 숫자를 저장하는 데 float 이나 double 을 사용하면 안됩니다. 대신 BigDecimal 클래스를 사용해야합니다.

float 의 기본값은 0.0f 입니다.

float defaultFloat;    // defaultFloat == 0.0f

float 은 대략 1 천만의 1로 오차가 있습니다.

주 : Float.POSITIVE_INFINITY , Float.NEGATIVE_INFINITY , Float.NaNfloat 값입니다. NaN 은 2 개의 무한 값을 나누는 것과 같이 결정할 수없는 연산의 결과를 나타냅니다. 또한 0f-0f 는 다르지만 == 가 true가됩니다.

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.NaNdouble 값입니다. NaN 은 2 개의 무한 값을 나누는 것과 같이 결정할 수없는 연산의 결과를 나타냅니다. 또한 0d-0d 는 다르지만 == 가 true가됩니다.

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 비트 유니 코드 문자를 저장할 수 있습니다. 문자 리터럴은 작은 따옴표로 묶습니다.

char myChar = 'u';
char myChar2 = '5';
char myChar3 = 65; // myChar3 == 'A'

\u0000 의 최소값 (10 진수 표현에서는 0, NULL 문자 라고도 함) 및 \uffff (65,535)의 최대 값 \uffff 집니다.

char 의 기본값은 \u0000 입니다.

char defaultChar;    // defaultChar == \u0000

' 값의 문자를 정의하려면 이스케이프 시퀀스 (백 슬래시 앞에 문자)를 사용해야합니다.

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

당신은 선언 할 수 있습니다 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 를 정수 표현으로 저장합니다. 대부분의 중요한 가치 저장 비트 VITH 값 s . 그 비트들에 의해 repesented 값은

x-s * 2n-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).

이것은 또한 긍정적 인 이진수 인 것처럼 이진 표현을 추가 할 수 있다는 좋은 부작용이 있습니다.

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
= v1 + v2
0 1
(x1 + x2) mod 2n-1 = x1 + x2 - 2n-1
= v1 + v2
1 0 * 위 참조 (summand swap)
1 1 아니 데이터 유형을 표시하기에는 너무 작은 (X1 + X2 - 2 N <-2 N-1] 언더)
1 1
(x1 + x2) mod 2n-1 - 2n-1 = (x1 + x2 - 2n-1) - 2n-1
= (x1 - s1 * 2n-1) + (x2 - s2 * 2n-1)
= v1 + v2

이 사실은 부가적인 역함수 (즉, 음수 값)의 이진 표현을 쉽게 찾도록 만듭니다.

숫자에 비트 보수를 추가하면 모든 비트가 1이됩니다. 이제 1을 추가하여 값 오버플로를 만들고 중립 요소 0 (모든 비트 0)을 얻습니다.

따라서 숫자 i 의 음수 값은 (여기서 int 가능한 승격을 무시하고)

(~i) + 1

예 : 0 ( byte )의 음수 값 가져 byte :

0 을 무효화 한 결과는 11111111 입니다. 1을 추가하면 100000000 (9 비트)의 값이 제공됩니다. byte 는 8 비트 만 저장할 수 있기 때문에 가장 왼쪽 값이 잘리고 결과는 00000000

기발한 방법 결과
0 (00000000) 부정하다 -0 (11111111)
11111111 바이너리에 1을 더한다. 100000000
100000000 8 비트로 자른다. 00000000 (-0은 0과 동일)

프리미티브 (primitives) 대 박스형 프리미티브 (boxed primitives)의 메모리 소비

원선 박스형 기본 / 박스형 메모리 크기
부울 부울 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 개의 다른 null이 아닌 값을 저장하는 Float[5] 는 총 112 바이트가 필요합니다 (압축 된 포인터가없는 64 비트에서는 152 바이트로 증가).

박스형 값 캐시

박스형의 공간 오버 헤드는 박스형 값 캐시에 의해 어느 정도 완화 될 수 있습니다. 박스형의 일부는 인스턴스 캐시를 구현합니다. 예를 들어, 기본적으로 Integer 클래스는 -128 에서 +127 범위의 숫자를 나타 내기 위해 인스턴스를 캐시합니다. 그러나이 방법은 추가 메모리 간접 지정으로 인해 발생하는 추가 비용을 줄이지는 못합니다.

autoboxing 또는 static valueOf(primitive) 메소드를 호출하여 박스형의 인스턴스를 생성하면 런타임 시스템은 캐시 된 값을 사용하려고 시도합니다. 응용 프로그램이 캐시 된 범위에서 많은 값을 사용하면 박스형을 사용할 때의 메모리 패널티가 크게 줄어들 수 있습니다. 물론, "손으로"박스형 값 인스턴스를 만드는 경우 new 아닌 valueOf 를 사용하는 것이 좋습니다. 그러나 new 값은 항상 새 인스턴스를 만듭니다. 대부분의 값이 캐시 된 범위에 없으면 new 를 호출하고 캐시 조회를 저장하는 것이 더 빠릅니다.

프리미티브 변환

Java에서는 정수 값과 부동 소수점 값 사이를 변환 할 수 있습니다. 또한 모든 문자가 유니 코드 인코딩의 숫자와 일치하기 때문에 char 유형을 정수 및 부동 소수점 유형간에 변환 할 수 있습니다. boolean 은 다른 원시 데이터 유형으로 변환하거나 다른 원시 데이터 유형에서 변환 할 수없는 유일한 원시 데이터 유형입니다.

전환에는 확대 전환축소 전환 의 두 가지 유형이 있습니다.

확장 변환 은 한 데이터 유형의 값이 이전 데이터 유형보다 많은 비트를 차지하는 다른 데이터 유형의 값으로 변환되는 경우입니다. 이 경우 데이터 손실 문제는 없습니다.

따라서 좁은 변환 은 한 데이터 유형의 값이 이전 데이터 유형보다 적은 비트를 차지하는 다른 데이터 유형의 값으로 변환되는 경우입니다. 이 경우 데이터 손실이 발생할 수 있습니다.

Java는 자동으로 확장 변환을 수행합니다. 그러나 좁은 변환 을 수행하려는 경우 (데이터 손실이 발생하지 않는다고 확신하는 경우), Java가 cast 로 알려진 언어 구성을 사용하여 변환을 수행하도록 할 수 있습니다.

확대 변환 :

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

기본 유형 Cheatsheet

모든 기본 유형의 크기 및 값 범위를 보여주는 표 :

데이터 형식 수치 표현 값의 범위 기본값
부울 해당 없음 거짓과 참 그릇된
바이트 8 비트 부호 -2 7 ~ 2 7 - 1 0
-128 ~ +127
짧은 16 비트 부호 -2 15 ~ 2 15 -1 0
-32,768 ~ + 32,767
int 32 비트 부호 -2 31 내지 2 31 -1 0
-2,147,483,648에서 +2,147,483,647
64 비트 서명 -2 63 내지 2 63 -1 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 ~ 65,535

노트:

  1. 정수형 (부호 Java 언어 사양의 의무 byte 통해 long ) 이진의 보수 표현을 사용하고 부동 소수점 형식 표준 IEE 754 이진 부동 소수점 표현을 사용합니다.
  2. Java 8 이상에서는 intlong 에 대해 부호없는 산술 연산을 수행하는 메소드를 제공합니다. 이러한 메서드를 사용하면 프로그램에서 각 형식의 값을 부호없는 형식으로 처리 할 수 있지만 형식은 서명 된 형식으로 유지됩니다.
  3. 위에 표시된 가장 작은 부동 소수점은 비정규입니다 . 즉, 정상 값보다 정밀도가 떨어집니다. 최소 정규 수는 1.175494351e-38 및 2.2250738585072014e-308입니다.
  4. char 일반적으로 유니 코드 / UTF-16 코드 단위를 나타냅니다.
  5. boolean 에는 단지 1 비트의 정보 만 포함되어 있지만 메모리의 크기는 Java Virtual Machine 구현에 따라 다릅니다 ( 부울 유형 참조).


Modified text is an extract of the original Stack Overflow Documentation
아래 라이선스 CC BY-SA 3.0
와 제휴하지 않음 Stack Overflow