There are 10 types of people in the world: those who understand binary numbers and those who don't.
Data in computer programs are stored in variables.
A variable's name corresponds to some location in computer
memory where the value of that variable is stored.
Suppose you could “see” the binary value stored in some memory
location.
For example say the variable “foo
” corresponds
to the memory address 1280
, and when you “looked”
at that part of memory you saw the following:
0 1 0 0 0 1 1 0 1 1 0 1 1 1 1 0 ...
There is no way for you (or a computer) to know what it means. It could be an integer, a string of characters, a floating point number, or something else (part of a GIF graphic, for example). This is one reason why all Java variables have a declared type. The type of a variable tells the computer how to interpret the data.
Java provides many different built-in (or primitive) types you can use for your variables. As a programmer you must be able to pick an appropriate type for the kind of data you expect to store in any variable. In general prefer integral (“fixed point”) types to “floating point” types, and prefer smaller types to larger ones. You do need to ensure you chose a type that is large enough to hold the full range of values expected (which should be documented as part of the requirements), and will be accurate enough.
Float and double are useful with scientific and engineering computation, and with statistics. Outside of these areas they should mostly be avoided. Float is preferred to double when memory is short, or when you need a very large number of values and can tolerate the lower precision. The performance advantage of floats to doubles is modest on modern hardware, and should not be a consideration.
For most applications you can chose int
, even when
a smaller integral type has an appropriate range.
As with floats, the smaller types are useful when you need a lot
of them and/or when memory use must be minimized.
Note most financial calculations can be calculated in fixed
point, that is using integers (calculate in pennies or
even thousandths of a cent).
Type | Size | Format | Range | Literals | Comments |
---|---|---|---|---|---|
boolean | ≤1 byte | — | — | false ,
true |
Use for on/off (checkbox) settings |
byte | 1 byte | signed integer | ±127 | −3, 0, 10, 124 | Use to store lots of small numbers (e.g., temperatures, years of service, test scores) |
short | 2 bytes | signed integer | ±32,767 | −130, −3, 0, 10, 124, 25000 | Use to store lots of small numbers too big for a byte |
char | 2 bytes | unsigned integer | 0 to +65,535 | 0, 124, 44000, 'A', '\u00A9' | Use for Unicode
character codes, including '\\' , '\n' ,
'\r' , '\t' , '\'' ,
and '\udddd' |
int | 4 bytes | signed integer | ±2,147,483,647 | −10, 0, 12, 120000, 1_200_000, 017 (octal), 0x2F (hex), 0b100 (binary) | Use to store or compute with integers; the most commonly used type |
long | 8 bytes | signed integer | ±9,223,372,036,854,775,807 | −10L, −3L, 0L, 10L, 250_000_000L | Use to store compute with integers too large for an int |
float | 4 bytes | floating point | ±10^{38} | −6F, 0.F, 0.0F, 3.14F, 6F, 6.02E23F, 1E2F, −1E2F, 1E−2F | Use to store or compute with rational numbers (numbers with decimal points or in scientific notation); has 6 decimal digits of accuracy. |
double | 8 bytes | floating point | ±10^{308} | −10.0, 0.0, 0.0D, 3.14, 12., 120000D | Similar to float but with greater range and 14 decimal digits
of accuracy. |
Most people consider using a signed value for byes a mis-feature in Java. The most common use for a byte is to hold non-ASCII data which is unsigned. So to process a GIF file read into an array of bytes requires a conversion:
int num = someByte < 0 ? someByte+256 : someByte;
byte
, short
,
and int
.
The only difference is the magnitude of the values, and what you are
doing with it.
For example:
byte b = 3; int i = 3;
Java doesn't have byte
or short
literals;
instead, int
literals are automatically narrowed or
widened as needed.
(Interestingly, char
literals such as 'a'
are first
converted to int
, which is then narrowed to short
or byte
as needed.
This means
“byte b = '\uXXXX';
”
might result in a negative value, if “XXXX
”
is large enough.)
0x
”
or “0X
”, and (new in Java 7) binary literals
start with “0b
” or “0b
”.
So 17
is the decimal number for seventeen, 017
is the octal number for fifteen, 0x17
is the
hex number for twenty-three, and 0b101
is the binary number
for five.
Further information on binary, octal, decimal, and hex numbers can
be found by searching the Internet, for example
Bin Dec Hex Tutorial.
1_234_567
” or “0x__0F
”.
Note such literals can't start or end with an underscore.
(As of May 2010, Integer.parseInt
and Long.parseLong
don't support using underscores this way.)
±num
" really means
"−(num+1)
to +num
".)
Just for fun, here's what the 3–bit two's complment numbers look like:
Decimal | Binary | Decimal | Binary | ||
---|---|---|---|---|---|
+3 | 0 1 1 | −1 | 1 1 1 | ||
+2 | 0 1 0 | −2 | 1 1 0 | ||
+1 | 0 0 1 | −3 | 1 0 1 | ||
0 | 0 0 0 | −4 | 1 0 0 |
3 bit two's complement signed integers
sign | exponent | mantissa |
---|
The sign is a single bit, zero for positive and one for
negative.
The exponent is a signed integer (but not in two's complment).
The mantissa (or fraction) is an unsigned integer,
with a descimal point assumed to be present at the far left end.
The larger the exponent field, the larger the range of the number, and
the larger the mantissa, the greater the accuracy. Given a limited
number of bits in a float
or double
, there
is a trade-off of these values.
Floating point number are never accurate, there is always some floating point round-off error. (This is not a problem for integers, which is the main reason to always pick an integer type if you possibly can. Note financial calculations can often be done using integers if you compute everying in pennies, and divide by 100 at the end to get dollars and cents.)
As an example pretend an 8–bit floating point format
(Java doesn't have any one byte floating point types) has 1 sign bit,
a 3–bit one's complement exponent, and a 4–bit mantissa.
Then the bit pattern of 00101101
can be intrepreted as:
sign | exponent | mantissa |
---|---|---|
0 | 0 1 0 | 1 1 0 1 |
Here the sign is positive, the exponent is 2
,
and the mantissa is .1101
.
The result is binary +11.01
, which in decimal
would be +3.25
.
strictfp
modifier.java.math
package,
"BigInteger
" and "BigDecimal
".
These are object types (not primitives), and can be much slower than
using primitive types. However there is no limit on the size of the values.
(See Big Numbers Demo for more information.)
String
literal is enclosed in double quotes:
"Howdy \"Wayne\"\n"
.
You can declare String
object references like this:
String msg = "Hello";
In Java strings are not a basic type but are objects of
class String
.
All identical String
literals in a program are collapsed
into a single object, so:
String s1 = "foo", s2 = "foo"; s1 == s2 true
but this can get tricky:
String s1 = "foo"; s2 = new String("foo"); s1 == s2 false
String
s can be concatenated using a plus symbol.
This allows one to break up String
literals too long
for a single line.
(Example: "ABC" + "DEF"
results in "ABCDEF"
.)
null
, which is a specal value that means this variable
doesn't refer to any object.
For example: String name = null;
. static
methods).
(Example: Integer.toString(int)
to convert an int
to a String
object, as can String.valueOf(int)
.)
To convert from String
s to primitive types, use one of the
parseXXX()
methods.
Examples : Integer.parseInt( "17" );
or
Float.parseFloat( "3.14F" );