Saturday, 30 May 2015

Java Access/Visibility Modifiers

Access/visibility modifiers control access to a class, interface, data member or method. There are four levels of visibility in Java:


  • public
  • protected
  • package
  • private

1. Access/Visibility Modifiers for Top-Level Classes.

Visibility of a top-level class can be either public or package.

public

The keyword public is the only modifier, which can be used with a top-level class. If a class is to 
be visible to all the classes irrespective of their package, then it must be declared as public by specifying the modifier public, which should appear before the keyword class.

package

There is no keyword package for visibility control. In the absence of any access/visibility modifier before the top-level class, its visibility is only within the package in which it is defined. The concept of package is somewhat similar to the concept of friend classes in C++.

2. Access/Visibility Modifiers for Data Members and Methods.

When used in the variable or method declarations, access/visibility modifiers control access to the variable or method i.e. they decide who can access the variables and methods. These modifiers are not applicable for local variables as their visibility/scope is anyhow limited to the method/block in which they are declared.

public

Any method or variable is always visible in the class in which it is declared. The instance methods of a class can access any other method (instance as well as static method) or variable (instance as well as static variable) declared in the class. Similarly a static method of a class can access any other static method or static variable declared in the same class. 

If a method or variable is to be visible to all the classes, then it must be declared as public by specifying the modifier public, which should appear before the data type. For example, main() method is always declared as public. The reason is that main() method is accessed by the code which is part of JVM i.e. it is outside the class in which main() method is declared. Similarly an instance or static variable can be declared public by specifying modifier public as shown below:

public float width;
public static float width;

A variable or method declared as public has the widest possible visibility. It can be accessed from any class.

private

If you want that a method or variable should not be visible outside the class in which it is declared then its access modifier should be private. We use this modifier to hide the variable or method so that it cannot be accessed from outside the class. 

A variable declared as private has the least possible visibility but it is the most commonly used modifier to encourage data encapsulation and data hiding.  

package 

There is no keyword package. In the absence of any access/visibility modifier before a data member or method, its visibility is only within the package in which it is defined.

protected

A variable declared as protected can be accessed from all the classes belonging to the same package as that of the class in which member is declared. This visibility is similar to the package scope. But in addition to this a protected member can be accessed from any child class irrespective of the package in which it is declared.

Example: A simple class Box is defined below.

1 class Box
2 {
3    double width;
4    double height;
5    double length;
6 }

Example: The class Box is redefined here to include one method volume().

1 class Box
2 {
3    double width;
4    double height;
5    double length;
6    void volume()
7    {
8        double vol = width * height * length;
9        System.out.println(vol);
10  }
11 }

Java defining a class

A Java class represents a user-defined data type. It acts like a template using which we can create multiple objects. The objects are like variables /instances of the data type represented by the class. To begin with you can think of a class as struct of C with the difference that a struct data type can have only data as members whereas the class can have data as well as methods as its members.

The general form of a class is

modifiers class <classname>
{
      <body of the class>
}

The body of the class can consist of data members as well as methods.
The general form is expanded below to show the fact that the class body can contain data members (variables) as well as methods.

modifiers class <classname>
{
modifiers type variable1;
modifiers type variable2;
.

.

modifiers type methodname1(parameter-list)
{
     <body of the method>
}

modifiers type methodname2(parameter-list)
{
     <body of the method>
}

.

.

}

Friday, 29 May 2015

Basic Concepts of OOP (Object-Oriented Programming)

Some of the essential elements of the object-oriented programming are mentioned below:


  • Abstraction
  • Objects and Classes
  • Three OOP Principle
                   Encapsulation
                   Inheritance
                   Polymorphism

  • Persistence
  • Genericity
  • Composition/Aggregation
1. Abstraction

The abstraction is one of the essential elements of any programming language including the procedural languages. The concept of built-in data type is also an abstraction. The feature of defining own data type using struct in C language further extends this abstraction.

The basic purpose of abstraction is to reduce complexity by hiding details. For example, people do not think of car as a set of hundreds of components. They think of it as a well-defined object having some unique properties and behavior.

Abstraction can be defined as an act for identifying the essential properties and behaviors of an object without going into details. The properties and behaviors of an object differentiate it from other objects of similar type and also help in classifying/grouping the objects.

The object-oriented programming languages model abstractions using classes and objects.

2. Objects and Classes

Object

An object is a physical or abstract entity or thing, which can be distinguished from other objects of similar types. An object has three characteristics:

(i) Identification
(ii) Properties (Attributes)
(iii) Behaviors (Methods/Operations/Functions)

The object can also be thought of as an instance of class, where class is like a built-in data type and object is a variable.

Class

A class represents a category of objects with similar properties and behaviors. A class can be thought of as a blueprint for creating objects. An object has the properties and behaviors defined by its class. The class can be thought of as a user-defined data type and object as a variable/instance of the data type represented by the class.

The properties/attributes of an object are defined by data members/fields in Java. A data member/field in a class is a variable that can hold data. The behaviors/operations of an object are defined using methods in Java. Both data members and methods are referred to as members of the class.

A class may also be thought of as a user-defined data type and an object as a variable of that data type. Once a class has been defined we can create any number of objects belonging to that class.

3. Three OOP Principles

3.1 Encapsulation

Encapsulation is the mechanism that binds code and data on which the code acts. Java classes support this as they allow us to define the code and data together. Encapsulation also helps in achieving data hiding by declaring some of the class members as private so that they cannot be accessed from the code that does not belong to the class.

3.2 Inheritance

In object-oriented programming, inheritance refers to the properties of a class being available to other classes called sub-classes or derived-classes. A sub-class or derived class is one that is derived from an existing class. It inherits all the features of the existing class which is also referred as the base-class or super-class. So inheritance can be defined as the process of deriving a class from a super-class or a base-class. Inheriting a class does not introduce any changes in the base-class/super-class. The derived-class/sub-class has a larger set of properties and behaviors as compared to the base-class.

The major advantage of the inheritance is code reusability. If the base class is in use for a long time and there is a need to add some extra attributes and methods, we can do so by deriving another class. The derived class will be able to use code of the base class without debugging as it is in use for a long time

Class Hierarchy

All the classes derived from a common base class belong to a family and form a class hierarchy. The class hierarchy can be compared with a tree structure where one base class is at the root and does not have a super-class. All other classes are either derived from the class at the root of the hierarchy or from some other class, which is derived from the root class directly or indirectly.

More features are added as we go down the tree. The classes that are represented by the leaf nodes do not have any sub-classes. The following examples show some class hierarchies.

Example 1: You can derive classes Saving Account and Current Account from the class Account. Here Account is the Base/Super Class and Saving Account and Current Account are Derived/Sub classes.

Example 2: The following diagram shows the classes derived from the Base class Vehicle.

3.3 Polymorphism

Polymorphism is a feature that allows same interface to be used for a general class of actions.

Most of the object-oriented languages use polymorphism in the following situations:

  • Operator Overloading
  • Method Overloading
  • Method Overriding

Operator Overloading

Most of the languages use this form of polymorphism for the built-in operations. For example, all the arithmetic operators in C/C++ or Java can be used with many types of operands (int, long, float, double etc.). So same addition operator can be used to add two integers as well as to add

two floating-point numbers. 

The C++ allows the user to overload the built-in operators. For example, you can overload the 

arithmetic operators to handle the complex numbers also. Although Java uses operator 

overloading for built-in operators but does not allow the user to overload the operators.

Method Overloading

This feature allows us to write more than one methods with the same name. Both C++ and Java have this feature. The methods (functions in C++) with same name are differentiated based on the parameters. The overloaded methods must either have different number of parameters or the types of the parameters must differ if their number is same.

If the call to an overloaded method can be resolved at compile time i.e. if the compiler can decide which of the overloaded method will be called then this is called static binding, which is an example of compile time polymorphism. 

If the call to an overloaded method cannot be resolved at compile time i.e. if the compiler cannot 
decide which of the overloaded method will be called then this is called dynamic binding, which 
is an example of run-time polymorphism. 

In general Java resolves calls to overloaded methods at run-time but there are many situations 
where the calls to overloaded methods are resolved at compile-time.

Method Overriding

The sub-class can define a method with the same name as in the super-class, and same number and type of parameters. This is called method overriding. 

The compiler can not resolve call to an overridden method. Java normally uses dynamic binding to resolve calls to overridden methods i.e. the decision takes place at run-time.

4. Persistence

Some object-oriented languages allow you to store/retrieve the state of a program to/from a persistent storage media i.e. a permanent storage media like secondary storage. This is called persistence.

Java allows you to store any object on the secondary storage and to retrieve it later on. If you attempt to store an object at the top of an object graph, all of the other referenced objects are recursively located and saved. Similarly when the object is retrieved later on, all of the objects and their references i.e. the entire object graph is correctly created in the main memory.

For example, it is possible to save an entire tree structure by just saving the root of the tree. At a
later stage it is possible to recreate the entire tree structure in the memory by just retrieving the root.
The C++ does not support this feature.

5. Genericity

The concept of defining an algorithm once, independently of any specific type of data, and then 
applying that algorithm to a wide variety of data types without any additional effort is called Genericity. 

C++ supports this feature using templates. Java also supports this feature through Object class, 
which is at the top of any class hierarchy in Java.

For example, using this feature, we can implement a generic data type stack so that it is possible 
to store element of any type in the stack.

This feature increases the degree of reusability to a large extent.

6. Composition/Aggregation

An object might be made up of other objects. Such an object is called Composite or Aggregate 
object. For example, it is appropriate if an object of class vehicle is defined as a composite object 
made up of objects like Engine, Body, Axle, Seats etc.

Inheritance v/s Composition

There are two basic mechanisms for deriving new classes from the existing ones: Inheritance and 
Composition. 

The class Bus can be derived by inheriting properties of class vehicle. Here Bus is a kind of vehicle which has some additional properties / behaviors beside the properties and behaviors which are common for all the vehicles. In other words class Bus has is-a relationship with the class vehicle as we can say that Bus is a vehicle.

The class vehicle itself might be derived from many other classes using composition. For example, an object of class vehicle might be composed of objects belonging to classes like Engine, Gear Box, Seats, Driver’s Seat, Body, Steering Wheel etc. The derived class in this case has whole-part relationship with the classes representing parts of the composite object. We can not say that Vehicle is an Engine or Vehicle is a Gear Box as Vehicle is made up of a number of parts.

Object-Oriented Programming v/s Procedural Programming

All the programs consist of two elements: process and data.  There can be two different approaches depending upon whether our main focus is on processing or data. The procedural programming languages (C, FORTRAN, PASCAL, COBOL etc.) focus on the processing part i.e. they give more importance to “what is happening” in the system and less importance to data.

The object-oriented languages (Java, C++) focus on the data i.e. they give more importance to “who is being affected”. The procedural approach becomes less and less suitable as the programs become large and complex. The object-oriented programming languages were developed to overcome the limitations of the procedural programming languages. The object-oriented programs are relatively far less complex as compared to the similar programs written in procedural languages.

Object-oriented programs are organized around data (i.e. objects) and a set of well-defined
interfaces (public methods) to that data. Java is based on object-oriented paradigm. Java is almost pure object-oriented programming language. We have used the term “almost” as Java also supports Primitive Data Types due to performance reasons. The C++ is not a pure object-oriented language. C++ is an extension to C so it uses an approach, which is a mix of procedure-oriented approach and object-oriented approach.

The basic differences in the two approaches are summarized below:

(i) The object-oriented programs are data centric while the programs written in procedural
languages are process centric.

(ii) The object-oriented programs are organized around data (objects) so they model the real
world objects in a better way.

(iii) The degree of reusability and extensibility of code is very high in case of object-
oriented approach as compared to procedural approach. So code size is less.

(iv) The object-oriented programs are easier to maintain, as they are relatively less complex
and smaller in size.

(v) The object-oriented programs are based on the bottom-up design methodology while
the procedural programs are based on the top-down design methodology.

Java return Statement

The return statement is used to immediately return control from a called method to the calling method.

The syntax of the return statement is as follows:

return;

or

return expression;

The first form of return statement is used to simply transfer control from the called method to the calling method. The second form returns control as well as returns a value to the calling method as specified by the expression following the return statement.

Java continue Statement

The general form of simple continue statement is:

continue;

The unlabeled continue statement can be used inside loops (for, while and do-while) only. It prematurely stops the current iteration of the loop body and proceeds with the next iteration, if possible.

In the case of while and do-while loops, the rest of the body is skipped and the execution continues with the loop condition. In the case of for loop, the rest of the body is skipped and the execution continues with the increment/decrement expression.

This is similar to continue statement in C/C++.

Example: The linear search program is rewritten to make use of the continue statement.

import java.util.*;

class LinearSearch

{ public static void main(String args[]) throws IOException

{ int n, x, a[]; boolean found = false; String number;

Buffered Reader in

= new BufferedReader(new InputStreamReader(System.in));

System.out.print("Enter the number of elements in the array: ");

number = in.readLine(); n = Integer.parseInt(number);

a = new int[n];

for(int i = 0; i < n; i++)// read the array elements

{ number = in.readLine();

a[i] = Integer.parseInt(number);

}

System.out.print("Enter the element to be searched in the array: ");

number = in.readLine(); x = Integer.parseInt(number);

int i = 0;

while(i < n && !found) // search the specified element

{

if(x = =  a[i]) // simple if statement

{

found = true;

continue;

}

i++;

}

if(found) // if-else statement

System.out.println("The number " + x + " is present in the list");

else

System.out.println("The number " + x + " is not in the list");
}
}

labeled continue Statement

The syntax of the labeled continue statement is as follows:

continue  <label>;

The labeled continue statement specifies the label of the enclosing loop to continue. The label need not correspond to the closest enclosing loop.

Example: The matrix search program is rewritten here to make use of the continue statement.

import java.util.*;

class SearchMatrix1

{ public static void main(String args[]) throws IOException

{

int i, j, x, row, col , matrix[][];  String number;  boolean found = false;

Buffered Reader in = new BufferedReader(new InputStreamReader(System.in));

System.out.print("Enter the number of rows in the matrix: ");

number = in.readLine(); row = Integer.parseInt(number);

System.out.print("Enter the number of columns in the matrix: ");

number = in.readLine(); col = Integer.parseInt(number);

matrix = new int[row][col];

for(i = 0; i < row; i++) //enter one element in one line

{

System.out.println("enter the elements of row " + (i+1));

for(j = 0; j < col; j++)

{ number = in.readLine();

}

}

System.out.print("Enter the element to be searched in the matrix: ");

number = in.readLine();

x = Integer.parseInt(number);

outerloop: for(i = 0; i < row && !found; i++)

{ for(j = 0; j < col; j++)

{ if(matrix[i][j] == x)

{ found = true;

continue outerloop;

}

}

}

// break will transfer control to the following statement

if(found)

System.out.println("The number "+ x + " is present in the matrix");

else

System.out.println("The number " + x + " is not in the matrix");

}

}

Java Jump Statements

Jump statements are used for breaking the control flow. Java supports the following jump statements:

  • break
  • labeled break
  • continue
  • labeled continue
  • return
Beside this the constructs used for exception handling can also be put into this category but they are discussed in a separate chapter.

break Statement

The general form of simple break statement is:

break;

The unlabeled break statement can be used inside loops (for, while and do-while) and switch statements. It terminates the containing statement and transfers the control outside the closest enclosing loop or switch statement. The rest of containing statement body is skipped and the execution continues after the containing statement.

This is similar to break statement in C/C++. Refer to examples of simple-if statement and switch statement discussed above for the use of break statement.

labeled break Statement

The syntax of the labeled break statement is as follows:

break  <label>;

The labeled beak statement is used to terminate the block whose label is specified in the break statement. Unlike simple break statement, you can terminate any block. For example, it is possible to terminate the outermost loop from inside a deeply nested for loop.

The break statement can also be used to terminate a simple block (i.e. the block need not be a loop or switch statement)

Example: The following program searches for a given element inside a matrix (2-D array) and makes use of the labeled break statement to come out of the outermost for loop as soon as the element is found.

import java.util.*;

class SearchMatrix

{ public static void main(String args[]) throws IOException

{ int i, j, x, row, col , matrix[][];

String number;

boolean found = false;

Buffered Reader in

= new BufferedReader(new InputStreamReader(System.in));

System.out.print("Enter the number of rows in the matrix: ");

number = in.readLine();

row = Integer.parseInt(number);

System.out.print("Enter the number of columns in the matrix: ");

number = in.readLine();

col = Integer.parseInt(number);

matrix = new int[ row][col];

for(i = 0; i < row; i++) //enter one element in one line

{ System.out.println("enter the elements of row " + (i+1));

for(j = 0; j < col; j++)

{ number = in.readLine();

}

}

System.out.print("Enter the element to be searched : ");

number = in.readLine();

x = Integer.parseInt(number);

outerloop: for(i = 0; i < row; i++)

matrix[i][j]= Integer.parseInt(number);

{

for(j = 0; j < col; j++)

{

if(matrix[i][j] == x)

{ found = true;

}

 break outerloop;
}

}
}
if(found)

System.out.println("The number "+ x + " is present");

else

System.out.println("The number " + x + " is not present");
}
}

The use of labeled break statement in the above program is a substitute of the labeled goto statement of C/C++. This is a better alternative, as the program is more readable hence the labeled break is referred to as the civilized form of goto statement.

Java Iteration Statements (Loop Control Structure)

The Java supports the while, do-while and for iteration/loop control statements. The syntax is similar to C/C++. With JDK1.5, a second form of for was added that implements a “for-each” style loop.

while Statement

The general form of a while statement is:

while(condition)

loop body

Loop body may contain one or more statements. If loop body contains more than one statement then they must be enclosed between braces.

Example: The following program accepts one natural number say n as command line argument and then calculates and displays the sum of first n natural numbers.

class SumNaturalNumbers

{

public static void main(String a[])

{ int n, sum=0;

n = Integer.parseInt(a[0]); //command line argument

int i = 1;

sum = 0;

while (i <= n)

{

sum = sum + i;

i  = i + 1;

}

System.out.println("Sum of first " + n + " natural numbers is " + sum);

}

}

do-while Statement

The general form of a do-while statement is:

do

{

} while (condition)

loop body

Example: The following program accepts one integer number say n as command line argument and then calculates and displays the sum of its digits.

class SumOfDigits

{ public static void main(String a[])

{ int n, m, sum, digit;

n = Integer.parseInt(a[0]); //command line argument

m = n;

if(m < 0)

m = -m;

sum = 0;

do

{ digit = m % 10;

sum = sum + digit;

m = m / 10;

}while (m > 0);

System.out.println("Sum of digits of number " + n + " is: " + sum);

}

}

for Statement

The general form of a for statement is:

for(initialization; condition; increment/decrement)

loop body

Loop body may contain one or more statements. If loop body contains more than one statement then they must be enclosed between braces.

Example: The following program accepts one natural number say n as command line argument

and then calculates and displays the sum of first n natural numbers.

class SumNaturalNumbers1

{ public static void main(String a[])

{ int i, n, sum;

n = Integer.parseInt(a[0]); //command line argument

for(i = 1, sum = 0; i <= n; i++)

{

sum = sum + i;

}

System.out.println("Sum of first " + n + " natural numbers is " + sum);
}
}


Java Selection Statements (Decision Control Structure)

Java supports the following selection statements:

  • simple if Statement
  • if-else Statement
  • nested-if Statement
  • if-else-if Ladder
  • switch Statement

The syntax of these statements is same as in C/C++ so we will be discussing in details only if there is some difference from C/C++.

Simple if Statement

The syntax of the simple if statement is:

if (condition)
Statement;

if-else Statement

The syntax of the if-else statement is

if(condition)
   Statement1;
else
   Statement2;

Example: The following program illustrates the use of simple if statement as well as if-else statement. The program reads elements in an array of type int, followed by the element to be searched in the array using the linear search method. The program then displays the suitable message according to the search result.

import java.util.*;

class LinearSearch

{ public static void main(String args[]) throws IOException

{ int n, x, a[]; boolean found = false;

String number;

Buffered Reader in

System.out.print("Enter the number of elements in the array: ");

number = in.readLine();

n = Integer.parseInt(number);

a = new int[n];

for(int i = 0; i < n; i++) // read the array elements

{ number = in.readLine(); // enter only one element in one line

}

System.out.print("Enter the element to be searched in the array: ");

number = in.readLine();

x = Integer.parseInt(number);

for(int i = 0; i < n; i++) // search the specified element

{

}

if(found) // if-else statement

else

}

}

nested-if Statement

Any type of if statement may appear in the if or else part of another if statement. The rules for nesting are same as in C/C++. The following example illustrates the use of nested-if statement.

Example: The following program finds the largest among three given numbers.

import java.util.*;

class LargestOfThree

{ public static void main(String args[]) throws IOException

{ int a,b,c,max;  String number;

Buffered Reader in

System.out.print("Enter the first number : ");

number = in.readLine(); a = Integer.parseInt(number);

System.out.print("Enter the second number : ");

number = in.readLine(); b = Integer.parseInt(number);

System.out.print("Enter the third number : ");

number = in.readLine(); c = Integer.parseInt(number);

if(a > b)

else

System.out.println("Maximum among "+a+","+b+","+c+" is:"+max);

}

}

if-else-if Ladder

The syntax of the if-else-if ladder statement is as follows:

if(condition)
  Statement;
else if (condition)
  Statement;
else if (condition)
  Statement;
else
  Statement;

Example: The following program demonstrates the use of if-else-if ladder. The program reads

the weekday as an integer and displays corresponding weekday.

import java.util.*;

class DisplayWeekDay

{ public static void main(String args[]) throws IOException

{ int weekDay;

Buffered Reader in = new BufferedReader(new InputStreamReader(System.in));

System.out.print("Enter the day of week (1 to 7) : ");

number = in.readLine(); weekDay = Integer.parseInt(number);

if (weekDay == 1)

System.out.println("Sunday");

else if(weekDay == 2)

System.out.println("Monday");

else if(weekDay == 3)

System.out.println("Tuesday");

else if(weekDay == 4)

System.out.println("Wednesday");

else if(weekDay == 5)

System.out.println("Thursday");

else if(weekDay == 6)

System.out.println("Friday");

else if(weekDay == 7)

System.out.println("Saturday");

else

System.out.println("Valid values are from 1 to 7");

}

}

switch Statement

The switch statement is a multi-way branch statement. Its syntax is as follows:

switch(expression)

{ case label-1: Statement Sequence

case label-2 : Statement Sequence

[break;]

[break;]

case label-n: Statement Sequence

default: Statement Sequence

[break;]

[break;]

}

The syntax is same as in C/C++, with the following differences:

(i) In Java, switch expression can be any integer expression except long i.e. the type of the switch expression can be byte, short, char or int. But the Java’s int is of 4 bytes which is same as size of long in C/C++.

(ii) The case labels are constant expressions as in C/C++ but the values of the case labels must be in the range of the type of the switch expression otherwise the program will not compile. For example, if switch expression is of type byte then the valid values for case labels are from –128 to 127.

Example: The following program demonstrates the use of switch statement. The program reads the weekday as an integer and displays the corresponding weekday in character form.

import java.util.*;

class DisplayWeekDay1

{ public static void main(String args[]) throws IOException

{ int weekDay;

String number;

Buffered Reader in

= new BufferedReader(new InputStreamReader(System.in));

System.out.print("Enter the day of week (1 to 7) : ");

number = in.readLine();

weekDay = Integer.parseInt(number);

switch(weekDay)

{

case 1: System.out.println("Sunday");

case 2: System.out.println("Monday");

case 3: System.out.println("Tuesday");

case 4: System.out.println("Wednesday");

case 5: System.out.println("Thursday");

case 6: System.out.println("Friday");

break;

break;

break;

break;

break;

break;

case 7: System.out.println("Saturday");

break;

default:

System.out.println("Valid values are from 1 to 7");

}
}
}

Java Control Statements

Control statements are used to change the flow of execution. Java’s control statements can be classified into three categories:

  • Selection Statements (Decision Control Structure)
  • Iteration Statements (Loop Control Structure)
  • Jump statements

Most of the statements have same syntax as the corresponding statements in C/C++. However there are some significant differences:

(i) The conditional expressions used in the if, for, while and do statements must be valid boolean expressions i.e. their values should be either true or false. You cannot use 0 (Zero) instead of false or a non-zero value instead of true that is valid in C/C++.

(ii) Java does not have any goto statement although goto is a reserved word in the language. Java provides labeled break and labeled continue statements, which are often referred to as the civilized form of goto as they are supposed to be better substitutes of goto statement.

Thursday, 28 May 2015

Java Type Conversions during Assignments

Types of the left hand side variable and right hand side expression in an assignment may differ from each other as long as they are type-compatible with each other. For example all the primitive types excluding boolean are type-compatible with each other. When value of an expression is assigned to a variable, it should be converted to the type of the variable on the left hand side. The type conversion may take place automatically or we may have to convert the type explicitly using typecast operator.

Type conversions can be classified as:

  • Widening (or Broadening or UpCasting) Type Conversions
  • Narrowing (or DownCasting) Type Conversions
Widening Conversions

Widening conversion takes place when we assign a lower type expression to a higher type. There is no possibility of any data/precision loss in a widening conversion so it takes place implicitly/automatically.

Examples: The following examples will clarify this.

Suppose following variables are declared in a method/block:

int i ; byte b= 3; short s = 16; char c = 65; long l; float f; double d;

The following expressions are valid as widening conversion takes place automatically:

i  = b; l = s; f = b; d = c;

Narrowing Conversions


Narrowing conversion takes place when we assign a higher type expression to a lower type.

There is possibility of data/precision loss in a narrowing conversion. So normally a narrowing conversion does not take place implicitly/automatically. The programmer needs to explicitly typecast the higher type to lower type so that he/she is aware of the possibility of data/precision loss. However, there are some cases where even narrowing conversion takes place automatically.

Simple assignments always need explicit type conversion.

Examples: The following examples will clarify this.

Suppose following variables are declared in a method/block:

int i = 10 ; byte b; short s; char c; long l = 23; float f = 18.1f; double d = 5.77;

The following expressions are not valid, as narrowing conversions need explicit typecast:

b = i; s  = l; b = f; c = d;

To use these expressions you need to do explicit typecasting as follows:

b = (byte) i; s = (short) l; b = (byte) f; c = (char) d;

Java Arithmetic Expressions

Arithmetic expressions are formed by combining numeric types (constants, variables and expressions) using arithmetic operators. The basic concepts are same as in case of C/C++ although there are some differences.

1. Type Conversions in Expressions

Automatic type promotion takes place in arithmetic expressions according to the following rules:

  • An operand of type byte, short or char is always converted to int. This is true even if unary operator is used.  This implies that the type of the result will always be int or some higher type.
  • If the higher type between two operands is long the other is converted to long.
  • If the higher type between two operands is float the other is converted to float.
  • If the higher type between two operands is double the other is converted to double.
  • If both the operands are of same type (after byte, short  or char has been promoted to int) then no conversion takes place.
Examples: The following examples will clarify these rules.

Suppose following variables are declared in a method/block:

int i = 10; byte b= 3; short s = 16; char c = 65; long l = 100;

float f = 10.3f; double d = 4.88;

The following table demonstrates some expressions formed using above variables, their result type and the value calculated using the conversion rules defined above:

2. Integer Expressions

An Integer expression is one where all the operands are of integer type. The result of such an expression will always be integer as in case of C/C++. The fractional part is simply ignored. For example the result of expression 5/3 is 1.

While evaluating an integer expression, the following rules are applied:

1. An operand of type byte, short or char is converted to int before evaluation of the expression. This is true for unary as well as binary operators. So the operands will always be of type int or long.

2. While evaluating expressions the operators are applied according to precedence rules, which are same as in C/C++.

3. If both the operands of an operator are of type int then result will also be of type int.

4. If both the operands of an operator are of type long then result will also be of type long.

5. If one of the operands of an operator is of type int and the other is of type long then the int would be converted to long and the result will also be of type long.

Integer division including modulo (%) operator may result in an ArithmeticException (run time error).

Example: The following example illustrates what happens on division by zero.

class ZeroDivision
{
   public static void main(String args[])

  {
     int i;

     int x = 5;

      i = x / 0;  // x % 0 will also lead to exception.

      int y = i + 3;

      System.out.println(y);

  }

}

On execution of the above program, the following exception (run time error) occurs at statement

i = x/0; and the program terminates:

Exception in thread "main" java.lang.ArithmeticException: / by zero

        at ZeroDivision.main(ZeroDivision.java:5)

The reason is that division by zero is not defined in Java when both the operands are integer. In Java, it is possible to recover from a run time error and continue the execution. This is done by using exception-handling mechanism that will be discussed later.

Overflow in Integer Expressions

Except division no other integer calculations result in any exception although the result might be arithmetically incorrect. On evaluation of an operator (or complex integer expression), the result may be outside the range of the result data type. Such a situation is called overflow.  The actual result is obtained by truncating the extra bits in the result. For example, if the type of the result is
int and the result contains more than 32 bits, then 32 least significant bits in the result are kept and rest are simply truncated to obtain the result. Thus the result will not be correct and in some cases result may be of the wrong sign.

Example:

int tooBig = Integer.MAX_VALUE + 1;

MAX_VALUE is a static final constant defined in the class Integer. Its value represents the maximum positive value that can be stored in a variable of type int, which is, 2147483647. The result of the above expression will be of type int as both the operands are of type int. But the expression would lead to overflow as we are adding one to highest integer value.

In fact, on displaying value of variable tooBig, you will find that it holds the value -2147483648, which is the minimum value that an integer can hold.  The only solution to the overflow problem is to use higher data type i.e. use long type if you expect the result to exceed the limit of the int.

3. Floating-Point Expressions

These are the expressions involving floating-point types. A floating-point expression may also have integer types i.e. a mix of integer and floating-point types. If a floating-point expression has an operator whose both the operands are integer then its result will be calculated as per integer arithmetic rules. For example the expression 3.1 + 5/3 is a floating-point expression but its result will be 4.1 (3.1 + 1) and not 4.76 (3.1 + 1.66) as one might expect because the result of the expression 5/3 would still be int.

While evaluating a floating-point expression, the following rules are applied:

  • An operand of type byte, short or char type is converted to int before evaluation of the expression. This is true for unary as well as binary operators. So the integer operands will always be of type int or long.
  • While evaluating expressions the operators are applied according to precedence rules, whichare same as in C/C++.
  • If operands of an operator are of different types then the lower type operand will be promoted to the type of the higher type operand and the type of the result will be the higher type.
There are three special floating-point values infinity, minus infinity and not a number to represent out-of-range values.

In case of float type these values are represented by constants Float.POSITIVE_INFINITY, Float.NEGATIVE_INFINITY and Float.NaN respectively defined in the class Float.

Similarly in case of double type these values are represented by constants
Double.POSITIVE_INFINITY, Double.NEGATIVE_INFINITY and Double.NaN respectively defined in the class Double.

No exception occurs on division by zero as this is defined in case of floating point expressions.

The result of division by zero is either Infinity or –Infinity. Similarly no error occurs if the floating-point expression involves non-determinant forms like 0/0, 0/, /, /0, complex numbers etc. The result of such an expression is NaN (Not a Number).

Examples: 
The following code segments demonstrate the use of three special values.

(i) double d = 10.0/0;

System.out.println(d);

The output of the above println() statement would be Infinity.

(ii) double d = -10.0/0;

System.out.println(d);

The output of the above println() statement would be Infinity.

(iii) double d = 0.0/0;

System.out.println(d);

The output of the above println() statement would be NaN.

(iv) double d = Math.sqrt(-25);

System.out.println(d);

The output of the above println() statement would be NaN.

Note: The result will be same if we substitute the type double with float.

Overflow in Floating-Point Expressions

If the result of a floating-point expression exceeds the maximum value (magnitude) it is represented by +Infinity or –Infinity depending on the sign of the result.

Examples:

(i) double d = 1.0E+308 * 10;

System.out.println(d);
The output of the above println() statement would be Infinity. The result exceeds the

maximum value (magnitude) and its sign is positive hence it is represented as positive

Infinity.

(ii) double d = -1.0E+308 * 10;

System.out.println(d);

The output of the above println() statement would be Infinity. The result exceeds the maximum value (magnitude) and its sign is negative hence it is represented as negative Infinity.

Note: The result will be same if we substitute the type double with float and the result exceeds the maximum float value.

Underflow in Floating-Point Expressions

If the result of a floating-point expression is less than the minimum value (magnitude), it is represented by 0 (Zero).

Examples:

(i) double d = 3E-324 – 1.0E-324;

System.out.println(d);

The output of the above println() statement would be 0 (Zero). The result is less than the minimum value (magnitude) hence it is treated as 0 (Zero).

(ii) double d =  -3E-324 – 1.5E-324;

System.out.println(d);

The output of the above println() statement would be 0 (Zero). The result is less than the minimum value (magnitude) hence it is treated as 0 (Zero).

Note: The result will be same if we substitute the type double with float and the result is less than the minimum float value.

Java Shift Operators

The Java supports the following bit-wise shift operators:

<< (left shift)

>> (right shift with sign fill)

>>> (right shift with zero fill)

Both the operands must be of integer type. The type promotion rule is applied to each operand before performing the shift operation. The type of the result is same as the promoted type of the left hand operand. This means that type of result will be either int or long.

The shift distance should be in the range 0 to 31 if the promoted type of the left hand operand is int. This means you can shift the bits to left or right by at the most 31 places.

If the shift distance is more than 31 then it will be converted to a value in the range 0 to 31 by obtaining mod with 32. So shifting by 32 is equivalent to shifting by 0 i.e. no shifting al all;

shifting by 33 is equivalent to shifting by 1, and so on.

If the shift distance is negative then actual shift distance is obtained by adding some multiple of 32 to the shift distance such that it falls in the range 0 to 31. For example, if shift distance is –30

then the actual shift distance will be 2 (-30 + 1*32); if the shift distance is –44 then the actual shift distance will be 20 (-44 + 2 * 32).

The shift distance should be in the range 0 to 63 if the promoted type of the left hand operand is long. This means you can shift the bits to left or right by at the most 63 places. If the shift distance is more than 63 then it will be converted to a value in the range 0 to 63 by obtaining mod with 64. So shifting by 64 is equivalent to shifting by 0 i.e. no shifting at all; shifting by 65 is equivalent to shifting by 1, and so on.

If the shift distance is negative then actual shift distance is obtained by adding some multiple of 64 to the shift distance such that it falls in the range 0 to 63. For example, if shift distance is –60

then the actual shift distance will be 4 (-60 + 1*64); if the shift distance is –88 then the actual shift distance will be 40 (-88 + 2 * 64).

Left Shift (<<) Operator

To obtain the result of << operator, the bits in the left hand side operand (which can be any integer expression) are shifted to the left as specified by the right hand operand (which can also be any integer expression) and the empty bit positions to the right are filled with zero.  Left shifting by 1 is equivalent to multiplication by 2. It is possible that sign of the result may differ from the sign of the left hand side operand. This may happen because the sign depends on the
left-most bit, which can change from 0 to 1 or 1 to 0 hence the change in sign.

Example:

y = x << 4

To obtain the value of y, shift the bits in x by 4 positions to the left and fill the 4 right bits with zero.

Right Shift with sign fill (>>) Operator

To obtain the result of >> operator, the bits in the left hand side operand (which can be any integer expression) are shifted to the right as specified by the right hand operand (which can also be any integer expression) and the empty bit positions to the left are filled with sign bit. Right shifting by 1 is equivalent to division 2. This operator never changes the sign of the result i.e. it will be same as the sign of the left hand operand.

Example:

y = x >> 4

To obtain the value of y, shift the bits in x by 4 positions to the right and fill the 4 left bits with sign bit (i.e. with 0 if the leftmost bit before shifting is 0 or 1 if the leftmost bit before shifting is 1).

Right Shift with zero fill (>>>) Operator

To obtain the result of >>> operator, the bits in the left hand side operand (which can be any integer expression) are shifted to the right as specified by the right hand operand (which can also be any integer expression) and the empty bit positions to the left are filled with 0.  Right shifting by 1 is equivalent to division 2. If shifting tales place then result will always be positive, as the rightmost bit would become zero.

Example:

y = x >>> 4

To obtain the value of y, shift the bits in x by 4 positions to the right and fill the 4 left bits with 0.

Java Bit-wise operators

The Java supports the following bit-wise operators:

~ (1’s complement or bit-wise complement)| (bit-wise OR)

& (bit-wise AND)

^ (bit-wise exclusive OR or XOR)

The operands of these operators must be of integer type only. If any of the operand of a bit-wise operator is of type byte, short or char then it is promoted to int before being used. If one operand is of type long then other is also promoted to long. So the type of the result will always be int or long.

Note: The operators |, & and ^ behave like boolean logical operators if both the operands are of boolean type.

Bit-wise Assignment Operators

The Java supports the following Bit-wsie Assignment Operators:

&=, |=, ^=

An assignment operator has the following syntax:

<variable><operator> = <expression>

The above assignment is equivalent to:

<variable> = <variable>  <operator> (<expression>)

For example the assignment:

 i &= i1 is equivalent to i = i & i1

Here i is an integer type variable and i1 is an integer expression.

Java Assignment Operator (=)

The assignment operator has the following syntax:

<variable> = <expression>

Here variable can be of primitive type or reference type. Similarly expression may result in a primitive data value or object reference:

Example: Assignment involving primitives.

x = 10;

Example: Assignment involving reference data type.

int x[];

x = new int [100];

Here new is an operator that returns an object reference.

Multiple Assignments

The assignment operator = may be used like any other operator to form a compound expression.

The operator can appear more than once in an assignment statement as shown below:

Example:

int x = 5, y = 6 , z = 7;

x = y = z; //multiple assignment statement

Here = behaves like an operator. It is a right associative operator, hence after the execution of the assignment statement, the value of variables x, y and z will be 7.

Example:

int  x[], y[];

x = y = new int[20];

Here new operator returns reference to an array, which can hold 20 int values. The reference is first assigned to y and then to x as the = operator is right associative.

Note: Assigning a reference does not create a copy of the object. So both x and y refer to the same array in this example.

Java Ternary Conditional Operator (? :)

The ternary conditional operator has the following syntax:

<condition> ? <expr1> : <expr2>

If condition (boolean expression) is true then <expr1> is evaluated otherwise <expr2> is evaluated.

For example, the following code segment, will store the maximum of x and y into variable max:

max = (x > y) ? x : y;

Here it is assumed that the variables x, y and max are of numeric type. The type of the variable max should be higher or same as the higher type among types of x and y.

Java Conditional Operators (or Short-Circuit Logical Operators)

The Java supports the following conditional operators:

|| (conditional OR)

&& (conditional AND)

The conditional operators && and || can be used to perform logical OR or AND operations on boolean operands. The operators are similar to boolean logical operators. The only difference is that if the result is definitely known after evaluating the first operand then second operand is not evaluated as discussed in the previous section. Hence these operators are also known as short-circuit logical operators. Sometimes this proves to be very useful in avoiding run-time exceptions.

For example, the following piece of code may result in a run-time exception, if the value of x is zero (assuming that x and y are integers), as it will lead to division by zero:

x = 0;

if( x != 0 & y/x > 5)

{

----

----

}

The possibility of the run-time exception can be avoided if we use the short-circuit operator && instead of boolean logical operator & as shown below:

x = 0;

if( x != 0 && y/x > 5)

{

----

----

}

Java Boolean Logical Operators

The Java supports the following boolean logical operators:

! (logical complement)

| (logical OR)

& (logical AND)

^ (logical exclusive OR)

Logical Complement ( ! ) Operator

This is a unary operator and the operand must always be a boolean expression. This acts as the negation operator, which negates a boolean expression as shown in the following table:

Boolean Expression(b) Logical Complement(!b)
true false
false true

Logical OR ( | ) Operator

The logical OR operator is used to combine two boolean expressions to form a compound boolean expression. The value of any boolean expression in Java is either true or false no matter how complex it is. The following table shows the value of boolean expression obtained by combining two boolean expressions using logical OR operator.

Boolean Expression(b1) Logical Complement(b2) Logical Complement(b1 | b2)
false false false
false true true
true false true
true true true

If first boolean expression is true then value of the compound expression will be true irrespective of the value of the second boolean expression. Even then the second boolean expression is always evaluated. This is different from the conditional (short-circuit) OR operator where the second boolean expression is not evaluated if the result of the first boolean expression is true.

If both the operands of the | operator are of integer type then this operator behaves like bit-wise OR operator.

Logical AND ( & ) Operator

The logical AND operator is used to combine two boolean expressions to form a compound boolean expression. The value of any boolean expression in Java is either true or false no matter how complex it is. The following table shows the value of boolean expression obtained by combining two boolean expressions using logical AND operator.

Boolean Expression(b1) Logical Complement(b2) Logical Complement(b1 & b2)
false false false
false true false
true false false
true true true

If first boolean expression is false then value of the compound expression will be false irrespective of the value of the second boolean expression. Even then the second boolean expression is always evaluated. This is different from the conditional (short-circuit) AND operator where the second boolean expression is not evaluated if the result of the first boolean expression is false.

If both the operands of the & operator are of integer type then this operator behaves like bit-wise AND operator.

Logical Exclusive OR or XOR ( ^ ) Operator

The logical exclusive OR operator is used to combine two boolean expressions to form a compound boolean expression. The value of any boolean expression in Java is either true or false no matter how complex it is. The following table shows the value of boolean expression obtained by combining two boolean expressions using logical exclusive operator.

Boolean Expression(b1) Logical Complement(b2) Logical Complement(b1 ^ b2)
false false false
false true true
true false true
true true false

If both the operands of the ^ operator are of integer type then this operator behaves like bit-wise exclusive OR operator.

Boolean Logical Assignment Operators

The Java supports the following Boolean Logical Assignment Operators:

&=, |=, ^=

An assignment operator has the following syntax:

<variable><operator> = <expression>

The above assignment is equivalent to:

<variable> = <variable>  <operator> (<expression>)

For example the assignment:

 b &= b1 is equivalent to b = b & b1

Here b is a boolean variable and b1 is a boolean expression

Java Comparison Operators (Relational Operators)

The Java supports the following comparison operators:

<, <=, >, >=,  = =, != and instanceof operator

These operators can be classified into three categories:
  1. Ordinal Comparisons or Relational Operators
  2. Equality Comparisons or Equality Operators
  3. instanaceof  Operator

Ordinal Comparisons or Relational Operators

Java Supports the following ordinal comparisons/relational operators:

<, <=, >, >=

These operators are used to compare ordinal data types i.e. data types where values have numeric order.

These operators cannot be applied on boolean types and reference types as these types do not have any numeric ordering among the values.

Equality Comparisons or Equality Operators

Equality comparisons test whether two values are same. They can be applied on all Java types including boolean and reference data types.

There are certain restrictions when these operators are used to compare reference data types.

Only references of the objects, whose classes belong to common type hierarchy, can be compared.

instanaceof  Operator


The instanceof operator is used to test the class of an object. The instanceof operator has the

general form:

object   instanceof   type

Here, object is an instance of a class, and type is a class type. If object is an instance of the

specified type or instance of any sub-class of the specified type, then the instanceof operator returns true. Otherwise its result is false.

Java Increment and Decrement Operators

Java supports the increment operator ++ and the decrement operator . 

These operators behave like increment/decrement operators in C/C++.

Java Arithmetic Operators

Java has five arithmetic operators:

  1. + (Addition)
  2. - (Subtraction)
  3.  * (Multiplication)
  4. / (Division) and
  5. % (Modulus)

The operands can be integers, floating-points or both. The arithmetic operators can be applied on

all the primitive types except the boolean. If a binary operator is used to combine two operands

of similar type then the type of result will also be same. But if a binary operator is used to

combine operands of different types then operand of lower type gets converted to the higher type

before the evaluation and the type of the result will be same as that of operand of higher type.

The type conversion rules are discussed in a subsequent section.



The behavior of the +, -, *, and / operator is same as in C/C++. The modulus operator can be

applied to integer as well as floating-point types while in case of C/C++ it can be applied to

integer types only. For example the following is valid in Java:

6.4 % 2.1

The result of the above expression will be 0.1.


Arithmetic Assignment Operators

The Java supports the following Assignment Operators like C/C++:

+=, -=, *=, /=, %=

An assignment operator has the following syntax:

<variable><operator> = <expression>

The above assignment is equivalent to:

<variable> = <variable>  <operator> (<expression>)

For example the assignment:

 x += 5 is equivalent to x = x + 5

For example the assignment:

 x += a * c is equivalent to x = x + (a*c)

Java Operators, Expressions and Assignments

Java provides a rich set of operators. Operators combine constants, variables and sub-expressions

to form expressions. Most of the operators in Java behave like C/C++ but there are few

differences, which are covered here.

Java operators can be classified as:

  1. Arithmetic Operators
  2. Increment and Decrement Operators
  3. Relational Operators (Comparison Operators to be more precise)
  4. Boolean Logical Operators
  5. Conditional Operators (or Short-Circuit Logical Operators)
  6. Ternary Conditional Operator
  7. Assignment Operator
  8. Bitwise Operators
  9. Shift Operators

Monday, 18 May 2015

Java input from keyboard

Example: The following example demonstrates how to read from the keyboard. It reads two numbers from the keyboard and display their sum.

Doing input from keyboard is a bit complex in java. The program makes use of classes in java.io package. The program makes use of import statement to import the classes from the java.io package, which contains most of the classes related to Input/Output. You can compare import statement with the #include directive in C/C++ though the comparison is not exact. For example, to use input/output related functions in C/C++ you must include the compiler directive #include<stdio.h> in your program.

import java.io.*;

public class AddTwoNumbers {
public static void main(String args[]) throws IOException{
DataInputStream dataInputStream = new DataInputStream(System.in);
int n1 = 0, n2 = 0, sum = 0, len;
String number;
System.out.println("Enter first number: ");
number = dataInputStream.readLine();
n1 = Integer.parseInt(number);
System.out.println("Enter second number: ");
number = dataInputStream.readLine();
n2 = Integer.parseInt(number);
sum = n1 + n2;
System.out.println("Sum = "+ sum);
}

}

The first statement in the above program is an import statement, which imports all the classes in the package java.io so that the classes can be used without qualifying.

The program makes use of the class DataInputStream to read from the keyboard. Creating an object of this class by passing System.in as parameter to the constructor creates an input stream connected to keyboard/console. The readLine() instance method of the class DataInputStream can then be used to read one line at a time from the keyboard. The readLine() method returns the line read as a string, so it has to be converted into int before doing addition.

If you input a String containing alphabets, the program will terminate with the following run time exception:

java.lang.NumberFormatException: <<String containing alphabets>>

The above program will compile and run successfully but you will see the following warning message:

Note: AddTwoNumber.java uses or overrides a deprecated API.
Note: Recompile with -deprecation for details

The above message appears due to the use of instance method readLine() of the class DataInputStream. This method has some known bugs and therefore sun has marked this method as deprecated, which means that this method may be discontinued in the future version of Java and its use should be avoided as far as possible. A method is deprecated when It has some known bugs or has side effects, which can cause some problems or may affect the performance.

We can rewrite the above program by avoiding the use of DataInputStream class and using other classes, whose methods are not deprecated. The following example is rewritten for this purpose.

Example: 

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class AddTwoNumbers {
public static void main(String args[]) throws IOException{
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
int n1 = 0, n2 = 0, sum = 0;
String number;
System.out.println("Enter first number: ");
number = bufferedReader.readLine();
n1 = Integer.parseInt(number);
System.out.println("Enter second number: ");
number = bufferedReader.readLine();
n2 = Integer.parseInt(number);
sum = n1 + n2;
System.out.println("Sum = "+ sum);
}
}