Sök…


Introduktion

De 8 primitiva datatyperna byte , short , int , long , char , boolean , float och double är de typer som lagrar mest råa numeriska data i Java-program.

Syntax

  • int aInt = 8; // Den definierande (nummer) delen av denna int-deklaration kallas en bokstavlig.

  • int hexInt = 0x1a; // = 26; Du kan definiera bokstäver med hexvärden förinställda med 0x .

  • int binInt = 0b11010; // = 26; Du kan också definiera binära bokstäver; förinställd med 0b .

  • länge braLång = 10000000000L; // Som standard är heltalslitteraler av typen int. Genom att lägga till L i slutet av det bokstavliga berättar du kompilatorn att bokstäverna är lång. Utan detta skulle kompilatorn kasta ett "heltal för stort" -fel.

  • dubbel aDouble = 3,14; // Flytande punktlitteraturer är av typen dubbel som standard.

  • float aFloat = 3,14F; // Som standard skulle denna bokstavliga ha varit ett dubbel (och orsakat ett "Inkompatibla typer" -fel), men genom att lägga till en F säger vi kompilatorn att det är en flottör.

Anmärkningar

Java har åtta primitiva datatyper , nämligen boolean , byte , short , char , int , long , float och double . (Alla andra typer är referenstyper . Detta inkluderar alla arraytyper och inbyggda objekttyper / klasser som har särskild betydelse för Java-språket; t.ex. String , Class och Throwable och dess underklasser.)

Resultatet av alla operationer (tillägg, subtraktion, multiplikation, etc) på en primitiv typ är åtminstone ett int , så att en short till en short ger en int , liksom att lägga till en byte till en byte , eller en char till en char . Om du vill tilldela resultatet av det tillbaka till ett värde av samma typ, måste du kasta det. t.ex

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

Om du inte kastar operationen kommer det att leda till ett kompileringsfel.

Detta beror på följande del av Java Language Spec, §2.11.1 :

En kompilator kodar massor av bokstavliga värden av typer byte och short hjälp av Java Virtual Machine-instruktioner som signerar-utökar dessa värden till värden av typ int vid kompileringstid eller körtid. Massor av bokstavliga värden av typen boolean och char kodas med hjälp av instruktioner som nollförlänger den bokstavliga till ett värde av typ int vid kompileringstid eller körtid. [..]. Således utförs de flesta operationer på värden på faktiska typer boolean , byte , char och short korrekt med instruktioner som arbetar med värden för beräkningstyp int .

Anledningen till detta anges också i det avsnittet:

Med tanke på Java Virtual Maskins en-byte-opkodstorlek , sätter kodningstyper till opcodes tryck på utformningen av dess instruktionsuppsättning. Om varje typad instruktion stödde alla Java Virtual Maskins runtime-datatyper skulle det finnas fler instruktioner än vad som kan representeras i en byte . [...] Separata instruktioner kan användas för att konvertera mellan datorstyper som inte stöds och stöds vid behov.

Den int primitiva

En primitiv datatyp som int håller värden direkt i den variabel som använder den, medan en variabel som deklarerades med Integer har en referens till värdet.

Enligt java API : "Integer-klassen lindar ett värde på den primitiva typen int i ett objekt. Ett objekt av typen Heltal innehåller ett enda fält vars typ är int."

Som standard är int ett 32-bitars signerat heltal. Den kan lagra ett minimivärde av -2 31 och ett maxvärde på 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

Om du behöver lagra ett nummer utanför detta intervall, bör du använda long istället. Överskridande av värdeintervallet för int leder till ett heltalöverskridande, vilket orsakar att värdet överskrider intervallet läggs till motsatt plats i intervallet (positivt blir negativt och vice versa). Värdet är ((value - MIN_VALUE) % RANGE) + MIN_VALUE eller ((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

Max- och minimivärden för int kan hittas på:

int high = Integer.MAX_VALUE;    // high == 2147483647
int low = Integer.MIN_VALUE;     // low == -2147483648

Standardvärdet för en int är 0

int defaultInt;    // defaultInt == 0

Den korta primitiva

En short är ett 16-bitars signerat heltal. Det har ett minimivärde av -2 15 (-32,768) och ett maximivärde av 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

Max- och minimivärdena för short finns på:

short high = Short.MAX_VALUE;        // high == 32767
short low = Short.MIN_VALUE;         // low == -32768

Standardvärdet för en short är 0

short defaultShort;    // defaultShort == 0

Den långa primitiva

Som standard är long ett 64-bitars signerat heltal (i Java 8 kan det antingen vara signerat eller osignerat). Undertecknad kan den lagra ett minimivärde av -2 63 , och ett maximivärde av 2 63 - 1, och utan signerad kan det lagra ett minimivärde av 0 och ett maximivärde av 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

Max- och minimivärden för long finns på:

long high = Long.MAX_VALUE;    // high == 9223372036854775807L
long low = Long.MIN_VALUE;     // low == -9223372036854775808L

Standardvärdet för en long är 0L

long defaultLong;    // defaultLong == 0L

Obs: bokstaven "L" bifogad i slutet av long bokstäver är falllöst känslig, men det är god praxis att använda kapital eftersom det är lättare att skilja från siffran ett:

2L == 2l;            // true

Varning: Java-cacheminne Heltalsobjekt förekommer från intervallet -128 till 127. Motiveringen förklaras här: https://blogs.oracle.com/darcy/entry/boxing_and_caches_integer_valueof

Följande resultat kan hittas:

Long val1 = 127L;
Long val2 = 127L;

System.out.println(val1 == val2); // true

Long val3 = 128L;
Long val4 = 128L;

System.out.println(val3 == val4); // false

För att jämföra 2 Objekt Långa värden använder du följande kod (Från Java 1.7 och framåt):

Long val3 = 128L;
Long val4 = 128L;

System.out.println(Objects.equal(val3, val4)); // true

Att jämföra en primitiv lång med ett objekt lång kommer inte att resultera i ett falskt negativt som att jämföra två objekt med == gör.

Den booleska primitiva

En boolean kan lagra ett av två värden, antingen true eller 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

Standardvärdet för en boolean är falskt

boolean defaultBoolean;    // defaultBoolean == false

Den byte primitiva

En byte är ett 8-bitars signerat heltal. Den kan lagra ett minimivärde av -2 7 (-128) och ett maximivärde av 2 7 - 1 (127)

byte example = -36;
byte myByte = 96;
byte anotherByte = 7;

byte addedBytes = (byte) (myByte + anotherByte); // 103
byte subtractedBytes = (byte) (myBytes - anotherByte); // 89

Max- och minimivärden för byte kan hittas på:

byte high = Byte.MAX_VALUE;        // high == 127
byte low = Byte.MIN_VALUE;         // low == -128

Standardvärdet för en byte är 0

byte defaultByte;    // defaultByte == 0

Float primitivt

En float är ett 32-bitars IEEE 754-flytpunktsnummer med en enda precision. Som standard tolkas decimaler som dubbletter. För att skapa en float bara lägga till en f till decimalbokstäverna.

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

Floats hanterar de fem vanliga aritmetiska operationerna: tillägg, subtraktion, multiplikation, delning och modul.

Obs: Följande kan variera något till följd av flytande punktfel. Vissa resultat har avrundats för tydlighet och läsbarhet (dvs. det tryckta resultatet av tilläggsexemplet var faktiskt 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

På grund av hur flytande punktnummer lagras (dvs. i binär form) har många nummer inte en exakt representation.

float notExact = 3.1415926f;
System.out.println(notExact); // 3.1415925

Även om det är bra att använda float för de flesta applikationer, bör varken float eller double användas för att lagra exakta representationer av decimaltal (som monetära belopp) eller siffror där högre precision krävs. Istället BigDecimal klassen BigDecimal användas.

Standardvärdet för en float är 0,0f .

float defaultFloat;    // defaultFloat == 0.0f

En float är exakt till ungefär ett fel på 1 av 10 miljoner.

Obs: Float.POSITIVE_INFINITY , Float.NEGATIVE_INFINITY , Float.NaN är float NaN står för resultat av operationer som inte kan bestämmas, till exempel att dela två oändliga värden. Dessutom är 0f och -0f olika, men == ger sant:

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

Den dubbla primitiva

En double är ett dubbelprecision 64-bitars IEEE 754 flytande punktnummer.

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

På grund av hur flytande punktnummer lagras har många nummer ingen exakt representation.

double notExact = 1.32 - 0.42; // result should be 0.9
System.out.println(notExact); // 0.9000000000000001

Även om du använder double är bra för de flesta applikationer, bör varken float eller double användas för att lagra exakta siffror som valuta. Istället BigDecimal klassen BigDecimal användas

Standardvärdet för en double är 0,0d

public double defaultDouble;    // defaultDouble == 0.0

Obs: Double.POSITIVE_INFINITY , Double.NEGATIVE_INFINITY , Double.NaN är double värden. NaN står för resultat av operationer som inte kan bestämmas, till exempel att dela två oändliga värden. Dessutom är 0d och -0d olika, men == ger sant:

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

Den röda primitiva

En char kan lagra ett enda 16-bitars Unicode-tecken. En bokstavlig bokstav finns i enkla citat

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

Det har ett \u0000 (0 i decimalrepresentationen, även kallad nolltecknet ) och ett maximivärde på \uffff (65,535).

Standardvärdet för en char är \u0000 .

char defaultChar;    // defaultChar == \u0000

För att definiera en karaktär med ' värde måste en flygsekvens (tecken som föregås av ett backslash) användas:

char singleQuote = '\'';

Det finns också andra flykt-sekvenser:

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

Du kan förklara en char av alla Unicode-karaktärer.

char heart = '\u2764';
System.out.println(Character.toString(heart)); // Prints a line containing "❤".

Det är också möjligt att lägga till en char . till exempel för att upprepa alla små bokstäver, kan du göra följande:

for (int i = 0; i <= 26; i++) {
    char letter = (char) ('a' + i);
    System.out.println(letter);
}

Negativt värde representation

Java och de flesta andra språk lagrar negativa integrala nummer i en representation som kallas 2: s komplementnotation .

För en unik binär representation av en datatyp med hjälp av n bitar kodas värdena så här:

De minst signifikanta n-1 bitarna lagrar ett positivt integralt antal x i integrerad representation. Det mest betydande värdet lagrar lite med värdet s . Värdet som repeteras av dessa bitar är

x - s * 2 n-1

dvs om den mest signifikanta biten är 1, då är ett värde som är bara 1 större än antalet du kan representera med de andra bitarna ( 2 n-2 + 2 n-3 + ... + 2 1 + 2 0 = 2 n-1 - 1 ) subtraheras vilket tillåter en unik binär representation för varje värde från - 2 n-1 (s = 1; x = 0) till 2 n-1 - 1 (s = 0; x = 2 n-1 - 1).

Detta har också den trevliga bieffekten att du kan lägga till de binära representationerna som om de var positiva binära siffror:

v1 = x1 - s1 * 2n-1
v2 = x2 - s2 * 2n-1
s1 s2 x1 + x2 överflöde tilläggsresultat
0 0 Nej x1 + x2 = v1 + v2
0 0 Ja för stor för att representeras med datatyp (översvämning)
0 1 Nej
x1 + x2 - 2n-1 = x1 + x2 - s2 * 2n-1
= v1 + v2
0 1 Ja
(x1 + x2) mod 2n-1 = x1 + x2 - 2n-1
= v1 + v2
1 0 * se ovan (byta summands)
1 1 Nej för liten för att representeras med datatyp (x1 + x2 - 2 n <-2 n-1 ; underflöde)
1 1 Ja
(x1 + x2) mod 2n-1 - 2n-1 = (x1 + x2 - 2n-1) - 2n-1
= (x1 - s1 * 2n-1) + (x2 - s2 * 2n-1)
= v1 + v2

Observera att detta faktum gör det lätt att hitta binär representation av tillsatsen invers (dvs. det negativa värdet):

Observera att lägga till det bitvisa komplementet till antalet resulterar i att alla bitar är 1. Lägg nu till 1 för att göra överflödet av värde och du får det neutrala elementet 0 (alla bitar 0).

Så det negativa värdet på ett tal i kan beräknas med (ignorera möjlig kampanj till int här)

(~i) + 1

Exempel: ta det negativa värdet 0 ( byte ):

Resultatet av att negera 0 är 11111111 . Att lägga till 1 ger ett värde av 100000000 (9 bitar). Eftersom en byte bara kan lagra 8 bitar, trunkeras det vänstra värdet och resultatet är 00000000

Original Bearbeta Resultat
0 (00000000) Förneka -0 (11111111)
11111111 Lägg till 1 i binär 100000000
100000000 Avkorta till 8 bitar 00000000 (-0 är lika med 0)

Minnesförbrukning av primitiva kontra boxade primitiva

Primitiv Boxed Type Minne Storlek på primitiv / låda
boolean Boolean 1 byte / 16 byte
bitgrupp byte 1 byte / 16 byte
kort Kort 2 byte / 16 byte
röding Röding 2 byte / 16 byte
int Heltal 4 byte / 16 byte
lång Lång 8 byte / 16 byte
flyta Flyta 4 byte / 16 byte
dubbel- Dubbel 8 byte / 16 byte

Boxade objekt kräver alltid 8 byte för typ- och minneshantering, och eftersom storleken på objekt alltid är en multipel av 8 kräver alla boxade typer 16 byte totalt . Dessutom innebär varje användning av ett boxat objekt att lagra en referens som står för ytterligare 4 eller 8 byte, beroende på JVM- och JVM-alternativ.

Vid datakrävande operationer kan minneskonsumtion ha stor inverkan på prestandan. Minneskonsumtionen växer ännu mer när du använder matriser: en float[5] -grupp kräver endast 32 byte; medan en Float[5] lagrar 5 distinkta icke-nollvärden kommer att kräva 112 byte totalt (på 64 bitar utan komprimerade pekare ökar detta till 152 byte).

Cacheminne för boxningsvärde

Rymdomkostnaderna för boxade typer kan mildras i viss utsträckning av cacheminnet med boxvärde. Vissa av de boxade typerna implementerar en cache av instanser. Till exempel, som Integer kommer heltalsklassen att cache-instanser för att representera siffror i intervallet -128 till +127 . Detta minskar emellertid inte den extra kostnaden som uppstår till följd av den extra minnesdirektionen.

Om du skapar en instans av en boxad typ antingen genom autoboxing eller genom att anropa valueOf(primitive) statisk valueOf(primitive) försöker runtime-systemet att använda ett cache-värde. Om din applikation använder många värden i cache-cacheområdet kan det minska minnestraffet för att använda boxade typer avsevärt. Visst, om du skapar inställda värden i rutor "för hand", är det bättre att använda valueOf snarare än new . (Den new åtgärden skapar alltid en ny instans.) Om huvuddelen av dina värden emellertid inte är i cacheområdet, kan det vara snabbare att ringa new och spara cacheuppslaget.

Konvertera primitiv

I Java kan vi konvertera mellan heltalvärden och flytpunktsvärden. Eftersom alla tecken motsvarar ett nummer i Unicode-kodningen, kan char typer också konverteras till och från heltal- och flytpunkttyperna. boolean är den enda primitiva datatypen som inte kan konverteras till eller från någon annan primitiv datatyp.

Det finns två typer av omvandlingar: bredda konverteringen och minska konverteringen .

En utvidgad konvertering är när ett värde på en datatyp konverteras till ett värde på en annan datatyp som upptar fler bitar än den förra. Det finns ingen fråga om dataförlust i detta fall.

På motsvarande sätt är en minskande konvertering när ett värde på en datatyp konverteras till ett värde på en annan datatyp som upptar färre bitar än den förra. Dataförlust kan uppstå i detta fall.

Java utför utvidgade omvandlingar automatiskt. Men om du vill utföra en förminskande konvertering (om du är säker på att ingen dataförlust kommer att inträffa) kan du tvinga Java att utföra konverteringen med en språkkonstruktion som kallas en cast .

Bredare konvertering:

int a = 1;    
double d = a;    // valid conversion to double, no cast needed (widening)

Begränsa konvertering:

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

Primitiva typer Cheatsheet

Tabell som visar storlek och värden för alla primitiva typer:

data typ numerisk representation värderingsintervall standardvärde
boolean n / a falskt och sant falsk
bitgrupp 8-bitars signerad -2 7 till 2 7 - 1 0
-128 till +127
kort 16-bitars signerad -2 15 till 2 15 - 1 0
-32,768 till +32,767
int 32-bitars signerad -2 31 till 2 31 - 1 0
-2,147,483,648 till +2,147,483,647
lång 64-bitars signerad -2 63 till 2 63 - 1 0L
-9,223,372,036,854,775,808 till 9,223,372,036,854,775,807
flyta 32-bitars flytande punkt 1.401298464e-45 till 3.402823466e + 38 (positiv eller negativ) 0.0F
dubbel- 64-bitars flytande punkt 4.94065645841246544e-324d till 1.79769313486231570e + 308d (positiv eller negativ) 0.0D
röding 16-bitars osignerad 0 till 2 16 - 1 0
0 till 65,535

Anmärkningar:

  1. Java-språkspecifikationen kräver att signerade integrerade typer ( byte genom long ) använder binär två-komplementrepresentation, och flytpunkttyperna använder standard IEE 754 binära flytpunktsrepresentationer.
  2. Java 8 och senare tillhandahåller metoder för att utföra osignerade aritmetiska operationer på int och long . Medan dessa metoder tillåter ett program att behandla värden för respektive typ som osignerade, förblir typerna signerade typer.
  3. Den minsta flytande punkten som visas ovan är subnormal ; dvs de har mindre precision än ett normalt värde. De minsta normala siffrorna är 1.175494351e − 38 och 2.2250738585072014e − 308
  4. Ett char representerar konventionellt en Unicode / UTF-16- kodenhet .
  5. Även om en boolean innehåller bara en bit information, varierar dess storlek i minnet beroende på Java Virtual Machine-implementeringen (se boolesktyp ).


Modified text is an extract of the original Stack Overflow Documentation
Licensierat under CC BY-SA 3.0
Inte anslutet till Stack Overflow