Primitive Data Types in Java
Primitive Data Types in Java
Java's primitive data types are very similar to those of C. They include boolean, byte,
short, int, long, float, double, and char. The boolean type has been added. However the
implementation of the data types has been substantially cleaned up in several ways.
1. Where C and C++ leave a number of issues to be machine and compiler dependent
(for instance the size of an int) Java specifies everything.
2. Java prevents casting between arbitrary variables. Only casts between numeric
variables and between sub and superclasses of the same object are allowed.
3. All numeric variables in Java are signed.
sizeofisn't necessary in Java because all sizes are precisely defined. For instance, an int is
always 4 bytes. This may not seem to be adequate when dealing with objects that aren't base
data types. However even if you did know the size of a particular object, you couldn't do
anything with it anyway. You cannot convert an arbitrary object into bytes and back again.
Java's Primitive Data Types
boolean
byte
short
int
long
float
Like all numeric types floats may be cast into other numeric types ( byte, short, long, int,
double). When lossy casts to integer types are done (e.g. float to short) the fractional part
is truncated and the conversion is done modulo the length of the smaller type.
double
8 bytes IEEE 754. Covers a range from 4.94065645841246544e-324d to
1.79769313486231570e+308d (positive or negative).
char
Operator Purpose
+ addition of numbers, concatenation of Strings
+= add and assign numbers, concatenate and assign Strings
- subtraction
-= subtract and assign
* multiplication
*= multiply and assign
/ division
/= divide and assign
% take remainder
%= take remainder and assign
++ increment by one
-- decrement by one
> greater than
>= greater than or equal to
< less than
<= less than or equal to
! boolean NOT
!= not equal to
&& boolean AND
|| boolean OR
== boolean equals
= assignment
~ bitwise NOT
?: conditional
instanceof type checking
| bitwise OR
|= bitwise OR and assign
^ bitwise XOR
^= bitwise XOR and assign
& bitwise AND
&= bitwise AND and assign
>> shift bits right with sign extension
>>= shift bits right with sign extension and assign
<< shift bits left
<<= shift bits left and assign
>>> unsigned bit shift right
>>>= unsigned bit shift right and assign
White Space
White space consists mostly of the space character that you produce by hitting the
space bar on your keyboard and that is commonly used to separate words in sentences.
There are four other white space characters in Java, the horizontal tab, the form feed, the
carriage return, and the linefeed. Depending on your platform, when you hit the return or enter
key, you get either a carriage return (the Mac), a linefeed (Unix) or both (DOS, Windows,
VMS). This produces a hard line break in the source code text.
Outside of String literals Java treats all white space and runs of white space (more than
one white space character in immediate succession) the same. It's used to separate tokens,
and one space is as good as seven spaces, a tab and two carriage returns. Exactly which
white space characters you use is primarily a result of what's convenient for human beings
reading the code. The compiler doesn't care.
Inside String and character literals the only white space permitted is the space character.
Carriage returns, tabs, line feeds and form feeds must be inserted with special escape
sequences like \r, \t, \f, and \n. You cannot break a String across a line like this:
Instead you must use \n and the string concatenation operator, +, like this:
Note that you can break a statement across multiple lines, you just can't break a String literal.
Also note that \n only works on Unix. You should probably use System.getProperty("line.separator")
instead to return the proper line separator string for the platform your program is running on.
Java does not have all the escape sequences C has. Besides those already mentioned it has
only \b for backspace, \\ for the backslash character itself.
There are also \u escapes that let you include any Unicode character.
Literals
Literals are pieces of Java source code that mean exactly what they say. For instance
"Hello World!" is a String literal and its meaning is the words Hello World!
The string "Hello World!" looks like it's several things; but to the compiler it's just one
thing, a String. This is similar to how an expression like 1,987,234 may be seven digits and two
commas but is really just one number.
The double quote marks tell you this is a string literal. A string is an ordered collection
of characters (letters, digits, punctuation marks, etc.). Although the String may have meaning
to a human being reading the code, the computer sees it as no more than a particular set of
letters in a particular order. It has no concept of the meaning of the characters. For instance it
does not know that "two" + "two" is "four." In fact the computer thinks that "two" + "two" is
"twotwo"
The quote marks show where the string begins and ends. However the quote marks
themselves are not a part of the string. The value of this string is Hello World!, not "Hello
World!" You can change the output of the program by changing Hello World to some other line
of text.
A string in a Java program has no concept of italics, bold face, font family or other
formatting. It cares only about the characters that compose it. Even if you're using an editor
like NisusWriter that lets you format text files, "Hello World!" is identical to "Hello World!" as
far as Java is concerned.
charliterals are similar to string literals except they're enclosed in single quotes and must have
exactly one character. For example 'c' is a char literal that means the letter c.
true and false are boolean literals that mean true and false.
Numbers can also be literals. 34 is an int literal and it means the number thirty-four. 1.5 is a
double literal. 45.6, 76.4E8 (76.4 times 10 to the 8th power) and -32.0 are also double literals.
34L is a long literal and it means the number thirty-four. 1.5F is a float literal. 45.6f, 76.4E8F and
-32.0F are also float literals.
Identifiers in Java
Identifiers are the names of variables, methods, classes, packages and interfaces.
Unlike literals they are not the things themselves, just ways of referring to them. In the
HelloWorld program, HelloWorld, String, args, main and println are identifiers.
Identifiers must be composed of letters, numbers, the underscore _ and the dollar sign
$. Identifiers may only begin with a letter, the underscore or a dollar sign.
Each variable has a name by which it is identified in the program. It's a good idea to give
your variables mnemonic names that are closely related to the values they hold. Variable
names can include any alphabetic character or digit and the underscore _. The main
restriction on the names you can give your variables is that they cannot contain any white
space. You cannot begin a variable name with a number. It is important to note that as in C
but not as in Fortran or Basic, all variable names are case-sensitive. MyVariable is not the same
as myVariable. There is no limit to the length of a Java variable name. The following are legal
variable names:
MyVariable
myvariable
MYVARIABLE
x
i
_myvariable
$myvariable
_9pins
andros
OReilly
This_is_an_insanely_long_variable_name_that_just_keeps_going_and_going_and_going_and_well_yo
u_get_the_idea_The_line_breaks_arent_really_part_of_the_variable_name_Its_just_that_this_variable_
name_is_so_ridiculously_long_that_it_won't_fit_on_the_page_I_cant_imagine_why_you_would_need_s
uch_a_long_variable_name_but_if_you_do_you_can_have_it
If you want to begin a variable name with a digit, prefix the name you'd like to have (e.g. 8ball)
with an underscore, e.g. _8ball. You can also use the underscore to act like a space in long
variable names.
Keywords
Keywords are identifiers like public, static and class that have a special meaning inside Java
source code and outside of comments and Strings. Four keywords are used in Hello World,
public, static, void and class.
Keywords are reserved for their intended use and cannot be used by the programmer for
variable or method names.
There are fifty reserved keywords in Java 1.1, 51 in Java 1.2, 52 in Java 1.4, and 54 in Java
5. The forty-eight that are actually used in are listed below. Don't worry if the purposes of the
keywords seem a little opaque at this point. They will all be explained in much greater detail
later.
Two other keywords, const and goto, are reserved by Java but are not actually implemented.
This allows compilers to produce better error messages if these common C++ keywords are
improperly used in a Java program.
Java 1.2 adds the strictfp keyword to declare that a method or class must be run with exact
IEEE 754 semantics.
trueand false appear to be missing from this list. In fact, they are not keywords but rather
boolean literals. You still can't use them as a variable name though.
Separators in Java
Separators help define the structure of a program. The separators used in HelloWorld are
parentheses, ( ), braces, { }, the period, ., and the semicolon, ;. The table lists the six Java
separators (nine if you count opening and closing separators as two).
Separator
Purpose
() Encloses arguments in method definitions and calling; adjusts precedence in
arithmetic expressions; surrounds cast types and delimits test expressions in flow
control statements
{} defines blocks of code and automatically initializes arrays
[] declares array types and dereferences array values
; terminates statements
separates successive identifiers in variable declarations; chains statements in the
,
test, expression of a for loop
Selects a field or method from an object; separates package names from sub-
.
package and class names
: Used after loop labels
int i = 1;
int j = 2;
int k = i + j;
System.out.println("i + j is " + k);
k = i - j;
System.out.println("i - j is " + k);
$ javac AddInts.java
$ java AddInts
i is 1
j is 2
i + j is 3
i - j is -1
class AddDoubles {
double x = 7.5;
double y = 5.4;
double z = x + y;
System.out.println("x + y is " + z);
z = x - y;
System.out.println("x - y is " + z);
% javac AddDoubles.java
% java AddDoubles
x is 7.5
y is 5.4
x + y is 12.9
x - y is 2.0999999999999996
class MultiplyDivide {
int i = 10;
int j = 2;
System.out.println("i is " + i);
System.out.println("j is " + j);
int k = i/j;
System.out.println("i/j is " + k);
k = i * j;
System.out.println("i * j is " + k);
% javac MultiplyDivide.java
% java MultiplyDivide
i is 10
j is 2
i/j is 5
i * j is 20
Floats and doubles are multiplied and divided in exactly the same way. When faced with an
inexact integer division, Java rounds the result down. For instance dividing 10 by 3 produces
3.
Unexpected Quotients
2/3 = 0
3/2 = 1
1/0 = ArithmeticException
0/0 = ArithmeticException
1.0/0.0 = Inf
1.0/0 = Inf
0.0/0.0 = NaN
-1.0/0.0 = -Inf
Inf + 1 = Inf
Inf/Inf = NaN
class Remainder {
public static void main (String args[]) {
int i = 10;
int j = 3;
int k = i % j;
System.out.println("i%j is " + k);
}
% javac Remainder.java
% java Remainder
i is 10
j is 3
i%j is 1
Perhaps surprisingly the remainder operator can be used with floating point values as
well. It's surprising because you don't normally think of real number division as producing
remainders. However there are rare times when it's useful to ask exactly how many times
does 1.5 go into 5.5 and what's left over? The answer is that 1.5 goes into 5.5 three times
with one left over, and it's that one which is the result of 5.5 % 1.5 in Java.
int m = 1 + 2 + 3 + 4 + 5;
A slightly more interesting example: the following program calculates the energy equivalent of
an electron using Einstein's famous formula E = mc 2.
class mc2 {
public static void main (String args[]) {
double mass = 9.1096E-25;
double c = 2.998E8;
double E = mass * c * c;
System.out.println(E);
}
}
$ javac mc2.java
$ java mc2
8.18771e-08
This is all very obvious. However if you use different operators on the same line it's not
always clear what the result will be. For instance consider the following code fragment:
int n = 1 - 2 * 3 - 4 + 5;
Is n equal to -2? You might think so if you just calculate from left to right. However if you
compile this in a program and print out the result you'll find that Java thinks n is equal to -4.
Java got that number because it performs all multiplications before it performs any additions
or subtractions. If you like you can think of the calculation Java did as being:
int n = 1 - (2 * 3) - 4 + 5;
This is an issue of order of evaluation. Within the limited number of operators you've learned
so far here is how Java calculates:
Parentheses in Java
Sometimes the default order of evaluation isn't what you want. For instance, the
formula to change a Fahrenheit temperature to a Celsius temperature is C = (5/9) (F - 32)
where C is degrees Celsius and F is degrees Fahrenheit. You must subtract 32 from the
Fahrenheit temperature before you multiply by 5/9, not after. You can use parentheses to
adjust the order much as they are used in the above formula. The next program prints a table
showing the conversions from Fahrenheit and Celsius between zero and three hundred
degrees Fahrenheit every twenty degrees.
// step size
double step = 20.0;
Parentheses in Java
As usual here's the output:
% javac FahrToCelsius.java
% java FahrToCelsius
0 -17.7778
20 -6.66667
40 4.44444
60 15.5556
80 26.6667
100 37.7778
120 48.8889
140 60
160 71.1111
180 82.2222
200 93.3333
220 104.444
240 115.556
260 126.667
280 137.778
300 148.889
This program is a little more involved than the previous examples. Mostly it's stuff you've seen
before though so a line by line analysis isn't necessary. The line to be concerned with is
This is a virtual translation of the formula C = (5/9)(F - 32) with the single change that a * was
added because Java does not implicitly multiply items in parentheses. The parentheses are
used just as they are in regular algebra, to adjust the precedence of terms in a formula. In fact
the precedence of operations that use the basic arithmetic operators ( +, -, *, /) is exactly the
same as you learned in high school algebra.
Remember, you can always use parentheses to change the order of evaluation. Everything
inside the parentheses will be calculated before anything outside of the parentheses is
calculated. If you're in doubt it never hurts to put in extra parentheses to clear up the order in
which terms will be evaluated.
class IntAndDouble {
int i = 10;
double x = 2.5;
double k;
k = i + x;
System.out.println("i + x is " + k);
k = i * x;
System.out.println("i * x is " + k);
k = i - x;
System.out.println("i - x is " + k);
k = x - i;
System.out.println("x - i is " + k);
k = i / x;
System.out.println("i / x is " + k);
k = x / i;
System.out.println("x / i is " + k);
% java IntAndDouble
i is 10
x is 2.5
i + x is 12.5
i * x is 25
i - x is 7.5
x - i is -7.5
i / x is 4
x / i is 0.25
%
1 / 2 * 3.5 = 0.0
3.5 * 1 / 2 = 1.75
3.5 / 2 = 1.75
You cannot assume that the usual mathematical laws of commutativity apply when mixing
data types, especially integer and floating point types.
The basic rule is that if either of the variables in a binary operation (addition, multiplication,
subtraction, addition, remainder) are doubles then Java treats both values as doubles. If
neither value is a double but one is a float, then Java treats both values as floats. If neither is a
float or a double but one is a long, then Java treats both values as longs. Finally if there are no
doubles, floats or longs, then Java treats both values as an int, even if there aren't any ints in
the equation. Therefore the result will be a double, float, long or int depending on the types of the
arguments.
Assigning long values to int variables or double values to float variables can be equally
troublesome. In fact it's so troublesome the compiler won't let you do it unless you tell it you
really mean it with a cast. When it's necessary to force a value into a particular type, use a
cast. To cast a variable or a literal or an expression to a different data type just precede it with
the type in parentheses. For instance:
A cast lets the compiler know that you're serious about the conversion you plan to make.
When a value is cast down before assignment, series of operations takes place to chop the
right hand side down to size. For a conversion between a floating point number and an int or
a long, the fractional part of the floating point number is truncated (rounded toward zero). This
produces an integer. If the integer is small enough to fit in the left hand side, the assignment
is completed. On the other hand if the number is too large, then the integer is set to the
largest possible value of its type. If the floating point number is too small the integer is set to
the smallest possible value of its type.
This can be a nasty bug in your code. It can also be hard to find since everything may work
perfectly 99 times out of a hundred and only on rare occasions will the rounding become a
problem. However when it does there will be no warning or error message. You need to be
very careful when assigning floating point values to integer types.
byte
int
long
float
Like all numeric types floats may be cast into other numeric types ( byte, short, long, int,
double). When lossy casts to integer types are done (e.g. float to short) the fractional part
is truncated and the conversion is done modulo the length of the smaller type.
double
8 bytes IEEE 754. Covers a range from 4.94065645841246544e-324d to
1.79769313486231570e+308d (positive or negative).
char
int i = Integer.valueOf("22").intValue();
Doubles, floats and longs are converted similarly. To convert a String like "22" into the long
value 22 you would write
long l = Long.valueOf("22").longValue();
To convert "22.5" into a float or a double you would write:
double x = Double.valueOf("22.5").doubleValue();
float y = Float.valueOf("22.5").floatValue();
The various valueOf() methods are relatively intelligent and can handle plus and minus signs,
exponents, and most other common number formats. However if you pass one something
completely non-numeric like "pretty in pink," it will throw a NumberFormatException. You haven't
learned how to handle exceptions yet, so try to avoid passing theses methods non-numeric
data.
You can now rewrite the E = mc2 program to accept the mass in kilograms as user input from
the command line. Many of the exercises will be similar.
class Energy {
public static void main (String args[]) {
$ javac Energy.java
$ java Energy 0.0456
4.09853e+15 Joules
Some characters are hard to type. For these Java provides escape sequences. This is a
backslash followed by an alphanumeric code. For instance '\n' is the newline character. '\t' is
the tab character. '\\' is the backslash itself. The following escape sequences are defined:
\b backspace
\t tab
\n linefeed
\f formfeed
\r carriage return
\" double quote, "
\' single quote, '
\\ backslash, \
The double quote escape sequence is used mainly inside strings where it would otherwise
terminate the string. For instance
It isn't necessary to escape the double quote inside single quotes. The following line is legal in
Java