Java Notes
Java Notes
Unit I : Hours: 12
Data Types, Variables and Arrays: Primary types – Integers – Floating point types – Characters –
Booleans – A Closer Look at Literals – Variables – Type Conversion and Casting – Automatic
type Promotion in Expressions - One Dimensional Arrays– Multi Dimensional Arrays.
Operators: Arithmetic Operators – Bitwise operators – Relational Operators – Boolean Logical
Operators – Assignment Operator – Conditional Operator – Operator Precedence-Using
parentheses.
Unit V: Hours: 12
Introducing the AWT: AWT Classes – Window fundamentals – working with Frame Windows –working
with Graphics– Working with color – Working with Fonts. Using AWT Controls: Controls Fundamentals
– Labels – Using Buttons –Applying check Boxes – Check Box group – Choice Controls – Using a Text
field – Using a Text Area – Understanding Layout Managers [Flow Layout Only ] – Menu Bars and
Menus.
UNIT I
Introduction to Java
Java’s Magic:
The Bytecode The key that allows Java to solve both the security and the portability problems
just described is that the output of a Java compiler is not executable code. Rather, it is bytecode. Bytecode
is a highly optimized set of instructions designed to be executed by the Java run-time system, which is
called the Java Virtual Machine (JVM). In essence, the original JVM was designed as an interpreter for
bytecode. This may come as a bit of a surprise since many modern languages are designed to be compiled
into executable code because of performance concerns. However, the fact that a Java program is executed
by the JVM helps solve the major problems associated with web-based programs.
Translating a Java program into bytecode makes it much easier to run a program in a wide variety
of environments because only the JVM needs to be implemented for each platform. Once the run-time
package exists for a given system, any Java program can run on it. Remember, although the details of the
JVM will differ from platform to platform, all understand the same Java bytecode. If a Java program were
compiled to native code, then different versions of the same program would have to exist for each type of
CPU connected to the Internet. This is, of course, not a feasible solution. Thus, the execution of bytecode
by the JVM is the easiest way to create truly portable programs.
Features of Java
Simple
Secure
Portable
Object-oriented
Robust
Multithreaded
Architecture-neutral
Interpreted
High performance
Distributed
Dynamic
A First Simple Program Now that the basic object-oriented underpinning of Java has been discussed, let’s
look at some actual Java programs. Let’s start by compiling and running the short sample program shown
here. As you will see, this involves a little more work than you might imagine.
1.1. Datatypes:
Java Is a Strongly Typed Language It is important to state at the outset that Java is a strongly
typed language. Indeed, part of Java’s safety and robustness comes from this fact. Let’s see what this
means. First, every variable has a type, every expression has a type, and every type is strictly defined.
Second, all assignments, whether explicit or via parameter passing in method calls, are checked for type
compatibility. There are no automatic coercions or conversions of conflicting types as in some languages.
The Java compiler checks all expressions and parameters to ensure that the types are compatible. Any
type mismatches are errors that must be corrected before the compiler will finish compiling the class.
Java defines eight primitive types of data: byte, short, int, long, char, float, double, and boolean. The
primitive types are also commonly referred to as simple types, and both terms will be used in this book.
These can be put in four groups:
Integers This group includes byte, short, int, and long, which are for whole-valued signed
numbers.
Floating-point numbers This group includes float and double, which represent numbers with
fractional precision.
Characters This group includes char, which represents symbols in a character set, like letters and
numbers.
Boolean This group includes boolean, which is a special type for representing true/false values.
1.3. Integers
Java defines four integer types: byte, short, int, and long. All of these are signed, positive and
negative values. Java does not support unsigned, positive-only integers. Many other computers languages
support both signed and unsigned integers. However, Java’s designers felt that unsigned integers were
unnecessary. Specifically, they felt that the concept of unsigned was used mostly to specify the behavior
of the high-order bit, which defines the sign of an integer value.
The width of an integer type should not be thought of as the amount of storage it consumes, but
rather as the behavior it defines for variables and expressions of that type. The Java run-time environment
is free to use whatever size it wants, as long as the types behave as you declared them. The width and
ranges of these integer types vary widely, as shown in this table:
Byte
The smallest integer type is byte. This is a signed 8-bit type that has a range from –128 to 127.
Variables of type byte are especially useful when you’re working with a stream of data from a network or
file. They are also useful when you’re working with raw binary data that may not be directly compatible
with Java’s other built-in types.
Byte variables are declared by use of the byte keyword. For example, the following declares two
byte variables called b and c:
byte b, c;
Short
short is a signed 16-bit type. It has a range from –32,768 to 32,767. It is probably the leastused
Java type. Here are some examples of short variable declarations:
short s; short t;
Int
The most commonly used integer type is int. It is a signed 32-bit type that has a range from –
2,147,483,648 to 2,147,483,647. In addition to other uses, variables of type int are commonly employed
to control loops and to index arrays. Although you might think that using a byte or short would be more
efficient than using an int in situations in which the larger range of an int is not needed, this may not be
the case.
The reason is that when byte and short values are used in an expression, they are promoted to int
when the expression is evaluated. (Type promotion is described later in this chapter.) Therefore, int is
often the best choice when an integer is needed.
Long
long is a signed 64-bit type and is useful for those occasions where an int type is not large enough
to hold the desired value. The range of a long is quite large. This makes it useful when big, whole
numbers are needed. For example, here is a program that computes the number of miles that light will
travel in a specified number of days:
// Compute distance light travels using long variables.
class Light {
public static void main(String args[]) {
int lightspeed;
long days;
long seconds;
long distance;
// approximate speed of light in miles per second lightspeed = 186000;
days = 1000; // specify number of days here
seconds = days * 24 * 60 * 60; // convert to seconds
distance = lightspeed * seconds; // compute distance
System.out.print("In " + days);
System.out.print(" days light will travel about ");
System.out.println(distance + " miles.");
}
}
This program generates the following output:
In 1000 days light will travel about 16070400000000 miles.
Float
The type float specifies a single-precision value that uses 32 bits of storage. Single precision is
faster on some processors and takes half as much space as double precision, but will become imprecise
when the values are either very large or very small. Variables of type float are useful when you need a
fractional component, but don’t require a large degree of precision. For example, float can be useful when
representing dollars and cents. Here are some example float variable declarations:
float hightemp, lowtemp;
Double
Double precision, as denoted by the double keyword, uses 64 bits to store a value. Double
precision is actually faster than single precision on some modern processors that have been optimized for
high-speed mathematical calculations. All transcendental math functions, such as sin(), cos(), and sqrt(),
return double values. When you need to maintain accuracy over many iterative calculations, or are
manipulating large-valued numbers, double is the best choice. Here is a short program that uses double
variables to compute the area of a circle:
// Compute the area of a circle. class Area {
public static void main(String args[]) {
double pi, r, a;
r = 10.8; // radius of circle
pi = 3.1416; // pi, approximately
a = pi * r * r; // compute area
System.out.println("Area of circle is " + a);
}
}
1.5. Characters
In Java, the data type used to store characters is char. However, C/C++ programmers beware:
char in Java is not the same as char in C or C++. In C/C++, char is 8 bits wide. This is not the case in
Java. Instead, Java uses Unicode to represent characters. Unicode defines a fully international character
set that can represent all of the characters found in all human languages. It is a unification of dozens of
character sets, such as Latin, Greek, Arabic, Cyrillic, Hebrew, Katakana, Hangul, and many more. At the
time of Java's creation, Unicode required 16 bits. Thus, in Java char is a 16-bit type. The range of a char is
0 to 65,536. There are no negative chars. The standard set of characters known as ASCII still ranges from
0 to 127.
Here is a program that demonstrates char variables:
// Demonstrate char data type. class CharDemo {
public static void main(String args[]) {
char ch1, ch2;
ch1 = 88; // code for X
ch2 = 'Y';
System.out.print("ch1 and ch2: ");
System.out.println(ch1 + " " + ch2);
}
}
1.6. Booleans
Java has a primitive type, called boolean, for logical values. It can have only one of two possible
values, true or false. This is the type returned by all relational operators, as in the case of a<b. boolean is
also the type required by the conditional expressions that govern the control statements such as if and for.
Here is a program that demonstrates the boolean type:
Boolean Literals
Boolean literals are simple. There are only two logical values that a boolean value can have, true and
false. The values of true and false do not convert into any numerical representation. The true literal in
Java does not equal 1, nor does the false literal equal 0. In Java, the Boolean literals can only be assigned
to variables declared as boolean or used in expressions with Boolean operators.
Character Literals
Characters in Java are indices into the Unicode character set. They are 16-bit values that can be converted
into integers and manipulated with the integer operators, such as the addition and subtraction operators. A
literal character is represented inside a pair of single quotes. All of the visible ASCII characters can be
directly entered inside the quotes, such as 'a', 'z', and '@'. For characters that are impossible to enter
directly, there are several escape sequences that allow you to enter the character you need, such as ' \' ' for
the single-quote character itself and ' \n' for the newline character. There is also a mechanism for directly
entering the value of a character in octal or hexadecimal. For octal notation, use the backslash followed
by the three-digit number.
String Literals
String literals in Java are specified like they are in most other languages—by enclosing a sequence of
characters between a pair of double quotes. Examples of string literals are
"Hello World"
"two\nlines"
" \"This is in quotes\""
The escape sequences and octal/hexadecimal notations that were defined for character literals work the
same way inside of string literals. One important thing to note about Java strings is that they must begin
and end on the same line. There is no line-continuation escape sequence as there is in some other
languages.
1.8. Variables
The variable is the basic unit of storage in a Java program. A variable is defined by the Combination of an
identifier, a type, and an optional initializer. In addition, all variables have A scope, which defines their
visibility, and a lifetime. These elements are examined next.
Declaring a Variable
In Java, all variables must be declared before they can be used. The basic form of a variable
Here are several examples of variable declarations of various types. Note that some Include an
initialization.
The identifiers that you choose have nothing intrinsic in their names that indicates their type. Java allows
any properly formed identifier to have any declared type.
Dynamic Initialization
Although the preceding examples have used only constants as initializers, Java allows Variables to be
initialized dynamically, using any expression valid at the time the variable Is declared.
For example, here is a short program that computes the length of the hypotenuse of a Right triangle given
the lengths of its two opposing sides:
Here, three local variables—a, b, and c—are declared. The first two, a and b, are initialized By constants.
If you have previous programming experience, then you already know that it is fairly common To assign
a value of one type to a variable of another type. If the two types are compatible, Then Java will perform
the conversion automatically. For example, it is always possible to assign an int value to a long variable.
However, not all types are compatible, and thus, not All type conversions are implicitly allowed. For
instance, there is no automatic conversion Defined from double to byte. Fortunately, it is still possible to
obtain a conversion between incompatible types. To do so, you must use a cast, which performs an
explicit conversion between incompatible types. Let’s look at both automatic type conversions and
casting.
When one type of data is assigned to another type of variable, an automatic type conversion Will take
place if the following two conditions are met:
When these two conditions are met, a widening conversion takes place. For example, the int type is
always large enough to hold all valid byte values, so no explicit cast statement is required.For widening
conversions, the numeric types, including integer and floating-point types, are compatible with each
other. However, there are no automatic conversions from the numeric types to char or boolean. Also, char
and boolean are not compatible with each other.As mentioned earlier, Java also performs an automatic
type conversion when storing a Literal integer constant into variables of type byte, short, long, or char.
Casting Incompatible
Types although the automatic type conversions are helpful, they will not fulfill all needs. For example,
what if you want to assign an int value to a byte variable? This conversion will not be performed
automatically, because a byte is smaller than an int. This kind of conversion Is sometimes called a
narrowing conversion, since you are explicitly making the value narrower So that it will fit into the target
type. To create a conversion between two incompatible types, you must use a cast. A cast is Simply an
explicit type conversion.
Here, target-type specifies the desired type to convert the specified value to. For example, the following
fragment casts an int to a byte. If the integer’s value is larger than the range of a Byte, it will be reduced
modulo (the remainder of an integer division by the) byte’s range.
Int a;
Byte b;
// …
B = (byte) a;
Example program
// Demonstrate casts.
Class Conversion {
Public static void main(String args[]) {
Byte b;
Int I = 257;
Double d = 323.142;
System.out.println(“\nConversion of int to byte.”);
B = (byte) I;
System.out.println(“I and b “ + I + “ “ + b);
System.out.println(“\nConversion of double to int.”);
I = (int) d;
System.out.println(“d and I “ + d + “ “ + i);
System.out.println(“\nConversion of double to byte.”);
B = (byte) d;
System.out.println(“d and b “ + d + “ “ + b);
}
}
In addition to assignments, there is another place where certain type conversions may Occur: in
expressions. To see why, consider the following. In an expression, the precision Required of an
intermediate value will sometimes exceed the range of either operand. For Example, examine the
following expression:
Byte a = 40;
Byte b = 50;
Byte c = 100;
Int d = a * b / c;
The result of the intermediate term a * b easily exceeds the range of either of its byteOperands. To handle
this kind of problem, Java automatically promotes each byte, short, Or char operand to int when
evaluating an expression. This means that the subexpression A*b is performed using integers—not bytes.
Thus, 2,000, the result of the intermediate Expression, 50 * 40, is legal even though a and b are both
specified as type byte. As useful as the automatic promotions are, they can cause confusing compile-time
Errors. For example, this seemingly correct code causes a problem:
Byte b = 50;
B = b * 2; // Error! Cannot assign an int to a byte!
The code is attempting to store 50 * 2, a perfectly valid byte value, back into a byteVariable. However,
because the operands were automatically promoted to int when the Expression was evaluated, the result
has also been promoted to int. Thus, the result of the Expression is now of type int, which cannot be
assigned to a byte without the use of a cast. This is true even if, as in this particular case, the value being
assigned would still fit in the Target type.In cases where you understand the consequences of overflow,
you should use an explicit Cast, such as
Byte b = 50;
B = (byte)(b * 2);
Java defines several type promotion rules that apply to expressions. They are as follows: First, All byte,
short, and char values are promoted to int, as just described. Then, if one operand is a long, the whole
expression is promoted to long. If one operand is a float, the entire expression is promoted to float. If any
of the operands are double, the result is double.
1.11. Arrays
An array is a group of like-typed variables that are referred to by a common name. Arrays of Any type
can be created and may have one or more dimensions. A specific element in an Array is accessed by its
index. Arrays offer a convenient means of grouping related Information.
One-Dimensional Arrays
A one-dimensional array is, essentially, a list of like-typed variables. To create an array, you first must
create an array variable of the desired type. The general form of a one-dimensional
Array declaration is
Type var-name[ ];
Here, type declares the element type (also called the base type) of the array. The element type Determines
the data type of each element that comprises the array. Thus, the element Type for the array determines
what type of data the array will hold. For example, the Following declares an array named month_days
with the type “array of int”:
Int month_days[];
Although this declaration establishes the fact that month_days is an array variable, no array actually
exists. To link month_days with an actual, physical array of integers, you must allocate one using new
and assign it to month_days. New is a special operator that allocates memory. You will look more closely
at new in a later chapter, but you need to use it now to allocate memory for arrays. The general form of
new as it applies to one-dimensional
Arrays appears as follows:
Here, type specifies the type of data being allocated, size specifies the number of elements in The array,
and array-var is the array variable that is linked to the array. That is, to use new to Allocate an array, you
must specify the type and number of elements to allocate. The elements
In the array allocated by new will automatically be initialized to zero (for numeric types), false(for
boolean), or null (for reference types, which are described in a later chapter). This example allocates a 12-
element array of integers and links them to month_days:
Class AutoArray {
Public static void main(String args[]) {
Int month_days[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31,
30, 31 };
System.out.println(“April has “ + month_days[3] + “ days.”);
}
}
Multidimensional Arrays
In Java, multidimensional arrays are actually arrays of arrays. These, as you might expect, look And act
like regular multidimensional arrays. However, as you will see, there are a couple Of subtle differences.
To declare a multidimensional array variable, specify each additional index using another set of square
brackets. For example, the following declares a two-Dimensional array variable called twoD:
This allocates a 4 by 5 array and assigns it to twoD. Internally, this matrix is implemented as An array of
arrays of int. Conceptually, this array will look like the one shown in Figure 3-1.thee following program
numbers each element in the array from left to right, top to bottom, and then displays these values:
01234
56789
10 11 12 13 14
15 16 17 18 19
// Manually allocate differing size second dimensions.
Class TwoDAgain {
Public static void main(String args[]) {
Int twoD[][] = new int[4][];
twoD[0] = new int[1];
twoD[1] = new int[2];
twoD[2] = new int[3];
twoD[3] = new int[4];
int I, j, k = 0;
for(i=0; i<4; i++)
for(j=0; j<i+1; j++) {
twoD[i][j] = k;
k++;
}
For(i=0; i<4; i++) {
For(j=0; j<i+1; j++)
System.out.print(twoD[i][j] + “ “);
System.out.println();
}
}
}
Type[ ] var-name;
Here, the square brackets follow the type specifier, and not the name of the array variable.
This alternative declaration form offers convenience when declaring several arrays at the same time. For
example,
The alternative declaration form is also useful when specifying an array as a return type for a method.
Both forms are used in this book.
1.12. Operators
Arithmetic Operators
Arithmetic operators are used in mathematical expressions in the same way that they are
Used in algebra. The following table lists the arithmetic operators:
The operands of the arithmetic operators must be of a numeric type. You cannot use Them on boolean
types, but you can use them on char types, since the char type in Java is, Essentially, a subset of int.
Behave as you would expect for all numeric types. The unary minus operator negates its
Single operand. The unary plus operator simply returns the value of its operand. Remember
That when the division operator is applied to an integer type, there will be no fractional
The following simple example program demonstrates the arithmetic operators. It also
When you run this program, you will see the following output:
Integer Arithmetic
A=2
B=6
C=1
D = -1
E=1
Floating Point Arithmetic
Da = 2.0
Db = 6.0
Dc = 1.5
Dd = -0.5
De = 0.5
The modulus operator, %, returns the remainder of a division operation. It can be Applied to floating-
point types as well as integer types. The following example program
Demonstrates the %:
When you run this program, you will get the following output:
X mod 10 = 2
Y mod 10 = 2.25
Java provides special operators that can be used to combine an arithmetic operation with An assignment.
As you probably know, statements like the following are quite common in Programming:
A = a + 4;
A += 4;
// Demonstrate ++.
Class IncDec {
Public static void main(String args[]) {
Int a = 1;
Int b = 2;
Int c;
Int d;
C = ++b;
D = a++;
C++;
System.out.println(“a = “ + a);
System.out.println(“b = “ + b);
System.out.println(“c = “ + c);
System.out.println(“d = “ + d);
}
}
A=2
B=3
C=4
D=1
Java defines several bitwise operators that can be applied to the integer types: long, int, short, Char, and
byte. These operators act upon the individual bits of their operands. They are Summarized in the
following table:
The bitwise logical operators are &, |, ^, and ~. The following table shows the outcome of Each operation.
In the discussion that follows, keep in mind that the bitwise operators are Applied to each individual bit
within each operand.
Also called the bitwise complement, the unary NOT operator, ~, inverts all of the bits of its operand. For
example, the number 42, which has the following bit pattern:
00101010
Becomes
11010101
00101010 42
&00001111 15
00001010 10
The Bitwise OR
The OR operator, |, combines bits such that if either of the bits in the operands is a 1, then The resultant
bit is a 1, as shown here:
00101010 42
| 00001111 15
_________
00101111 47
The XOR operator, ^, combines bits such that if exactly one operand is 1, then the result Is 1. Otherwise,
the result is zero. The following example shows the effect of the ^. This Example also demonstrates a
useful attribute of the XOR operation. Notice how the bit pattern of 42 is inverted wherever the second
operand has a 1 bit. Wherever the second Operand has a 0 bit, the first operand is unchanged. You will
find this property useful when performing some types of bit manipulations.
00101010 42
^ 00001111 15
00100101 37
Relational Operators
The relational operators determine the relationship that one operand has to the other. Specifically, they
determine equality and ordering. The relational operators are shown here:
Boolean Logical Operators
The Boolean logical operators shown here operate only on boolean operands. All of the binary logical
operators combine two boolean values to form a resultant boolean value.
// Demonstrate the boolean logical operators.
Class BoolLogic {
Public static void main(String args[]) {
Boolean a = true;
Boolean b = false;
Boolean c = a | b;
Boolean d = a & b;
Boolean e = a ^ b;
Boolean f = (!a & b) | (a & !b);
Boolean g = !a;
System.out.println(“ a = “ + a);
System.out.println(“ b = “ + b);
System.out.println(“ a|b = “ + c);
System.out.println(“ a&b = “ + d);
System.out.println(“ a^b = “ + e);
System.out.println(“!a&b|a&!b = “ + f);
System.out.println(“ !a = “ + g);
}
}
After running this program, you will see that the same logical rules apply to booleanValues as they did to
bits. As you can see from the following output, the string representation of a Java boolean value is one of
the literal values true or false:
A = true
B = false
A|b = true
A&b = false
A^b = true
!a&b|a&!b = true
!a = false
You have been using the assignment operator since Chapter 2. Now it is time to take a formal look at it.
The assignment operator is the single equal sign, =. The assignment operator works in Java much as it
does in any other computer language. It has this general form:
Var = expression;
Here, the type of var must be compatible with the type of expression.The assignment operator does have
one interesting attribute that you may not be Familiar with: it allows you to create a chain of assignments.
For example, consider this fragment:
Int x, y, z;
X = y = z = 100; // set x, y, and z to 100
This fragment sets the variables x, y, and z to 100 using a single statement. This works Because the = is
an operator that yields the value of the right-hand expression. Thus, the Value of z = 100 is 100, which is
then assigned to y, which in turn is assigned to x. Using a “chain of assignment” is an easy way to set a
group of variables to a common value.
The ? Operator
Java includes a special ternary (three-way) operator that can replace certain types of if-then-Else
statements. This operator is the ?. It can seem somewhat confusing at first, but the ? Can be used very
effectively once mastered. The ? has this general form:
Here, expression1 can be any expression that evaluates to a boolean value. If expression1 is True, then
expression2 is evaluated; otherwise, expression3 is evaluated. The result of the ?Operation is that of the
expression evaluated. Both expression2 and expression3 are required To return the same (or compatible)
type, which can’t be void.
// Demonstrate ?.
class Ternary {
public static void main(String args[]) {
int i, k;
i = 10;
k = i < 0 ? -i : i; // get absolute value of i
System.out.print("Absolute value of ");
System.out.println(i + " is " + k);
i = -10;
k = i < 0 ? -i : i; // get absolute value of i
System.out.print("Absolute value of ");
System.out.println(i + " is " + k);
}
}
The output generated by the program is shown here:
Absolute value of 10 is 10
Absolute value of -10 is 10
Parentheses raise the precedence of the operations that are inside them. This is often necessary to obtain
the result you desire. For example, consider the following expression:
a >> b + 3
This expression first adds 3 to b and then shifts a right by that result. That is, this expression can be
rewritten using redundant parentheses like this:
a >> (b + 3)
However, if you want to first shift a right by b positions and then add 3 to that result, you will need to
parenthesize the expression like this:
(a >> b) + 3.