09 Java Handout
09 Java Handout
09 Java Handout
Discover Java
Lab Manual
Nature of Comments
Change/
Next Review
INDEX
S.No 1 2 3 4 5 6 7
Topic
Page.no
Benefits of JAVA
Your programming language is object oriented, yet it's still dead simple. Your development cycle is much faster because Java technology is interpreted. The compile-link-load-test-crash-debug cycle is obsolete--now you just compile and run. Your applications are portable across multiple platforms. Write your applications once, and you never need to port them--they will run without modification on multiple operating systems and hardware architectures. Your applications are robust because the Java runtime environment manages memory for you.
Your interactive graphical applications have high performance because multiple concurrent threads of activity in your application are supported by the multithreading built into the Java programming language and runtime platform. Your applications are adaptable to changing environments because you can dynamically download code modules from anywhere on the network. Your end users can trust that your applications are secure, even though they're downloading code from all over the Internet; the Java runtime environment has built-in protection against viruses and tampering.
Characteristics of JAVA The Java programming language is a high-level language that can be characterized by all of the following buzzwords: Simple and Object Oriented: Primary characteristics of the Java programming language include a simple language that can be programmed without extensive programmer training while being attuned to current software practices. The fundamental concepts of Java technology are grasped quickly; programmers can be productive from the very beginning. The Java programming language is designed to be object oriented from the ground up. Object technology has finally found its way into the programming mainstream after a gestation period of thirty years. The needs of distributed, client-server based systems coincide with the encapsulated, message-passing paradigms of object-based software. To function within increasingly complex, network-based environments, programming systems must adopt object-oriented concepts. Java technology provides a clean and efficient object-based development platform. Programmers using the Java programming language can access existing libraries of tested objects that provide functionality ranging from basic data types through I/O and network interfaces to graphical user interface toolkits. These libraries can be extended to provide new behavior. Even though C++ was rejected as an implementation language, keeping the Java programming language looking like C++ as far as possible results in it being a familiar language, while removing the unnecessary complexities of C++. Having the Java programming language retain many of the object-oriented features and the "look and feel" of C++ means that programmers can migrate easily to the Java platform and be productive quickly.
Robust and Secure: The Java programming language is designed for creating highly reliable software. It provides extensive compile-time checking, followed by a second level of run-time checking. Language features guide programmers towards reliable programming habits. The memory management model is extremely simple: objects are created with a new operator. There are no explicit programmer-defined pointer data types, no pointer arithmetic, and automatic garbage collection. This simple memory management model eliminates entire classes of programming errors that bedevil C and C++ programmers. You can develop Java code with confidence that the system will find many errors quickly and that major problems won't lay dormant until after your production code has shipped. Java technology is designed to operate in distributed environments, which means that security is of paramount importance. With security features designed into the language and run-time system, Java technology lets you construct applications that can't be invaded from outside. In the network environment, applications written in the Java programming language are secure from intrusion by unauthorized code attempting to get behind the scenes and create viruses or invade file systems.
Architecture Neutral and Portable: Java technology is designed to support applications that will be deployed into heterogeneous network environments. In such environments, applications must be capable of executing on a variety of hardware architectures. Within this variety of hardware platforms, applications must execute atop a variety of operating systems and interoperate with multiple programming language interfaces. To accommodate the diversity of operating environments, the Java Compiler TM product generates bytecodes-an architecture neutral intermediate format designed to transport code efficiently to multiple hardware and software platforms. The interpreted nature of Java technology solves both the binary distribution problem and the version problem; the same Java programming language byte codes will run on any platform. Architecture neutrality is just one part of a truly portable system. Java technology takes portability a stage further by being strict in its definition of the basic language. Java technology puts a stake in the ground and specifies the sizes of its basic data types and the behavior of its arithmetic operators. Your programs are the same on every platform-there are no data type incompatibilities across hardware and software architectures. The architecture-neutral and portable language platform of Java technology is known as the Java virtual machine. It's the specification of an abstract machine for which Java programming language compilers can generate code. Specific implementations of the Java virtual machine for specific hardware and software platforms then provide the concrete realization of the virtual machine. The Java virtual machine is based primarily on the POSIX interface specification--an industry-standard definition of a portable system interface. Implementing the Java virtual machine on new architectures is
Limited Access for Syntel Employees only
a relatively straightforward task as long as the target platform meets basic requirements such as support for multithreading. High Performance: Performance is always a consideration. The Java platform achieves superior performance by adopting a scheme by which the interpreter can run at full speed without needing to check the run-time environment. The automatic garbage collector runs as a low-priority background thread, ensuring a high probability that memory is available when required, leading to better performance. Applications requiring large amounts of compute power can be designed such that compute-intensive sections can be rewritten in native machine code as required and interfaced with the Java platform. In general, users perceive that interactive applications respond quickly even though they're interpreted. Interpreted, Threaded, and Dynamic: The Java interpreter can execute Java bytecodes directly on any machine to which the interpreter and run-time system have been ported. In an interpreted platform such as Java technology-based system, the link phase of a program is simple, incremental, and lightweight. You benefit from much faster development cycles-prototyping, experimentation, and rapid development are the normal case, versus the traditional heavyweight compile, link, and test cycles. Modern network-based applications, such as the HotJava TM Browser for the World Wide Web, typically need to do several things at the same time. A user working with HotJava Browser can run several animations concurrently while downloading an image and scrolling the page. Java technology's multithreading capability provides the means to build applications with many concurrent threads of activity. Multithreading thus results in a high degree of interactivity for the end user. The Java platform supports multithreading at the language level with the addition of sophisticated synchronization primitives: the language library provides the Thread class, and the run-time system provides monitor and condition lock primitives. At the library level, moreover, Java technology's high-level system libraries have been written to be thread safe: the functionality provided by the libraries is available without conflict to multiple concurrent threads of execution. While the Java Compiler is strict in its compile-time static checking, the language and run-time system are dynamic in their linking stages. Classes are linked only as needed. New code modules can be linked in on demand from a variety of sources, even from sources across a network. In the case of the HotJava Browser and similar applications, interactive executable code can be loaded from anywhere, which enables transparent updating of applications. The result is on-line services that constantly evolve; they can remain innovative and fresh, draw more customers, and spur the growth of electronic commerce on the Internet.
Limited Access for Syntel Employees only
The Java Platform--a New Approach to Distributed Computing: Taken individually, the characteristics discussed above can be found in a variety of software development platforms. What's completely new is the manner in which Java technology and its runtime environment have combined them to produce a flexible and powerful programming system. Developing your applications using the Java programming language results in software that is portable across multiple machine architectures, operating systems, and graphical user interfaces, secure, and high performance. With Java technology, your job as a software developer is much easier--you focus your full attention on the end goal of shipping innovative products on time, based on the solid foundation of the Java platform. The better way to develop software is here, now, brought to you by the Java platform. The Java Platform A platform is the hardware or software environment in which a program runs. Some of the most popular platforms like Microsoft Windows, Linux, Solaris OS, and Mac OS. Most platforms can be described as a combination of the operating system and underlying hardware. The Java platform differs from most other platforms in that it's a software-only platform that runs on top of other hardware-based platforms. Java platform has two components The Java Virtual Machine The Java Application Programming Interface (API)
Java Technology Gives Development Tools: The development tools provide everything you'll need for compiling, running, monitoring, debugging, and documenting your application Application Programming Interface (API): The API provides the core functionality of the Java programming language. It offers a wide array of useful classes ready for use in your own applications. It spans everything from basic objects, to networking and security, to XML generation and database access, and more. Deployment Technologies: The JDK software provides standard mechanisms such as the Java Web Start software and Java Plug-In software for deploying your applications to end users. User Interface Toolkits: The Swing and Java 2D toolkits make it possible to create sophisticated Graphical User Interfaces (GUIs). Integration Libraries: Integration libraries such as the JDBCTM API, Java RMI, and Java Remote Method Invocation over Internet Inter-ORB Protocol Technology (Java RMI-IIOP Technology) enable database access and manipulation of remote objects.
JAVA Tools 1) Editor To type your program into, a notepad could be used for this 2) Compiler To convert your high language program into native machine code 3) Linker To combine different program files reference in your main program together. 4) Loader To load the files from your secondary storage device like Hard Disk, Flash Driver, CD into RAM for execution. The loading is automatically done when you execute your code. 5) Execution Actual execution of the code which is handled by your OS & processor. Why is Java both interpreted and compiled language?
Programming languages are classifies as Higher Level Language Ex. C++ , Java Middle Level Languages Ex. C Low Level Language Ex Assembly Finally the lowest level as the Machine Language.
10
A compiler is a program which converts a program from one level of language to another. The java compiler is a converts high level java code into byte code (which is also a type of machine code). An interpreter is a program which converts a program at one level to another programming language at the same level. Why is Java slow? The two main reasons behind the slowness of Java are Dynamic Linking = Unlike C, linking is done at run-time, every time the program is run in Java. Run-time Interpreter = the conversion of byte code into native machine code is done at run-time in Java which furthers slows down the speed Writing First JAVA Program FirstDemo.java
//This program belongs to below package package com.first.java; //java.lang package is imported by default //import Scanner class using import keyword import java.util.Scanner; //Name of the public class and file name must be same //only one public is allowed in a java file public class FirstDemo { //main method should be public and static method //without main method program cannot be executed. public static void main(String[] args) { //Scanner object for getting input value from keyboard Scanner in=new Scanner(System.in); String name; //output statement System.out.println("Enter your Name"); //next() method is getting input value from user. name=in.next(); System.out.println("Your name is "+name); }
11
12
13
Convert Class into Jar file Common JAR file operations Operation To create a JAR file To view the contents of a JAR file To extract the contents of a JAR file To extract specific files from a JAR file Command jar cf jar-file input-file(s) jar tf jar-file jar xf jar-file jar xf jar-file archivedfile(s)
To run an application packaged as a JAR file (requires the java -jar app.jar Main-class manifest header) Creating Jar file Command C:\paranthaman\src\classes>jar cvf0 app.jar com added manifest adding: com/(in = 0) (out= 0)(stored 0%) adding: com/first/(in = 0) (out= 0)(stored 0%) adding: com/first/java/(in = 0) (out= 0)(stored 0%) adding: com/first/java/FirstDemo.class(in = 775) (out= 775)(stored 0%) Creating Jar File and Setting an Applications Entry Point C:\paranthaman\src\classes>jar cfe app1.jar com/first/java/FirstDemo com
View the jar file content C:\paranthaman\src\classes>jar tf app1.jar META-INF/ META-INF/MANIFEST.MF com/ com/first/ com/first/java/ com/first/java/FirstDemo.class
14
View the Jar file Content C:\paranthaman\src\classes>jar tf app.jar META-INF/ META-INF/MANIFEST.MF com/ com/first/ com/first/java/ com/first/java/FirstDemo.class Extract the Jar file Content C:\paranthaman\src\classes>jar xf app.jar Extract the Jar file Content C:\paranthaman\src\classes>jar xf app1.jar Run the Jar File C:\paranthaman\src\classes>java -jar app1.jar Enter your Name 1000 Your name is 1000
15
Run the Jar File C:\paranthaman\src\classes>java -jar app.jar Failed to load Main-Class manifest attribute from app.jar
16
Java OOPS
What is OOPS? OOP is a design philosophy. It stands for Object Oriented Programming. Everything in OOP is grouped as self sustainable "objects". Hence, you gain re-usability by means of four main object-oriented programming concepts. The main achievement of OOPS are grouping related programming members together, decide where that members can be accessed, reusing that program and using same name for two or more members. Discussion about house House is a single object when user sees it. House is collection of object when architect, Constructor, builder see it. Each Object has its own attributes and behaviors.
Characteristic of an Object 1) State value of an Object 2) Behavior what It is doing 3) Identity how to identify an object from the collection similar Object. Door is an Object. State of the Door is color, material, length, width and isopened or isclosed. Behaviors of the Door are open, close, lock. Identity is door number.
What is Class? Classes define the attribute and behavior of an Object. Class is a blueprint or template of Object.
17
public class Door { String color,material; int length,width; boolean isClosed,isLocked; void store(String color,String material,int length,int width,boolean isClosed){ this.color=color; this.material=material; this.length=length; this.width=width; this.isClosed=isClosed; } void display(){ System.out.println("Door Color is "+color); System.out.println("Door Material is "+material); System.out.println("Door Length is "+length); System.out.println("Door Width is "+width); System.out.println("is Door Closed"+isClosed); } void lock(){ this.isLocked=true; } void close(){ this.isClosed=true; } void unLock(){ this.isLocked=false; } What is Object? void opne(){ this.isClosed=false; Let us now look } deep into what are objects. If we consider the real-world we can find many objects around us, Cars, Dogs, Humans etc. All these objects have a state and } behavior. If we consider a dog then its state is - name, breed, color, and the behavior is barking, wagging, running. If you compare the software object with a real world object, they have very similar characteristics. Software objects also have a state and behavior. A software object's state is stored in fields and behavior is shown via methods. So in software development methods operate on the internal state of an object and the object-to-object communication is done via methods. Object is an instance of class or real time entity. When program create object it is allocating the memory for instance variable of that class.There are three steps when creating an object from a class:
Limited Access for Syntel Employees only
18
Declaration . A variable declaration with a variable name with an object type. Instantiation . The 'new' key word is used to create the object. Initialization . The 'new' keyword is followed by a call to a constructor. This call initializes the new object.
class MainClass{ public static void main(String[] args) { Door d1=new Door(); Door d2=new Door(); d1.store("gray","wood",7,3,true); d2.store("yellow","piper",6,3,true); d1.display(); d2.display(); d1.close(); d1.lock(); d1.display(); d2.display(); } }
D1 D2
19
OOPS Concept:
E n c a p s u l a t i o n
public class Box{ int length; float width , height; public void boxValue (int l,float w,float h){ length=l; width=w; height=h; } void boxValue(int v){ width=height=length=v; } }
Member variables
Member Methods
20
Abstraction Extracting the necessary members to other object and hiding unnecessary members from other objects. Taking decision that where that class members can be accessed. Java gives four access modifiers to control the accessibility of the class members. They are: 1) public 2) private 3) protected 4) Default Inheritance One class can inherit the members from another class it is called an Inheritance. Type of Inheritance: 1) Single inheritance 2) Multiple inheritance 3) Multilevel inheritance 4) Hybrid inheritance In java classes can be derived from classes. Basically if you need to create a new class and here is already a class that has some of the code you require, then it is possible to derive your new class from the already existing code. This concept allows you to reuse the fields and methods of the existing class without having to rewrite the code in a new class. In this scenario the existing class is called the super class and the derived class is called the subclass.
21
//Super class or Base class or Parent class class Box{ protected int length; protected float width , height; public void boxValue(int l,float w,float h){ length=l; width=w; height=h; } public void boxValue(int v){ width=height=length=v; } } //Sub class or Derived class or Child class class NewBox extends Box{ public float findVolume(){ float volume; volume=length*width*height; return volume; } }
22
Polymorphism: Static Polymorphism: It is implemented by function overloading. Two or more methods have same name in single class. But arguments must be different. Dynamic Polymorphism: It is implemented by function overriding. Redefine the super class methods in the subclasses. class SavingAccount{ private int accNo; protected double balance; private static double minimumBalance; public SavingAccount(){ this(-1,0.0); } public SavingAccount(int accNo,double balance){ this.accNo=accNo; this.balance=balance; } double withdraw(double amount){ if(balance-amount>=minimumBalance){ balance-=amount; } return balance; } double deposit(double amount){ double balance=this.balance+amount; this.balance=balance; return balance; } public double checkBalance(){ return balance; } }
23
class CurrentAccount extends SavingAccount{ private double loanLimit; private static double minimumBalance; public double getLoanAmount(){ return loanLimit; } double withdraw(double amount){ if(balance-amount>=minimumBalance){ balance-=amount; } return balance; } } class Test{ public static void main(String[] args) { SavingAccount acc=null; acc=new SavingAccount(); acc.withdraw(1000.00); System.out.println(SavingAccount Balance + acc.checkBalance()); acc=new CurrentAccount(); acc.withdraw(1000.00); System.out.println(CurrentAccount Balance is+ acc.checkBalance()); } }
24
Java Basics: Java Keywords There are totally 50 keywords in java. Keywords are reserved words.
abstract byte class do extends for import long private short switch throws volatile
assert case const double final goto instanceof native protected static synchronized transient while
boolean catch continue else finally if int new public strictfp this try
break char default enum float implements interface package return super throw void
25
Java Data Types There are two data types available in Java:
1) 2)
Primitive Data Types: There are eight primitive data types supported by Java. Primitive data types are predefined by the language and named by a key word. Let us now look into detail about the eight primitive data types. byte:
Byte data type is a 8-bit signed two's complement integer. Minimum value is -128 (-2^7) Maximum value is 127 (inclusive)(2^7 -1) Default value is 0 Byte data type is used to save space in large arrays, mainly in place of integers, since a byte is four times smaller than an int. Example : byte a = 100 , byte b = -50
short:
Short data type is a 16-bit signed two's complement integer. Minimum value is -32,768 (-2^15) Maximum value is 32,767(inclusive) (2^15 -1) Short data type can also be used to save memory as byte data type. A short is 2 times smaller than an int Default value is 0. Example : short s= 10000 , short r = -20000
26
int:
Int data type is a 32-bit signed two's complement integer. Minimum value is - 2,147,483,648.(-2^31) Maximum value is 2,147,483,647(inclusive).(2^31 -1) Int is generally used as the default data type for integral values unless there is a concern about memory. The default value is 0. Example : int a = 100000, int b = -200000
long:
Long data type is a 64-bit signed two's complement integer. Minimum value is -9,223,372,036,854,775,808.(-2^63) Maximum value is 9,223,372,036,854,775,807 (inclusive). (2^63 -1) This type is used when a wider range than int is needed. Default value is 0L. Example : long a = 100000L, int b = -200000L
float:
Float data type is a single-precision 32-bit IEEE 754 floating point. Float is mainly used to save memory in large arrays of floating point numbers. Default value is 0.0f. Float data type is never used for precise values such as currency. Example : float f1 = 234.5f
27
double:
double data type is a double-precision 64-bit IEEE 754 floating point. This data type is generally used as the default data type for decimal values. generally the default choice. Double data type should never be used for precise values such as currency. Default value is 0.0d. Example : double d1 = 123.4
boolean:
boolean data type represents one bit of information. There are only two possible values : true and false. This data type is used for simple flags that track true/false conditions. Default value is false. Example : boolean one = true
char:
char data type is a single 16-bit Unicode character. Minimum value is '\u0000' (or 0). Maximum value is '\uffff' (or 65,535 inclusive). Char data type is used to store any character. Example . char letterA ='A'
28
Reference variables are created using defined constructors of the classes. They are used to access objects. These variables are declared to be of a specific type that cannot be changed. For example, Employee, Puppy etc. Class objects, and various type of array variables come under reference data type. Default value of any reference variable is null. A reference variable can be used to refer to any object of the declared type or any compatible type.
Java Identifiers: All java components require names. Names used for classes, variables and methods are called identifiers. In java there are several points to remember about identifiers. They are as follows:
All identifiers should begin with a letter (A to Z or a to z ), currency character ($) or an underscore (_). After the first character identifiers can have any combination of characters. A key word cannot be used as an identifier. Most importantly identifiers are case sensitive. Examples of legal identifiers:age, $salary, _value, __1_value Examples of illegal identifiers : 123abc, -salary
Class Names - For all class names the first letter should be in Upper Case. If several words are used to form a name of the class each inner words first letter should be in Upper Case. Example class MyFirstJavaClass
Method Names and Variable Names- All method names should start with a Lower Case letter. If several words are used to form the name of the method, then each inner word's first letter should be in Upper Case.
29
Final Variable Names- Final variable names should be in Upper Case letter. Program File Name - Name of the program file should exactly match the public class name.
Local Variables Class Variables (Static Variables) Instance Variables (Non static variables)
Local variables :
Local variables are declared in methods, constructors, or blocks. Local variables are created when the method, constructor or block is entered and the variable will be destroyed once it exits the method, constructor or block. Access modifiers cannot be used for local variables. Local variables are visible only within the declared method, constructor or block. Local variables are implemented at stack level internally. There is no default value for local variables so local variables should be declared and an initial value should be assigned before the first use.
Instance variables:
Instance variables are declared in a class, but outside a method, constructor or any block. When a space is allocated for an object in the heap a slot for each instance variable value is created. Instance variables are created when an object is created with the use of the key word 'new' and destroyed when the object is destroyed. Instance variables hold values that must be referenced by more than one method, constructor or block, or essential parts of an objects state that must be present throughout the class. Instance variables can be declared in class level before or after use. 30
Access modifiers can be given for instance variables. The instance variables are visible for all methods, constructors and block in the class. Normally it is recommended to make these variables private (access level).However visibility for subclasses can be given for these variables with the use of access modifiers. Instance variables have default values. For numbers the default value is 0, for Booleans it is false and for object references it is null. Values can be assigned during the declaration or within the constructor. Instance variables can be accessed directly by calling the variable name inside the class. However within static methods and different class (when instance variables are given accessibility) the should be called using the fully qualified name. ObjectReference.VariableName.
Class/static variables :
Class variables also known as static variables are declared with the static keyword in a class, but outside a method, constructor or a block. There would only be one copy of each class variable per class, regardless of how many objects are created from it. Static variables are rarely used other than being declared as constants. Constants are variables that are declared as public/private, final and static. Constant variables never change from their initial value. Static variables are stored in static memory. It is rare to use static variables other than declared final and used as either public or private constants. Static variables are created when the program starts and destroyed when the program stops. Visibility is similar to instance variables. However, most static variables are declared public since they must be available for users of the class. Default values are same as instance variables. For numbers the default value is 0, for Booleans it is false and for object references it is null. Values can be assigned during the declaration or within the constructor. Additionally values can be assigned in special static initializer blocks. Static variables can be accessed by calling with the class name . ClassName.VariableName.
31
When declaring class variables as public static final, then variables names (constants) are all in upper case. If the static variables are not public and final the naming syntax is the same as instance and local variables.
Discuss the life time of the variable types. public class Account { private double balance; private int accNo; private static double minimumBalance; public double deposit(double amount){ balance+=amount; return balance; } public double withdraw(double amount){ double newbalance=balance-amount; if(newbalance>=minimumBalance){ balance=newbalance; } return balance; } public double checkBalance(){ return balance; } public static double getMinimumBalance(){ return minimumBalance; } public static void setMinimumBalance(double minimumBalance){ Account.minimumBalance=minimumBalance; } } The JVM divided the memory into following sections. 1. 2. 3. 4. Heap Stack Code Static
32
This division of memory is required for its effective management. The code section contains your bytecode. The Stack section of memory contains methods, local variables and reference variables. The Heap section contains Objects (may also contain reference variables). The Static section contains Static data/methods. Comments in JavaMulti Line Comments /* This is my first java program. * This will print 'Hello World' as the output * This is an example of multi-line comments. */
Using Blank Lines: A line containing only whitespace, possibly with a comment, is known as a blank line, and Java totally ignores it. Java Literals: A literal is a source code representation of a fixed value. They are represented directly in the code without any computation. Literals can be assigned to any primitive type variable. For example: byte a = 68; char a = 'A'
33
byte, int, long, and short can be expressed in decimal(base 10),hexadecimal(base 16) or octal(base 8) number systems as well.
Prefix 0 is used to indicate octal and prefix 0x indicates hexadecimal when using these number systems for literals. For example:
int decimal = 100; int octal = 0144; int hexa = 0x64; 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\"" String and char types of literals can contain any Unicode characters. For example: char a = '\u0001'; String a = "\u0001"; Java language supports few special escape sequences for String and char literals as well. They are:
Notation \n \r \f
34
Backspace (0x08) Space (0x20) tab Double quote Single quote backslash Octal character (ddd) Hexadecimal UNICODE character (xxxx)
Java Operators Java provides a rich set of operators to manipulate variables. We can divide all the Java operators into the following groups:
Arithmetic Operators Relational Operators Bitwise Operators Logical Operators Assignment Operators Misc Operators
The 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: Assume integer variable A holds 10 and variable B holds 20 then:
35
Subtraction - Subtracts right hand operand from left hand A - B will give operand 10 Multiplication - Multiplies values on either side of the A * B will give operator 200 Division - Divides left hand operand by right hand operand B / A will give 2
* / % ++ --
Modulus - Divides left hand operand by right hand operand B % A will give and returns remainder 0 Increment - Increase the value of operand by 1 Decrement - Decrease the value of operand by 1 B++ gives 21 B-- gives 19
36
The Relational Operators: There are following relational operators supported by Java language Assume variable A holds 10 and variable B holds 20 then: Operator Description == Example
Checks if the value of two operands are equal or not, if yes (A == B) is not then condition becomes true. true. Checks if the value of two operands are equal or not, if (A != B) is true. values are not equal then condition becomes true. Checks if the value of left operand is greater than the value (A > B) is not of right operand, if yes then condition becomes true. true. Checks if the value of left operand is less than the value of (A < B) is true. right operand, if yes then condition becomes true. Checks if the value of left operand is greater than or equal (A >= B) is not to the value of right operand, if yes then condition becomes true. true. Checks if the value of left operand is less than or equal to the value of right operand, if yes then condition becomes (A <= B) is true. true.
!=
>
<
>=
<=
37
The Bitwise Operators: Java defines several bitwise operators which can be applied to the integer types, long, int, short, char, and byte. Bitwise operator works on bits and performs bit by bit operation. Assume if a = 60; and b = 13; Now in binary format they will be as follows: a = 0011 1100 b = 0000 1101 ----------------a&b = 0000 1100 a|b = 0011 1101 a^b = 0011 0001 ~a = 1100 0011 The following table lists the bitwise operators: Assume integer variable A holds 60 and variable B holds 13 then:
Operator Description
Example
&
(A & B) will Binary AND Operator copies a bit to the result if it exists in give 12 which is both operands. 0000 1100 (A | B) will give Binary OR Operator copies a bit if it exists in eather 61 which is operand. 0011 1101 (A ^ B) will Binary XOR Operator copies the bit if it is set in one give 49 which is operand but not both. 0011 0001 (~A ) will give Binary Ones Complement Operator is unary and has the 60 which is efect of 'flipping' bits. 1100 0011 Binary Left Shift Operator. The left operands value is A << 2 will give moved left by the number of bits specified by the right 240 which is operand. 1111 0000 Binary Right Shift Operator. The left operands value is A >> 2 will give moved right by the number of bits specified by the right 15 which is
<<
>>
38
operand.
1111
>>>
Shift right zero fill operator. The left operands value is A >>>2 will moved right by the number of bits specified by the right give 15 which is operand and shifted values are filled up with zeros. 0000 1111
39
The Logical Operators: The following table lists the logical operators: Assume boolean variables A holds true and variable B holds false then: Operator Description && Example
Called Logical AND operator. If both the operands are non (A && B) is zero then then condition becomes true. false. Called Logical OR Operator. If any of the two operands are (A || B) is true. non zero then then condition becomes true. Called Logical NOT Operator. Use to reverses the logical !(A && B) is state of its operand. If a condition is true then Logical NOT true. operator will make false.
||
40
Assignment Operators: There are following assignment operators supported by Java language:
Operator Description
Example
C = A + B Simple assignment operator, Assigns values from will assigne value of A + right side operands to left side operand B into C Add AND assignment operator, It adds right C += A is operand to the left operand and assign the result to equivalent to left operand C=C+A Subtract AND assignment operator, It subtracts C -= A is right operand from the left operand and assign the equivalent to result to left operand C=C-A Multiply AND assignment operator, It multiplies C *= A is right operand with the left operand and assign the equivalent to result to left operand C=C*A Divide AND assignment operator, It divides left C /= A is operand with the right operand and assign the result equivalent to to left operand C=C/A Modulus AND assignment operator, It takes C %= A is modulus using two operands and assign the result equivalent to to left operand C=C%A C <<= 2 is same as C = C << 2 C >>= 2 is same as C = C >> 2
+=
-=
*=
/=
%=
<<=
>>=
41
&=
^=
42
Misc Operators There are few other operators supported by Java Language. Conditional Operator ( ? : ): int a , b; a = 10; b = (a == 1) ? 20: 30; System.out.println( "Value of b is : " + b );
b = (a == 10) ? 20: 30; System.out.println( "Value of b is : " + b ); This would produce following result: Value of b is : 30 Value of b is : 20
43
Precedence of Java Operators: Category Postfix Unary Multiplicative Additive Shift Relational Equality Bitwise AND Bitwise XOR Bitwise OR Logical AND Logical OR Conditional Assignment Comma Operator () [] . (dot operator) ++ - - ! ~ */% +>> >>> << > >= < <= == != & ^ | && || ?: = += -= *= /= %= >>= <<= &= ^= |= , Associativity Left to right Right to left Left to right Left to right Left to right Left to right Left to right Left to right Left to right Left to right Left to right Left to right Right to left Right to left Left to right
44
There are two types of decision making statements in Java. They are:
The if Statement: An if statement consists of a Boolean expression followed by one or more statements. Syntax: The syntax of an if statement is: if(Boolean_expression) { //Statements will execute if the Boolean expression is true } If the boolean expression evaluates to true then the block of code inside the if statement will be executed. If not the first set of code after the end of the if statement(after the closing curly brace) will be executed. Example: public class Test { public static void main(String args[]){ int x = 10;
if( x < 20 ){ System.out.print("This is if statement"); } } } This would produce following result: This is if statement
45
The if...else Statement: An if statement can be followed by an optional else statement, which executes when the Boolean expression is false. Syntax: The syntax of a if...else is: if(Boolean_expression){ //Executes when the Boolean expression is true }else{ //Executes when the Boolean expression is false } Example: public class Test { public static void main(String args[]){ int x = 30;
if( x < 20 ){ System.out.print("This is if statement"); }else{ System.out.print("This is else statement"); } } } This would produce following result: This is else statement The if...else if...else Statement: An if statement can be followed by an optional else if...else statement, which is very usefull to test various conditions using single if...else if statement. When using if , else if , else statements there are few points to keep in mind.
An if can have zero or one else's and it must come after any else if's. An if can have zero to many else if's and they must come before the else. Once an else if succeeds, none of he remaining else if's or else's will be tested.
46
Syntax: The syntax of a if...else is: if(Boolean_expression 1){ //Executes when the Boolean expression 1 is true }else if(Boolean_expression 2){ //Executes when the Boolean expression 2 is true }else if(Boolean_expression 3){ //Executes when the Boolean expression 3 is true }else { //Executes when the none of the above condition is true. }
47
if( x == 10 ){ System.out.print("Value of X is 10"); }else if( x == 20 ){ System.out.print("Value of X is 20"); }else if( x == 30 ){ System.out.print("Value of X is 30"); }else{ System.out.print("This is else statement"); } } } This would produce following result: Value of X is 30
48
Nested if...else Statement: It is always legal to nest if-else statements, which means you can use one if or else if statement inside another if or else if statement. Syntax: The syntax for a nested if...else is as follows: if(Boolean_expression 1){ //Executes when the Boolean expression 1 is true if(Boolean_expression 2){ //Executes when the Boolean expression 2 is true } } You can nest else if...else in the similar way as we have nested if statement.
if( x == 30 ){ if( y == 10 ){ System.out.print("X = 30 and Y = 10"); } } } This would produce following result: X = 30 and Y = 10
49
The switch Statement: A switch statement allows a variable to be tested for equality against a list of values. Each value is called a case, and the variable being switched on is checked for each case. Syntax: The syntax of enhanced for loop is: switch(expression){ case value : //Statements break; //optional case value : //Statements break; //optional //You can have any number of case statements. default : //Optional //Statements } The following rules apply to a switch statement:
The variable used in a switch statement can only be a byte, short, int, or char. You can have any number of case statements within a switch. Each case is followed by the value to be compared to and a colon. The value for a case must be the same data type as the variable in the switch, and it must be a constant or a literal. When the variable being switched on is equal to a case, the statements following that case will execute until a break statement is reached. When a break statement is reached, the switch terminates, and the flow of control jumps to the next line following the switch statement. Not every case needs to contain a break. If no break appears, the flow of control will fall through to subsequent cases until a break is reached. A switch statement can have an optional default case, which must appear at the end of the switch. The default case can be used for performing a task when none of the cases is true. No break is needed in the default case.
50
switch(grade) { case 'A' : System.out.println("Excellent!"); break; case 'B' : case 'C' : System.out.println("Well done"); break; case 'D' : System.out.println("You passed"); case 'F' : System.out.println("Better try again"); break; default : System.out.println("Invalid grade"); } System.out.println("Your grade is " + grade); } } Compile and run above program using various command line arguments. This would produce following result: $ java Test a Invalid grade Your grade is a a
Limited Access for Syntel Employees only
51
$ java Test A Excellent! Your grade is a A $ java Test C Well done Your grade is a C $
The break Keyword: The break keyword is used to stop the entire loop. The break keyword must be used inside any loop or a switch statement. The break keyword will stop the execution of the innermost loop and start executing the next line of code after the block. Syntax: The syntax of a break is a single statement inside any loop: break;
public static void main(String args[]) { int [] numbers = {10, 20, 30, 40, 50};
52
The continue Keyword: The continue keyword can be used in any of the loop control structures. It causes the loop to immediately jump to the next iteration of the loop.
In a for loop, the continue keyword causes flow of control to immediately jump to the update statement. In a while loop or do/while loop, flow of control immediately jumps to the Boolean expression.
Syntax: The syntax of a continue is a single statement inside any loop: continue; Example: public class Test {
public static void main(String args[]) { int [] numbers = {10, 20, 30, 40, 50};
53
} } } This would produce following result: 10 20 40 50 Loop Statements There may be a sitution when we need to execute a block of code several number of times, and is often referred to as a loop. Java has very flexible three looping mechanisms. You can use one of the following three loops:
As of java 5 the enhanced for loop was introduced. This is mainly used for Arrays. The while Loop: A while loop is a control structure that allows you to repeat a task a certain number of times. Syntax: The syntax of a while loop is: while(Boolean_expression) { //Statements } When executing, if the boolean_expression result is true then the actions inside the loop will be executed. This will continue as long as the expression result is true. Here key point of the while loop is that the loop might not ever run. When the expression is tested and the result is false, the loop body will be skipped and the first statement after the while loop will be executed.
Limited Access for Syntel Employees only
54
while( x < 20 ) { System.out.print("value of x : " + x ); x++; System.out.print("\n"); } } } This would produce following result: value of x : 10 value of x : 11 value of x : 12 value of x : 13 value of x : 14 value of x : 15 value of x : 16 value of x : 17 value of x : 18 value of x : 19
55
The do...while Loop: A do...while loop is similar to a while loop, except that a do...while loop is guaranteed to execute at least one time. Syntax: The syntax of a do...while loop is: do { //Statements }while(Boolean_expression); Notice that the Boolean expression appears at the end of the loop, so the statements in the loop execute once before the Boolean is tested. If the Boolean expression is true, the flow of control jumps back up to do, and the statements in the loop execute again. This process repeats until the Boolean expression is false. Example: public class Test {
do{ System.out.print("value of x : " + x ); x++; System.out.print("\n"); }while( x < 20 ); } } This would produce following result: value of x : 10 value of x : 11 value of x : 12 value of x : 13
Limited Access for Syntel Employees only
56
value of x : 14 value of x : 15 value of x : 16 value of x : 17 value of x : 18 value of x : 19 For Loop: A for loop is a repetition control structure that allows you to efficiently write a loop that needs to execute a specific number of times. A for loop is useful when you know how many times a task is to be repeated. Syntax: The syntax of a for loop is: for(initialization; Boolean_expression; update) { //Statements } Here is the flow of control in a for loop:
The initialization step is executed first, and only once. This step allows you to declare and initialize any loop control variables. You are not required to put a statement here, as long as a semicolon appears. Next, the Boolean expression is evaluated. If it is true, the body of the loop is executed. If it is false, the body of the loop does not execute and flow of control jumps to the next statement past the for loop. After the body of the for loop executes, the flow of control jumps back up to the update statement. This statement allows you to update any loop control variables. This statement can be left blank, as long as a semicolon appears after the Boolean expression. The Boolean expression is now evaluated again. If it is true, the loop executes and the process repeats itself (body of loop, then update step,then Boolean expression). After the Boolean expression is false, the for loop terminates.
57
for(int x = 10; x < 20; x = x+1) { System.out.print("value of x : " + x ); System.out.print("\n"); } } } This would produce following result: value of x : 10 value of x : 11 value of x : 12 value of x : 13 value of x : 14 value of x : 15 value of x : 16 value of x : 17 value of x : 18 value of x : 19
Enhanced for loop in Java: As of java 5 the enhanced for loop was introduced. This is mainly used for Arrays.Syntax: The syntax of enhanced for loop is: for(declaration : expression) { //Statements }
Limited Access for Syntel Employees only
58
Declaration . The newly declared block variable, which is of a type compatible with the elements of the array you are accessing. The variable will be available within the for block and its value would be the same as the current array element. Expression . This evaluate to the array you need to loop through. The expression can be an array variable or method call that returns an array.
public static void main(String args[]){ int [] numbers = {10, 20, 30, 40, 50};
for(int x : numbers ){ System.out.print( x ); System.out.print(","); } System.out.print("\n"); String [] names ={"James", "Larry", "Tom", "Lacy"}; for( String name : names ) { System.out.print( name ); System.out.print(","); } } } This would produce following result: 10,20,30,40,50, James,Larry,Tom,Lacy,
59
Array in JAVA: Java provides a data structure, the array, which stores a fixed-size sequential collection of elements of the same type. An array is used to store a collection of data, but it is often more useful to think of an array as a collection of variables of the same type. Instead of declaring individual variables, such as number0, number1, ..., and number99, you declare one array variable such as numbers and use numbers[0], numbers[1], and ..., numbers[99] to represent individual variables. This tutorial introduces how to declare array variables, create arrays, and process arrays using indexed variables. Declaring Array Variables: To use an array in a program, you must declare a variable to reference the array, and you must specify the type of array the variable can reference. Here is the syntax for declaring an array variable: dataType[] arrayRefVar; // preferred way. or dataType arrayRefVar[]; // works but not preferred way. Note: The style dataType[] arrayRefVar is preferred. The style dataType arrayRefVar[] comes from the C/C++ language and was adopted in Java to accommodate C/C++ programmers. Example: The following code snippets are examples of this syntax: double[] myList; or double myList[]; Creating Arrays: You can create an array by using the new operator with the following syntax: arrayRefVar = new dataType[arraySize]; // works but not preferred way. // preferred way.
60
It creates an array using new dataType[arraySize]; It assigns the reference of the newly created array to the variable arrayRefVar.
Declaring an array variable, creating an array, and assigning the reference of the array to the variable can be combined in one statement, as shown below: dataType[] arrayRefVar = new dataType[arraySize]; Alternatively you can create arrays as follows: dataType[] arrayRefVar = {value0, value1, ..., valuek}; The array elements are accessed through the index. Array indices are 0-based; that is, they start from 0 to arrayRefVar.length-1. Example: Following statement declares an array variable, myList, creates an array of 10 elements of double type, and assigns its reference to myList.: double[] myList = new double[10]; Following picture represents array myList. Here myList holds ten double values and the indices are from 0 to 9.
Processing Arrays: When processing array elements, we often use either for loop or foreach loop because all of the elements in an array are of the same type and the size of the array is known.
Limited Access for Syntel Employees only
61
Example: Here is a complete example of showing how to create, initialize and process arrays: public class TestArray {
public static void main(String[] args) { double[] myList = {1.9, 2.9, 3.4, 3.5};
// Print all the array elements for (int i = 0; i < myList.length; i++) { System.out.println(myList[i] + " "); } // Summing all elements double total = 0; for (int i = 0; i < myList.length; i++) { total += myList[i]; } System.out.println("Total is " + total); // Finding the largest element double max = myList[0]; for (int i = 1; i < myList.length; i++) { if (myList[i] > max) max = myList[i]; } System.out.println("Max is " + max);
Limited Access for Syntel Employees only
62
} } This would produce following result: 1.9 2.9 3.4 3.5 Total is 11.7 Max is 3.5 The foreach Loops: JDK 1.5 introduced a new for loop, known as foreach loop or enhanced for loop, which enables you to traverse the complete array sequentially without using an index variable. Example: The following code displays all the elements in the array myList: public class TestArray {
public static void main(String[] args) { double[] myList = {1.9, 2.9, 3.4, 3.5}; // Print all the array elements for (double element: myList) { System.out.println(element); } }
63
} This would produce following result: 1.9 2.9 3.4 3.5 Passing Arrays to Methods: Just as you can pass primitive type values to methods, you can also pass arrays to methods. For example, the following method displays the elements in an int array: public static void printArray(int[] array) { for (int i = 0; i < array.length; i++) { System.out.print(array[i] + " "); } } You can invoke it by passing an array. For example, the following statement invokes the printArray method to display 3, 1, 2, 6, 4, and 2: printArray(new int[]{3, 1, 2, 6, 4, 2}); Returning an Array from a Method: A method may also return an array. For example, the method shown below returns an array that is the reversal of another array: public static int[] reverse(int[] list) { int[] result = new int[list.length]; for (int i = 0, j = result.length - 1; i < list.length; i++, j--) { result[j] = list[i];
64
} return result; } The Arrays Class: The java.util.Arrays class contains various static methods for sorting and searching arrays, comparing arrays, and filling array elements. These methods are overloaded for all primitive types. SN Methods with Description public static int binarySearch(Object[] a, Object key) Searches the specified array of Object ( Byte, Int , double etc) for the specified value using the binary search algorithm. The array must be sorted prior to making this call. This returns index of the search key, if it is contained in the list; otherwise, ((insertion point + 1). public static boolean equals(long[] a, long[] a2) Returns true if the two specified arrays of longs are equal to one another. Two arrays are considered equal if both arrays contain the same number of elements, and all corresponding pairs of elements in the two arrays are equal. This returns true if the two arrays are equal. Same method could be used by all other premitive data types ( Byte, short, Int etc.) public static void fill(int[] a, int val) Assigns the specified int value to each element of the specified array of ints. Same method could be used by all other premitive data types ( Byte, short, Int etc.) public static void sort(Object[] a) Sorts the specified array of objects into ascending order, according to the natural ordering of its elements. Same method could be used by all other premitive data types ( Byte, short, Int etc.)
Methods in JAVA A Java method is a collection of statements that are grouped together to perform an operation. When you call the System.out.println method, for example, the system actually executes several statements in order to display a message on the console. Now you will learn how to create your own methods with or without return values, invoke a method with or without parameters, overload methods using the same names, and apply method abstraction in the program design.
65
Creating a Method: In general, a method has the following syntax: modifier returnValueType methodName(list of parameters) { // Method body; } A method definition consists of a method header and a method body. Here are all the parts of a method:
Modifiers: The modifier, which is optional, tells the compiler how to call the method. This defines the access type of the method. Return Type: A method may return a value. The returnValueType is the data type of the value the method returns. Some methods perform the desired operations without returning a value. In this case, the returnValueType is the keyword void. Method Name: This is the actual name of the method. The method name and the parameter list together constitute the method signature. Parameters: A parameter is like a placeholder. When a method is invoked, you pass a value to the parameter. This value is referred to as actual parameter or argument. The parameter list refers to the type, order, and number of the parameters of a method. Parameters are optional; that is, a method may contain no parameters. Method Body: The method body contains a collection of statements that define what the method does.
66
Note: In certain other languages, methods are referred to as procedures and functions. A method with a nonvoid return value type is called a function; a method with a void return value type is called a procedure. Example: Here is the source code of the above defined method called max(). This method takes two parameters num1 and num2 and returns the maximum between the two: /** Return the max between two numbers */ public static int max(int num1, int num2) { int result; if (num1 > num2) result = num1; else result = num2;
return result; } Calling a Method: In creating a method, you give a definition of what the method is to do. To use a method, you have to call or invoke it. There are two ways to call a method; the choice is based on whether the method returns a value or not. When a program calls a method, program control is transferred to the called method. A called method returns control to the caller when its return statement is executed or when its method-ending closing brace is reached. If the method returns a value, a call to the method is usually treated as a value. For example: int larger = max(30, 40);
67
Classes & Objects: Class This is a class declaration. The class body (the area between the braces) contains all the code that provides for the life cycle of the objects created from the class: constructors for initializing new objects, declarations for the fields that provide the state of the class and its objects, and methods to implement the behavior of the class and its objects. The preceding class declaration is a minimal one. It contains only those components of a class declaration that are required. You can provide more information about the class, such as the name of its superclass, whether it implements any interfaces, and so on, at the start of the class declaration. For example, class MyClass extends MySuperClass implements YourInterface { // field, constructor, and // method declarations } means that MyClass is a the YourInterface interface. subclass of MySuperClass and that it implements
In general, class declarations can include these components, in order: 1. Modifiers such as public, private, and a number of others that you will encounter later. 2. The class name, with the initial letter capitalized by convention. 3. The name of the class's parent (superclass), if any, preceded by the keyword extends. A class can only extend (subclass) one parent. 4. A comma-separated list of interfaces implemented by the class, if any, preceded by the keyword implements. A class can implement more than one interface. 5. The class body, surrounded by braces, {}.
Constructors A class contains constructors that are invoked to create objects from the class blueprint. Constructor declarations look like method declarationsexcept that they use the name of the class and have no return type. Both constructors could have been declared in Box because they have different argument lists. As with methods, the Java platform differentiates constructors on the basis of the number of arguments in the list and their types. You cannot write two constructors that have the same number and type of arguments for the same class, because the platform would not be able to tell them apart. Doing so causes a compile-time error. You don't have to provide any constructors for your class, but you must be careful when doing this. The compiler automatically provides a no-argument, default constructor for
Limited Access for Syntel Employees only
68
any class without constructors. This default constructor will call the no-argument constructor of the superclass. In this situation, the compiler will complain if the superclass doesn't have a no-argument constructor so you must verify that it does. If your class has no explicit superclass, then it has an implicit superclass of Object, which does have a no-argument constructor. You can use a superclass constructor yourself. You can use access modifiers in a constructor's declaration to control which other classes can call the constructor. Static Initialization Blocks A static initialization block is a normal block of code enclosed in braces, { }, and preceded by the static keyword. Here is an example: static { // whatever code is needed for initialization goes here } A class can have any number of static initialization blocks, and they can appear anywhere in the class body. The runtime system guarantees that static initialization blocks are called in the order that they appear in the source code. Initializing Instance Members Normally, you would put code to initialize an instance variable in a constructor. There are two alternatives to using a constructor to initialize instance variables: initializer blocks and final methods. Initializer blocks for instance variables look just like static initializer blocks, but without the static keyword: { // whatever code is needed for initialization goes here } The Java compiler copies initialize blocks into every constructor. Therefore, this approach can be used to share a block of code between multiple constructors.
Passing Information to a Method or a Constructor The declaration for a method or a constructor declares the number and the type of the arguments for that method or constructor. For example, the following is a method that computes the monthly payments for a home loan, based on the amount of the loan, the interest rate, the length of the loan (the number of periods), and the future value of the loan: public double computePayment( double loanAmt, double rate, double futureValue, int numPeriods) {
Limited Access for Syntel Employees only
69
double interest = rate / 100.0; double partial1 = Math.pow((1 + interest), - numPeriods); double denominator = (1 - partial1) / interest; double answer = (-loanAmt / denominator) - ((futureValue * partial1) / denominator); return answer; } This method has four parameters: the loan amount, the interest rate, the future value and the number of periods. The first three are double-precision floating point numbers, and the fourth is an integer. The parameters are used in the method body and at runtime will take on the values of the arguments that are passed in.
Note: Parameters refers to the list of variables in a method declaration. Arguments are the actual values that are passed in when the method is invoked. When you invoke a method, the arguments used must match the declaration's parameters in type and order.
Parameter Types You can use any data type for a parameter of a method or a constructor. This includes primitive data types, such as doubles, floats, and integers, as you saw in the computePaymentmethod, and reference data types, such as objects and arrays. Here's an example of a method that accepts an array as an argument. In this example, the method creates a new Polygon object and initializes it from an array of Point objects (assume that Point is a class that represents an x, y coordinate): public Polygon polygonFrom(Point[] corners) { // method body goes here } Note: The Java programming language doesn't let you pass methods into methods. But you can pass an object into a method and then invoke the object's methods. Arbitrary Number of Arguments You can use a construct called varargs to pass an arbitrary number of values to a method. You use varargs when you don't know how many of a particular type of argument will be passed to the method. It's a shortcut to creating an array manually (the previous method could have used varargs rather than an array).
70
Parameter Names When you declare a parameter to a method or a constructor, you provide a name for that parameter. This name is used within the method body to refer to the passed-in argument. The name of a parameter must be unique in its scope. It cannot be the same as the name of another parameter for the same method or constructor, and it cannot be the name of a local variable within the method or constructor. A parameter can have the same name as one of the class's fields. If this is the case, the parameter is said to shadow the field. Shadowing fields can make your code difficult to read and is conventionally used only within constructors and methods that set a particular field. For example, consider the following Circle class and its setOrigin method: Passing Primitive Data Type Arguments Primitive arguments, such as an int or a double, are passed into methods by value. This means that any changes to the values of the parameters exist only within the scope of the method. When the method returns, the parameters are gone and any changes to them are lost. Passing Reference Data Type Arguments Reference data type parameters, such as objects, are also passed into methods by value. This means that when the method returns, the passed-in reference still references the same object as before. However, the values of the object's fields can be changed in the method, if they have the proper access level. The Garbage Collector Some object-oriented languages require that you keep track of all the objects you create and that you explicitly destroy them when they are no longer needed. Managing memory explicitly is tedious and error-prone. The Java platform allows you to create as many objects as you want (limited, of course, by what your system can handle), and you don't have to worry about destroying them. The Java runtime environment deletes objects when it determines that they are no longer being used. This process is called garbage collection. An object is eligible for garbage collection when there are no more references to that object. References that are held in a variable are usually dropped when the variable goes out of scope. Or, you can explicitly drop an object reference by setting the variable to the special value null. Remember that a program can have multiple references to the same object; all references to an object must be dropped before the object is eligible for garbage collection.
71
The Java runtime environment has a garbage collector that periodically frees the memory used by objects that are no longer referenced. The garbage collector does its job automatically when it determines that the time is right.
Creating and Using Packages To make types easier to find and use, to avoid naming conflicts, and to control access, programmers bundle groups of related types into packages.
Definition: A package is a grouping of related types providing access protection and name space management. Note that types refers to classes, interfaces, enumerations, and annotation types. Enumerations and annotation types are special kinds of classes and interfaces, respectively, so types are often referred to in this lesson simply as classes and interfaces.
The types that are part of the Java platform are members of various packages that bundle classes by function: fundamental classes are in java.lang, classes for reading and writing (input and output) are in java.io, and so on. You can put your types in packages too. Naming Conventions Package names are written in all lower case to avoid conflict with the names of classes or interfaces. Companies use their reversed Internet domain name to begin their package namesfor example, com.example.mypackage for a package named mypackage created by a programmer at example.com. Name collisions that occur within a single company need to be handled by convention within that company, perhaps by including the region or the project name after the company name (for example, com.example.region.mypackage). Packages in the Java language itself begin with java. or javax. In some cases, the internet domain name may not be a valid package name. This can occur if the domain name contains a hyphen or other special character, if the package name begins with a digit or other character that is illegal to use as the beginning of a Java name, or if the package name contains a reserved Java keyword, such as "int". In this event, the suggested convention is to add an underscore. For example:
72
Legalizing Package Names Domain Name example.int 123name.example.com Package Name Prefix int_.example com.example._123name hyphenated-name.example.org org.example.hyphenated_name
Using Package Members The types that comprise a package are known as the package members. To use a public package member from outside its package, you must do one of the following:
Refer to the member by its fully qualified name Import the package member Import the member's entire package
Importing a Package Member To import a specific member into the current file, put an import statement at the beginning of the file before any type definitions but after the package statement, if there is one. Here's how you would import the Rectangle class from the graphics package created in the previous section. import graphics.Rectangle; Now you can refer to the Rectangle class by its simple name. Rectangle myRectangle = new Rectangle(); This approach works well if you use just a few members from the graphics package. But if you use many types from a package, you should import the entire package. Importing an Entire Package To import all the types contained in a particular package, use the import statement with the asterisk (*) wildcard character. import graphics.*; Now you can refer to any class or interface in the graphics package by its simple name.
73
Name Ambiguities If a member in one package shares its name with a member in another package and both packages are imported, you must refer to each member by its qualified name. The Static Import Statement There are situations where you need frequent access to static final fields (constants) and static methods from one or two classes. Prefixing the name of these classes over and over can result in cluttered code. The static import statement gives you a way to import the constants and static methods that you want to use so that you do not need to prefix the name of their class.
This Program is covering all the following topics. Classes and Objects Class Static variables Static methods Instance variables Instance methods Constructors Pass by value and Pass by Reference Var args Local and static blocks Object Declaration Instantiation Initialization this Garbage Collector Access Modifiers
public class Box { private int length,width,height; private static int count; private int id; //default constructor
Limited Access for Syntel Employees only
74
public Box() { System.out.println("Default construtor in Box class"); } //three arguments constructor public Box(int length, int width, int height) { this.length = length; this.width = width; this.height = height; System.out.println("Three arg construtor in Box class"); } //one argument constructor public Box(int side){ this.length=this.width=this.height=side; System.out.println("One arg construtor in Box class"); } //Cloning process public Box(Box org){ this.length=org.length; this.width=org.width; this.height=org.height; System.out.println("box type arg construtor in Box class"); } //static block static{ count=0; System.out.println("static block in Box class"); } //local block { this.id=++count; System.out.println("local block in Box class"); } public int getLength() { return length; } public void setLength(int length) { this.length = length; } public int getWidth() { return width;
Limited Access for Syntel Employees only
75
} public void setWidth(int width) { this.width = width; } public int getHeight() { return height; } public void setHeight(int height) { this.height = height; } public static int getCount() { return count; } public static void setCount(int count) { Box.count = count; } public int getId() { return id; } public void setId(int id) { this.id = id; } }
package com.java.boxdemo; public class BoxService { public static int findVolume(Box box){ return box.getLength()*box.getHeight()*box.getWidth(); } public static void addSize(Box b,int size){ b.setLength(b.getLength()+size); b.setWidth(b.getWidth()+size); b.setHeight(b.getHeight()+size); } public static void addSize(int length,int width,int height,int size){ length+=size; width+=size; height+=size; }
Limited Access for Syntel Employees only
76
public static int findVolumeBoxes(Box[] boxs){ int volume=0; for(Box box : boxs){ volume=findVolume(box); } return volume; } public static int findVolumeBox(Box... boxs){ int volume=0; for(Box box : boxs){ volume=findVolume(box); } return volume; }
} package com.java.box; import com.java.boxdemo.Box; import com.java.boxdemo.BoxService; //import com.java.boxdemo.*; //import com.java.boxdemo.BoxService; //import static com.java.boxdemo.BoxService.*; //import static com.java.boxdemo.BoxService.findVolume; public class BoxMain { public static void main(String[] args) { { //Static variable and method can be used before the object is created //Static block is called when class is loaded System.out.println("No of Box object created is "+Box.getCount()); //instance are created whenever object is created //Constructor are invoked whenever object is created //it is initializing the instance values. //local block is called whenever object is created //Object Declaration Box b1; //Object Instantiation and Initialization b1=new Box(); Box b2=new Box(10,20,30); Box b3=new Box(10);
Limited Access for Syntel Employees only
77
Box b4=new Box(b2); //pass by value BoxService.addSize(b2,10); System.out.println("B2 object length is "+b2.getLength()); System.out.println("B2 object height is "+b2.getHeight()); System.out.println("B2 object width is "+b2.getWidth()); //pass by value BoxService.addSize(b4.getLength(),b4.getWidth(),b4.getHeight(),10); System.out.println("B4 object length is "+b4.getLength()); System.out.println("B4 object height is "+b4.getHeight()); System.out.println("B4 object width is "+b4.getWidth()); //passing array value Box[] a={b1,b2,b3,b4}; System.out.println("Volume "+BoxService.findVolumeBoxes(a)); //passing var args System.out.println("Volume "+BoxService.findVolumeBox(b1,b2,b3,b4)); { Box b5=new Box(); System.gc(); } System.gc(); } System.gc(); } }
of
all
the
boxes
is
of
all
the
boxes
is
78
Inheritance and Interface: Type of Relationships in JAVA Inheritance can be defined as the process where one object acquires the properties of another. With the use of inheritance the information is made manageable in a hierarchical order. When we talk about inheritance the most commonly used keyword would be extends and implements. These words would determine whether one object IS-A type of another. By using these keywords we can make one object acquire the properties of another object.
IS-A Relationship: IS-A is a way of saying : This object is a type of that object. Let us see how the extends keyword is used to achieve inheritance. public class Animal{ } public class Mammal extends Animal{ } public class Reptile extends Animal{ } public class Dog extends Mammal{ }
Now based on the above example, In Object Oriented terms following are true:
Animal is the superclass of Mammal class. Animal is the superclass of Reptile class. Mammal and Reptile are sub classes of Animal class. Dog is the subclass of both Mammal and Animal classes. Now if we consider the IS-A relationship we can say:
Limited Access for Syntel Employees only
79
Mammal IS-A Animal Reptile IS-A Animal Dog IS-A Mammal Hence : Dog IS-A Animal as well With use of the extends keyword the subclasses will be able to inherit all the properties of the superclass except for the private properties of the superclass. We can assure that Mammal is actually an Animal with the use of the instance operator. Example: public class Dog extends Mammal{ public static void main(String args[]){ Animal a = new Animal(); Mammal m = new Mammal(); Dog d = new Dog(); System.out.println(m instanceof Animal); System.out.println(d instanceof Mammal); System.out.println(d instanceof Animal); } } This would produce following result: true true true Since we have a good understanding of the extends keyword let us look into how the implementskeyword is used to get the IS-A relationship. The implements keyword is used by classes by inherit from interfaces. Interfaces can never be extended by the classes. Example: public interface Animal {} public class Mammal implements Animal{
Limited Access for Syntel Employees only
80
The instanceof Keyword: Let us use the instanceof operator to check determine whether Mammal is actually an Animal, and dog is actually an Animal interface Animal{} class Mammal implements Animal{} public class Dog extends Mammal{ public static void main(String args[]){ Mammal m = new Mammal(); Dog d = new Dog(); System.out.println(m instanceof Animal); System.out.println(d instanceof Mammal); System.out.println(d instanceof Animal); } }
HAS-A relationship: These relationships are mainly based on the usage. This determines whether a certain class HAS-Acertain thing. This relationship helps to reduce duplication of code as well as bugs. Lets us look into an example:
Limited Access for Syntel Employees only
81
public class Vehicle{} public class Speed{} public class Van extends Vehicle{ private Speed sp; } This shows that class Van HAS-A Speed. By having a separate class for Speed we do not have to put the entire code that belongs to speed inside the Van class., which makes it possible to reuse the Speed class in multiple applications. In Object Oriented feature the users do not need to bother about which object is doing the real work. To achieve this, the Van class hides the implementation details from the users of the Van class. SO basically what happens is the users would ask the Van class to do a certain action and the Vann class will either do the work by itself or ask another class to perform the action. A very important fact to remember is that Java only supports only single inheritance. This means that a class cannot extend more than one class. Therefore following is illegal: public class extends Animal, Mammal{} However a class can implement one or more interfaces. This has made Java get rid of the impossibility of multiple inheritance
Overriding: If a class inherits a method from its super class, then there is a chance to override the method provided that it is not marked final. The benefit of overriding is: ability to define a behavior that's specific to the sub class type. Which means a subclass can implement a parent class method based on its requirement. In object oriented terms, overriding means to override the functionality of any existing method.
82
Example: Let us look at an example. class Animal{ public void move(){ System.out.println("Animals can move"); } } class Dog extends Animal{ public void move(){ System.out.println("Dogs can walk and run"); } } public class TestDog{ public static void main(String args[]){ Animal a = new Animal(); // Animal reference and object Animal b = new Dog(); // Animal reference but Dog object a.move();// runs the method in Animal class b.move();//Runs the method in Dog class } }
Animals can move Dogs can walk and run In the above example you can see that the even though b is a type of Animal it runs the move method in the Dog class. The reason for this is : In compile time the check is made on the reference type. However in the runtime JVM figures out the object type and would run the method that belongs to that particular object. Therefore in the above example, the program will compile properly since Animal class has the method move. Then at the runtime it runs the method specific for that object.
Limited Access for Syntel Employees only
83
Consider the following example : class Animal{ public void move(){ System.out.println("Animals can move"); } } class Dog extends Animal{ public void move(){ System.out.println("Dogs can walk and run"); } public void bark(){ System.out.println("Dogs can bark"); } } public class TestDog{ public static void main(String args[]){ Animal a = new Animal(); // Animal reference and object Animal b = new Dog(); // Animal reference but Dog object a.move();// runs the method in Animal class b.move();//Runs the method in Dog class b.bark(); } } This would produce following result: TestDog.java:30: cannot find symbol symbol : method bark() location: class Animal b.bark(); ^ This program will throw a compile time error since b's reference type Animal doesn't have a method by the name of bark. Rules for method overriding:
The argument list should be exactly the same as that of the overridden method.
Limited Access for Syntel Employees only
84
The return type should be the same or a subtype of the return type declared in the original overridden method in the super class. The access level cannot be more restrictive than the overridden method's access level. For example: if the super class method is declared public then the overridding method in the sub class cannot be either private or protected. Instance methods can be overridden only if they are inherited by the subclass. A method declared final cannot be overridden. A method declared static cannot be overridden but can be re-declared. If a method cannot be inherited then it cannot be overridden. A subclass within the same package as the instance's superclass can override any superclass method that is not declared private or final. A subclass in a different package can only override the non-final methods declared public or protected. An overriding method can throw any uncheck exceptions, regardless of whether the overridden method throws exceptions or not. However the overriding method should not throw checked exceptions that are new or broader than the ones declared by the overridden method. The overriding method can throw narrower or fewer exceptions than the overridden method. Constructors cannot be overridden.
85
86
When invoking a superclass version of an overridden method the super keyword is used. class Animal{ public void move(){ System.out.println("Animals can move"); } } class Dog extends Animal{ public void move(){ super.move(); // invokes the super class method System.out.println("Dogs can walk and run"); } } public class TestDog{ public static void main(String args[]){ Animal b = new Dog(); // Animal reference but Dog object b.move(); //Runs the method in Dog class } }
This would produce following result: Animals can move Dogs can walk and run Abstract Class Abstraction refers to the ability to make a class abstract in OOP. An abstract class is one that cannot be instantiated. All other functionality of the class still exists, and its fields, methods, and constructors are all accessed in the same manner. You just cannot create an instance of the abstract class. If a class is abstract and cannot be instantiated, the class does not have much use unless it is subclassed. This is typically how abstract classes come about during the design phase. A parent class contains the common functionality of a collection of child classes, but the parent class itself is too abstract to be used on its own.
Limited Access for Syntel Employees only
87
Use the abstract keyword to declare a class abstract. The keyword appears in the class declaration somewhere before the class keyword. /* File name : Employee.java */ public abstract class Employee { private String name; private String address; private int number; public Employee(String name, String address, int number) { System.out.println("Constructing an Employee"); this.name = name; this.address = address; this.number = number; } public double computePay() { System.out.println("Inside Employee computePay"); return 0.0; } public void mailCheck() { System.out.println("Mailing a check to " + this.name + " " + this.address); } public String toString() { return name + " " + address + " " + number; } public String getName() { return name; } public String getAddress() { return address; } public void setAddress(String newAddress) { address = newAddress; } public int getNumber() { return number;
Limited Access for Syntel Employees only
88
} } Notice that nothing is different in this Employee class. The class is now abstract, but it still has three fields, seven methods, and one constructor. Now if you would try as follows: /* File name : AbstractDemo.java */ public class AbstractDemo { public static void main(String [] args) { /* Following is not allowed and would raise error */ Employee e = new Employee("George W.", "Houston, TX", 43); System.out.println("\n Call mailCheck using Employee reference--"); e.mailCheck(); } } When you would compile above class then you would get following error: Employee.java:46: Employee is abstract; cannot be instantiated Employee e = new Employee("George W.", "Houston, TX", 43); ^ 1 error
89
Extending Abstract Class: We can extend Employee class in normal way as follows: /* File name : Salary.java */ public class Salary extends Employee { private double salary; //Annual salary public Salary(String name, String address, int number, double salary) { super(name, address, number); setSalary(salary); } public void mailCheck() { System.out.println("Within mailCheck of Salary class "); System.out.println("Mailing check to " + getName() + " with salary " + salary); } public double getSalary() { return salary; } public void setSalary(double newSalary) { if(newSalary >= 0.0) { salary = newSalary; } } public double computePay() { System.out.println("Computing salary pay for " + getName()); return salary/52; } } Here we cannot instantiate a new Employee, but if we instantiate a new Salary object, the Salary object will inherit the three fields and seven methods from Employee. /* File name : AbstractDemo.java */ public class AbstractDemo { public static void main(String [] args)
Limited Access for Syntel Employees only
90
{ Salary s = new Salary("Mohd Mohtashim", "Ambehta, UP", 3, 3600.00); Salary e = new Salary("John Adams", "Boston, MA", 2, 2400.00); System.out.println("Call mailCheck using Salary reference --"); s.mailCheck(); System.out.println("\n Call mailCheck using Employee reference--"); e.mailCheck(); } } This would produce following result: Constructing an Employee Constructing an Employee Call mailCheck using Salary reference -Within mailCheck of Salary class Mailing check to Mohd Mohtashim with salary 3600.0 Call mailCheck using Employee reference-Within mailCheck of Salary class Mailing check to John Adams with salary 2400.
91
Abstract Methods: If you want a class to contain a particular method but you want the actual implementation of that method to be determined by child classes, you can declare the method in the parent class as abstract. The abstract keyword is also used to declare a method as abstract.An abstract methods consist of a method signature, but no method body. Abstract method would have no definition, and its signature is followed by a semicolon, not curly braces as follows: public abstract class Employee { private String name; private String address; private int number; public abstract double computePay(); //Remainder of class definition } Declaring a method as abstract has two results:
The class must also be declared abstract. If a class contains an abstract method, the class must be abstract as well. Any child class must either override the abstract method or declare itself abstract. A child class that inherits an abstract method must override it. If they do not, they must be abstract,and any of their children must override it. Eventually, a descendant class has to implement the abstract method; otherwise, you would have a hierarchy of abstract classes that cannot be instantiated. If Salary is extending Employee class then it is required to implement computePay() method as follows: /* File name : Salary.java */ public class Salary extends Employee { private double salary; // Annual salary public double computePay() {
Limited Access for Syntel Employees only
92
System.out.println("Computing salary pay for " + getName()); return salary/52; } //Remainder of class definition }
Interface An interface is a collection of abstract methods. A class implements an interface, thereby inheriting the abstract methods of the interface. An interface is not a class. Writing an interface is similar to writing a class, but they are two different concepts. A class describes the attributes and behaviors of an object. An interface contains behaviors that a class implements. Unless the class that implements the interface is abstract, all the methods of the interface need to be defined in the class. An interface is similar to a class in the following ways:
An interface can contain any number of methods. An interface is written in a file with a .java extension, with the name of the interface matching the name of the file. The bytecode of an interface appears in a .class file. Interfaces appear in packages, and their corresponding bytecode file must be in a directory structure that matches the package name. However, an interface is different from a class in several ways, including:
You cannot instantiate an interface. An interface does not contain any constructors. All of the methods in an interface are abstract. An interface cannot contain instance fields. The only fields that can appear in an interface must be declared both static and final. An interface is not extended by a class; it is implemented by a class. An interface can extend multiple interfaces.
93
Declaring Interfaces: The interface keyword is used to declare an interface. Here is a simple example to declare an interface:
94
Example: Let us look at an example that depicts encapsulation: /* File name : NameOfInterface.java */ import java.lang.*; //Any number of import statements public interface NameOfInterface { //Any number of final, static fields //Any number of abstract method declarations\ } Interfaces have the following properties:
An interface is implicitly abstract. You do not need to use the abstract keyword when declaring an interface. Each method in an interface is also implicitly abstract, so the abstract keyword is not needed. Methods in an interface are implicitly public.
95
Example: /* File name : Animal.java */ interface Animal { public void eat(); public void travel(); }
96
Implementing Interfaces: When a class implements an interface, you can think of the class as signing a contract, agreeing to perform the specific behaviors of the interface. If a class does not perform all the behaviors of the interface, the class must declare itself as abstract. Aclass uses the implements keyword to implement an interface. The implements keyword appears in the class declaration following the extends portion of the declaration. /* File name : MammalInt.java */ public class MammalInt implements Animal{ public void eat(){ System.out.println("Mammal eats"); } public void travel(){ System.out.println("Mammal travels"); } public int noOfLegs(){ return 0; } public static void main(String args[]){ MammalInt m = new MammalInt(); m.eat(); m.travel(); } } This would produce following result: Mammal eats Mammal travels When overriding methods defined in interfaces there are several rules to be followed:
Checked exceptions should not be declared on implementation methods other than the ones declared by the interface method or subclasses of those declared by the interface method. The signature of the interface method and the same return type or subtype should be maintained when overriding the methods. An implementation class itself can be abstract and if so interface methods need not be implemented.
Limited Access for Syntel Employees only
97
A class can implement more than one interface at a time. A class can extend only one class, but implement many interface. An interface can extend another interface, similarly to the way that a class can extend another class.
98
Extending Interfaces: An interface can extend another interface, similarly to the way that a class can extend another class. The extends keyword is used to extend an interface, and the child interface inherits the methods of the parent interface. The following Sports interface is extended by Hockey and Football interfaces. //Filename: Sports.java public interface Sports { public void setHomeTeam(String name); public void setVisitingTeam(String name); } //Filename: Football.java public interface Football extends Sports { public void homeTeamScored(int points); public void visitingTeamScored(int points); public void endOfQuarter(int quarter); } //Filename: Hockey.java public interface Hockey extends Sports { public void homeGoalScored(); public void visitingGoalScored(); public void endOfPeriod(int period); public void overtimePeriod(int ot); } The Hockey interface has four methods, but it inherits two from Sports; thus, a class that implements Hockey needs to implement all six methods. Similarly, a class that implements Football needs to define the three methods from Football and the two methods from Sports.
99
Extending Multiple Interfaces: A Java class can only extend one parent class. Multiple inheritance is not allowed. Interfaces are not classes, however, and an interface can extend more than one parent interface. The extends keyword is used once, and the parent interfaces are declared in a commaseparated list. For example, if the Hockey interface extended both Sports and Event, it would be declared as: public interface Hockey extends Sports, Event
100
Tagging Interfaces: The most common use of extending interfaces occurs when the parent interface does not contain any methods. For example, the MouseListener interface in the java.awt.event package extended java.util.EventListener, which is defined as: package java.util; public interface EventListener {} An interface with no methods in it is referred to as a tagging interface. There are two basic design purposes of tagging interfaces: Creates a common parent: As with the EventListener interface, which is extended by dozens of other interfaces in the Java API, you can use a tagging interface to create a common parent among a group of interfaces. For example, when an interface extends EventListener, the JVM knows that this particular interface is going to be used in an event delegation scenario. Adds a data type to a class: This situation is where the term tagging comes from. A class that implements a tagging interface does not need to define any methods (since the interface does not have any), but the class becomes an interface type through polymorphism.
Polymorphsim Polymorphism is the ability of an object to take on many forms. The most common use of polymorphism in OOP occurs when a parent class reference is used to refer to a child class object. Any java object that can pass more than one IS-A test is considered to be polymorphic. In Java, all java objects are polymorphic since any object will pass the IS-A test for their own type and for the class Object. It is important to know that the only possible way to access an object is through a reference variable. A reference variable can be of only one type. Once declared the type of a reference variable cannot be changed. The reference variable can be reassigned to other objects provided that it is not declared final. The type of the reference variable would determine the methods that it can invoke on the object. A reference variable can refer to any object of its declared type or any subtype of its declared type. A reference variable can be declared as a class or interface type.
101
Example: Let us look at an example. public interface Vegetarian{} public class Animal{} public class Deer extends Animal implements Vegetarian{} Now the Deer class is considered to be polymorphic since this has multiple inheritance. Following are true for the above example:
A Deer IS-A Animal A Deer IS-A Vegetarian A Deer IS-A Deer A Deer IS-A Object When we apply the reference variable facts to a Deer object reference, the following declarations are legal: Deer d = new Deer(); Animal a = d; Vegetarian v = d; Object o = d; All the reference variables d,a,v,o refer to the same Deer object in the heap.
102
Virtual Methods: In this section, I will show you how the behavior of overridden methods in Java allows you to take advantage of polymorphism when designing your classes. We already have discussed method overriding, where a child class can override a method in its parent. An overridden method is essentially hidden in the parent class, and is not invoked unless the child class uses the super keyword within the overriding method. /* File name : Employee.java */ public class Employee { private String name; private String address; private int number; public Employee(String name, String address, int number) { System.out.println("Constructing an Employee"); this.name = name; this.address = address; this.number = number; } public void mailCheck() { System.out.println("Mailing a check to " + this.name + " " + this.address); } public String toString() { return name + " " + address + " " + number; } public String getName() { return name; } public String getAddress() { return address; } public void setAddress(String newAddress) { address = newAddress; } public int getNumber() { return number;
Limited Access for Syntel Employees only
103
} } Now suppose we extend Employee class as follows: /* File name : Salary.java */ public class Salary extends Employee { private double salary; //Annual salary public Salary(String name, String address, int number, double salary) { super(name, address, number); setSalary(salary); } public void mailCheck() { System.out.println("Within mailCheck of Salary class "); System.out.println("Mailing check to " + getName() + " with salary " + salary); } public double getSalary() { return salary; } public void setSalary(double newSalary) { if(newSalary >= 0.0) { salary = newSalary; } } public double computePay() { System.out.println("Computing salary pay for " + getName()); return salary/52; } } Now you study the following program carefully and try to determine its output: /* File name : VirtualDemo.java */ public class VirtualDemo { public static void main(String [] args)
Limited Access for Syntel Employees only
104
{ Salary s = new Salary("Mohd Mohtashim", "Ambehta, UP", 3, 3600.00); Employee e = new Salary("John Adams", "Boston, MA", 2, 2400.00); System.out.println("Call mailCheck using Salary reference --"); s.mailCheck(); System.out.println("\n Call mailCheck using Employee reference--"); e.mailCheck(); } } This would produce following result: Constructing an Employee Constructing an Employee Call mailCheck using Salary reference -Within mailCheck of Salary class Mailing check to Mohd Mohtashim with salary 3600.0 Call mailCheck using Employee reference-Within mailCheck of Salary class Mailing check to John Adams with salary 2400.0 Here we instantiate two Salary objects . one using a Salary reference s, and the other using an Employee reference e. While invoking s.mailCheck() the compiler sees mailCheck() in the Salary class at compile time, and the JVM invokes mailCheck() in the Salary class at run time. Invoking mailCheck() on e is quite different because e is an Employee reference. When the compiler seese.mailCheck(), the compiler sees the mailCheck() method in the Employee class. Here, at compile time, the compiler used mailCheck() in Employee to validate this statement. At run time, however, the JVM invokes mailCheck() in the Salary class. This behavior is referred to as virtual method invocation, and the methods are referred to as virtual methods. All methods in Java behave in this manner, whereby an overridden method is invoked at run time, no matter what data type the reference is that was used in the source code at compile time.
105
Demo 1: package com.training; import java.util.Scanner; public abstract class Person { private String name; private int age; protected static final Scanner in=new Scanner(System.in); public Person(){ this.name=""; this.age=0; } public Person(String name,int age){ this.name=name; this.age=age; } public void accept(){ System.out.println("Enter Name"); this.name=in.next(); System.out.println("Enter Age"); this.age=in.nextInt(); } public void display(){ System.out.println("Name is\t"+name); System.out.println("Age is\t"+age); } }
package com.training; public class Student extends Person{ private double fees; private int score=0; public Student() { this.fees=0.0; this.score=0; }
Limited Access for Syntel Employees only
106
public Student(String name,int age,double fees,int score) { super(name,age); this.fees=fees; this.score=score; } @Override public void accept(){ System.out.println("Enter Student Details"); super.accept(); System.out.println("Enter Fees"); this.fees=in.nextDouble(); System.out.println("Enter Score"); this.score=in.nextInt(); } @Override public void display(){ System.out.println("Display Student Details"); super.display(); System.out.println("Fees is\t"+fees); System.out.println("Score is\t"+score); } }
package com.training; public class Faculty extends Person{ private double salary; public Faculty() { this.salary=0.0; } public Faculty(String name,int age,double salary) { super(name,age); this.salary=salary; } @Override public void accept(){ System.out.println("Enter Faculty Details"); super.accept(); System.out.println("Enter Salary"); this.salary=in.nextDouble(); } @Override public void display(){
Limited Access for Syntel Employees only
107
//Type casting Person p=null; Student s=null; Faculty f=null; //Implicit object casting s=new Student(); p=new Student();//Student is a Person f=new Faculty(); p=new Faculty();//Faculty is a Person //Explicit object casting p=new Student(); //p object is an instance of Student. s=(Student)p;//valid casting //p object is not an instance of Faculty. f=(Faculty)p;//throws ClassCastException at runtime. //To avoid Exception if(p instanceof Student){ s=(Student)p; } else if(p instanceof Faculty){ f=(Faculty)p; } //Constructors in Inheritance Student s1=new Student(); Student s2=new Student("David",21,10000.00,87); Faculty f1=new Faculty(); Faculty f2=new Faculty("Jhon",30,20000.00);
108
//Abstract Class Person p=new Person(); //instance cannot be created for abstract classes. //Dynamic Polymorphism Scanner in=new Scanner(System.in); Person p=null; System.out.println("1.Faculty"); System.out.println("2.Student"); int opt=in.nextInt(); switch(opt){ case 1: p=new Faculty(); case 2: p=new Student(); default: System.out.println("Invalid Option"); System.exit(0); } p.accept(); p.display();
Demo 2: package com.java.bank; public abstract class Account{ private int accNo; protected double balance; protected static final double MINIMUMBALANCE=500.00; public Account(){ this(-1,0.0); } public Account(int accNo,double balance){ this.accNo=accNo; this.balance=balance; } public final double checkBalance(){ return balance; } public abstract double deposit(double amount); public abstract double withdraw(double amount);
Limited Access for Syntel Employees only
109
package com.java.bank; public final class SavingAccount extends Account{ private double interest; public SavingAccount(){ interest=0.0; } public SavingAccount(int accNo,double balance,double interest){ super(accNo,balance); this.interest=interest; }
public double withdraw(double amount){ if(balance-amount>=MINIMUMBALANCE){ balance-=amount; } return balance; } public double deposit(double amount){ double balance=this.balance+amount; this.balance=balance; return balance; } }
package com.java.bank; public final class CurrentAccount extends Account{ private static final double MINIMUMBALANCE=1000.00; private double loanLimit; public CurrentAccount(){ loanLimit=0.0; }
Limited Access for Syntel Employees only
110
public double withdraw(double amount){ if(balance-amount>=MINIMUMBALANCE){ balance-=amount; } return balance; } public double deposit(double amount){ double balance=this.balance+amount; this.balance=balance; return balance; } }
} //sub class must be implementing the abstract methods of the super classes class SalaryAccount extends Account{ //Final Methods cannot not be overridden in sub class public final double checkBalance(){ return balance; } }
public static void main(String[] args) { //Dynamic Polymorphism Scanner in=new Scanner(System.in); Account acc=null; System.out.println("1.Saving Account"); System.out.println("2.Current Account");
Limited Access for Syntel Employees only
111
int opt=in.nextInt(); switch(opt){ case 1: acc=new SavingAccount(); break; case 2: acc=new CurrentAccount(); break; default: System.out.println("Invalid Option"); System.exit(0); } System.out.println("1.Withdraw"); System.out.println("2.Deposit"); System.out.println("2.Balance"); opt=in.nextInt(); double amount,oldbal,newbal; switch(opt){ case 1: System.out.println("Enter the Withdrawing amount"); amount=in.nextDouble(); oldbal=acc.checkBalance(); newbal=acc.withdraw(amount); if(oldbal==newbal){ System.out.println("Withdraw Transaction failure"); System.out.println("Current Balance is "+acc.checkBalance()); } else{ System.out.println("Withdraw Transaction Successfull"); System.out.println("Current Balance is"+acc.checkBalance()); } break; case 2: System.out.println("Enter the Deposit amount"); amount=in.nextDouble(); oldbal=acc.checkBalance(); newbal=acc.deposit(amount); if(oldbal==newbal){ System.out.println("Deposit Transaction failure"); System.out.println("Current Balance is "+acc.checkBalance()); } else{ System.out.println("Deposit Transaction Successfull"); System.out.println("Current Balance is"+acc.checkBalance()); } break;
Limited Access for Syntel Employees only
112
113
package com.draw; public class Square implements ShapeArea{ private double side; public Square(){ this.side=0.0; } public Square(double side){ this.side=side; }
package com.draw; public class Circle implements ShapePerimeter{ private double radius; public Circle(){ this.radius=0.0; } public Circle(double radius){ this.radius=radius; } @Override public double area() { return PI*radius*radius; } @Override public double perimeter() { return 2*PI*radius; }
Limited Access for Syntel Employees only
114
package com.draw; public class Sphere implements ShapeVolume{ private double radius; public Sphere(){ this.radius=0.0; } public Sphere(double radius){ this.radius=radius; } @Override public double volume() { return (4/3)*PI*radius*radius*radius; } }
package com.draw; public class Cube implements ShapeVolume{ private double length,width,height; public Cube(){ this.length=this.width=this.height=0.0; } public Cube(double length,double width,double height){ this.length=length; this.width=width; this.height=height; } public Cube(double side){ this.length=this.width=this.height=side;
Limited Access for Syntel Employees only
115
package com.draw; import java.util.Scanner; public class ShapeMain { public static void main(String[] args) { Scanner in=new Scanner(System.in); Shape s=null; System.out.println("Select the Shape"); System.out.println("1.SQUARE"); System.out.println("2.CIRCLE"); System.out.println("3.CUBE"); System.out.println("4.SPHERE"); System.out.println("5.Rectangular Prism"); int opt=in.nextInt(); double side,radius,length,width,height; switch(opt){ case 1: System.out.println("Enter the Side Value"); side=in.nextDouble(); s=new Square(side); break; case 2: System.out.println("Enter the Radius Value"); radius=in.nextDouble(); s=new Circle(radius); break; case 3: System.out.println("Enter the side value"); side=in.nextDouble(); s=new Cube(side); break; case 4:
Limited Access for Syntel Employees only
116
System.out.println("Enter the Radius value"); radius=in.nextDouble(); s=new Sphere(radius); break; case 5: System.out.println("Enter the length*width*height Value"); length=in.nextDouble(); width=in.nextDouble(); height=in.nextDouble(); s=new Cube(length,width,height); break; } if(opt==3 || opt==4 || opt==5){ ShapeVolume sv=(ShapeVolume)s; System.out.println("Volume is"+sv.volume()); } else if(opt==1){ ShapeArea sa=(ShapeArea)s; System.out.println("Area is"+sa.area()); } else if(opt==2){ ShapePerimeter sp=(ShapePerimeter)s; System.out.println("Area is"+sp.area()); System.out.println("Perimeter is"+sp.perimeter()); } else{ System.out.println("Invalid Option"); } } }
117
Nested Class: A nested class is a member of its enclosing class. Non-static nested classes (inner classes) have access to other members of the enclosing class, even if they are declared private. Static nested classes do not have access to other members of the enclosing class. As a member of the OuterClass, a nested class can be declared private, public, protected, or package private. (Recall that outer classes can only be declared public or package private.) Why Use Nested Classes? There are several compelling reasons for using nested classes, among them:
It is a way of logically grouping classes that are only used in one place. It increases encapsulation. Nested classes can lead to more readable and maintainable code.
Logical grouping of classesIf a class is useful to only one other class, then it is logical to embed it in that class and keep the two together. Nesting such "helper classes" makes their package more streamlined. Increased encapsulationConsider two top-level classes, A and B, where B needs access to members of A that would otherwise be declared private. By hiding class B within class A, A's members can be declared private and B can access them. In addition, B itself can be hidden from the outside world. More readable, maintainable codeNesting small classes within top-level classes places the code closer to where it is used. Types of Nested class: There are two types of nested classes non-static and static nested classes.The non-static nested classes are also known as inner classes. 1. non-static nested class(inner class) o a)Member inner class o b)Annomynous inner class o c)Local inner class 2. static nested class
118
Nested class Member inner class Annonymous inner class Local Inner class static nested class
package com.nested.demo; import java.util.Scanner; import com.draw.Cube; public class Box { private int length,width,height; //default constructor private Box() { System.out.println("Default construtor in Box class"); } //three arguments constructor
Limited Access for Syntel Employees only
119
private Box(int length, int width, int height) { this.length = length; this.width = width; this.height = height; System.out.println("Three arg construtor in Box class"); } public static class BoxService{ private Box b; private static Scanner in=new Scanner(System.in); public void createBox(){ System.out.println("Enter the length*width*height Value"); int length=in.nextInt(); int width=in.nextInt(); int height=in.nextInt(); b=new Box(length,width,height); } public void printBox(){ System.out.println("Print Box Details"); System.out.println("Length is"+b.length); System.out.println("Width is"+b.width); System.out.println("Height is"+b.height); } } }
public class BoxMain { public static void main(String[] args) { //Creating Object of Static Nested Class Box.BoxService b=new Box.BoxService(); b.createBox(); (); } } 1) Class Box and BoxService both can access the private members of each others. 2) Class BoxService can access only the static member of class Box directly. 3) Class BoxService can access instance member of Class Box through box reference variable.
Limited Access for Syntel Employees only
120
Non-Static Nested Class- Inner Class package com.nested.demo; import java.util.Scanner; import com.draw.Cube; public class Box { private int length,width,height; //default constructor public Box() { System.out.println("Default construtor in Box class"); } //three arguments constructor public Box(int length, int width, int height) { this.length = length; this.width = width; this.height = height; System.out.println("Three arg construtor in Box class"); } public class BoxService{ //private Box b; //private static Scanner in=new Scanner(System.in); public void printBox(){ System.out.println("Print Box Details"); System.out.println("Length is"+length); System.out.println("Width is"+width); System.out.println("Height is"+height); } } }
121
package com.nested.demo; import com.nested.demo.Box.BoxService; public class BoxMain { public static void main(String[] args) { Box b1=new Box(10,20,30); Box b2=new Box(100,200,300); //instance can be created by using outer class object. Box.BoxService bs1=b1.new BoxService(); bs1.printBox(); Box.BoxService bs2=b2.new BoxService(); bs2.printBox(); } } 1) Class Box and BoxService both can access the private members of each others. 2) Class BoxService can access both static member and instance member of class Box directly. 3) Class Boxservice does not static members to be declared inside. 4) BoxService object can be created by using only the instance of Box object.
Local Inner class package com.nested.demo; import java.util.Scanner; import com.draw.Cube; public class Box { private int length, width, height; // default constructor public Box() { System.out.println("Default construtor in Box class"); } // three arguments constructor
Limited Access for Syntel Employees only
122
public Box(int length, int width, int height) { this.length = length; this.width = width; this.height = height; System.out.println("Three arg construtor in Box class"); } public void volume() { final int volume = length * width * height; class BoxService { public void printBox() { System.out.println("Print Box Details"); System.out.println("Length is" + length); System.out.println("Width is" + width); System.out.println("Height is" + height); System.out.println("Volume is" + volume); } } } }
Local class can access only final variables of the enclosing method.
Anonymous inner class package com.nested.demo; import java.util.Scanner; import com.draw.ShapeVolume; public class BoxMain { public static void main(String[] args) { ShapeVolume s=new ShapeVolume() { private double radius,height; { Scanner in =new Scanner(System.in); System.out.println("Enter Radius"); this.radius=in.nextDouble();
Limited Access for Syntel Employees only
123
System.out.println("Enter Height"); this.height=in.nextDouble(); } @Override public double volume() { System.out.println(radius+" "+height); return (1/3.00)*PI*radius*radius*height; } }; System.out.println("Cone Volume is "+s.volume()); } }
124
Enum Types: An enum type is a special data type that enables for a variable to be a set of predefined constants. The variable must be equal to one of the values that have been predefined for it. Common examples include compass directions (values of NORTH, SOUTH, EAST, and WEST) and the days of the week. 1) 2) 3) 4) Enum improve the type safety Enum can be easily used in switch Enam can be traversed Enum may may implements interface but cannot extends any class because it is implicitly extending Enum class.
5) Enum can have fields, constructors and methods. Class declaration Following is the declaration for java.lang.Enum class: public abstract class Enum<E extends Enum<E>> extends Object implements Comparable<E>, Serializable
Demo 1: package com.enumdemo; public enum Day { //public static final Day SUNDAY=new Day(); SUNDAY,MONDAY,TUESDAY,WEDNESDAY,THURSDAY,FRIDAY,SATURDAY } package com.enumdemo; public class DayMain { public static void main(String[] args) { //new instance cannot be created. //Day d=new Day(); Day d1=Day.MONDAY; } }
125
Demo 2: package com.enumdemo; public enum Fruit { APPLE(25),MANGO(20),BANANA(5); private int price; //should nto be public constructor private Fruit(int price) { this.price=price; } public int getPrice() { return price; } public void setPrice(int price) { this.price = price; } public double calculateAmount(int count){ return count*price; } }
package com.enumdemo; import java.io.IOException; import java.util.Scanner; public class DayMain { public static void main(String[] args) { while(true){ Scanner in=new Scanner(System.in); System.out.println("Select Fruit Option"); System.out.println("1.Apple"); System.out.println("2.Mango"); System.out.println("3.Banana"); System.out.println("4.Exit"); int opt=in.nextInt(); Fruit f=null; switch(opt){ case 1: f=Fruit.APPLE; break;
Limited Access for Syntel Employees only
126
case 2: f=Fruit.MANGO; break; case 3: f=Fruit.BANANA; break; default: System.exit(0); } System.out.println("Select Option"); System.out.println("1.Display Price of"+f.name()); System.out.println("2.Change the Price of "+f.name()); System.out.println("3.Calculate the bill amount"); opt=in.nextInt(); switch(opt){ case 1: System.out.println("Price is "+f.getPrice()); break; case 2: System.out.println("Enter the price value"); int amount=in.nextInt(); f.setPrice(amount); break; case 3: System.out.println("Enter the no of Items"); int count=in.nextInt(); System.out.println("Bill amount is "+f.calculateAmount(count)); break; } } } }
127
Java Annotations Annotations, a form of metadata, provide data about a program that is not part of the program itself. Annotations have no direct effect on the operation of the code they annotate. Annotations have a number of uses, among them:
Information for the compiler Annotations can be used by the compiler to detect errors or suppress warnings. Compile-time and deployment-time processing Software tools can process annotation information to generate code, XML files, and so forth. Runtime processing Some annotations are available to be examined at runtime.
Annotation is code about the code, that is metadata about the program itself. In other words, organized data about the code, embedded within the code itself. It can be parsed by the compiler, annotation processing tools and can also be made available at run-time too. We have basic java comments infrastructure using which we add information about the code / logic so that in future, another programmer or the same programmer can understand the code in a better way. Javadoc is an additional step over it, where we add information about the class, methods, and variables in the source code. The way we need to add is organized using syntax. Therefore, we can use a tool and parse those comments and prepare a javadoc document which can be distributed separately. Javadoc facility gives option for understanding the code in an external way, instead of opening the code the javadoc document can be used separately. IDE benefits using this javadoc as it are able to render information about the code as we develop. Annotations were introduced in JDK 1.5 Uses of Annotations Annotations are far more powerful than java comments and javadoc comments. One main difference with annotation is it can be carried over to runtime and the other two stops with compilation level. Annotations are not only comments; it brings in new possibilities in terms of automated processing. In java we have been passing information to compiler for long. For example take serialization; we have the keyword transient to tell that this field is not serializable. Now instead of having such keywords decorating attribute annotations provide a generic way of adding information to class/method/field/variable. This is information is meant for programmers, automated tools, java compiler and runtime. Transient is a modifier and annotations are also a kind of modifiers.
Limited Access for Syntel Employees only
128
More than passing information, we can generate code using these annotations. Take web services where we need to adhere by the service interface contract. The skeleton can be generated using annotations automatically by an annotation parser. This avoids human errors and decreases development time as always with automation. Frameworks like Hibernate, spring, Axis make heavy use of annotations. When a language needs to be made popular one of the best things to do is support development of frameworks based on the language. Annotation is a good step towards that and will help grow Java. When Not to Use Annotations Do not over use annotation as it will pollute the code. It is better not to try to change the behavior of objects using annotations. There is sufficient constructs available in oops and annotation is not a better mechanism to deal with it. We should not what we are parsing. Do not try to over generalize as it may complicate the underlying code. Code is the real program and annotation is Meta. Avoid using annotation to specify environment / application / database related information.
Annotation Structure There are two main components in annotations. First is annotation type and the next is the annotation itself which we use in the code to add meaning. Every annotation belongs to an annotation type. Annotation Type: @interface <annotation-type-name> { method declaration; } Rules Annotation type is very similar to an interface with little difference. We attach @ just before interface keyword. Methods will not have parameters. Methods will not have throws clause. Method return types are restricted to primitives, String, Class, enums, annotations, and arrays of the preceding types. We can assign a default value to method.
129
Annotation Types Documented When a annotation type is annotated with @Documented then wherever this annotation is used those elements should be documented using Javadoc tool. Inherited This meta annotation denotes that the annotation type can be inherited from super class. When a class is annotated with annotation of type that is annotated with Inherited, then its super class will be queried till a matching annotation is found. Retention This meta annotation denotes the level till which this annotation will be carried. When an annotation type is annotated with meta annotation Retention, RetentionPolicy has three possible values: @Retention(RetentionPolicy.RUNTIME) public @interface Developer { String value(); } Class When the annotation value is given as class then this annotation will be compiled and included in the class file. Runtime The value name itself says, when the retention value is Runtime this annotation wil l be available in JVM at runtime. We can write custom code using reflection package and parse the annotation. Source This annotation will be removed at compile time and will not be available at compiled class. Target This meta annotation says that this annotation type is applicable for only the element (ElementType) listed. Possible values for ElementType are, CONSTRUCTOR, FIELD, LOCAL_VARIABLE, METHOD, PACKAGE, PARAMETER, TYPE. @Target(ElementType.FIELD) public @interface FieldInfo { } Built-in Java Annotations
130
@Documented, @Inherited, @Retention and @Target are the four available meta annotations that are built-in with Java. Apart from these meta annotations we have the following annotations. @Override When we want to override a method, we can use this annotation to say to the compiler we are overriding an existing method. If the compiler finds that there is no matching method found in super class then generates a warning. This is not mandatory to use @Override when we override a method. But I have seen Eclipse IDE automatically adding this @Override annotation. Though it is not mandatory, it is considered as a best practice. @Deprecated When we want to inform the compiler that a method is deprecated we can use this. So, when a method is annotated with @Deprecated and that method is found used in some place, then the compiler generates a warning. @SuppressWarnings This is like saying, I know what I am doing, so please shut up! We want the compiler not to raise any warnings and then we use this annotation. Custom Annotations We can create our own annotations and use it. We need to declare a annotation type and then use the respective annotation is java classes.Following is an example of custom annotation, where this annotation can be used on any element by giving values. Note that I have used @Documented meta-annotation here to say that this annotation should be parsed by javadoc. Marker Annotation package com.annotation; public @interface ProgramLog { } Single Value Annotation public @interface ProgramLog { String name(); } Multi value Annotation public @interface ProgramLog { String name(); int bugNo(); }
Limited Access for Syntel Employees only
131
Default value of an Annotation Field. package com.annotation; public @interface ProgramLog { public String name(); public int bugNo() default 0; }
package com.annotation; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Inherited; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target;
@Target(value={ElementType.CONSTRUCTOR,ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @Inherited @Documented public @interface ProgramLog { public String name(); public int bugNo() default 0; }
package com.annotation; import java.util.Scanner; import com.annotation.ProgramLog; import com.draw.Cube; //cannot be used on class type //@ProgramLog(name="Paranthaman") public class Box { private int length, width, height; // default constructor @ProgramLog(name="paranthaman") public Box() { System.out.println("Default construtor in Box class"); }
Limited Access for Syntel Employees only
132
// three arguments constructor public Box(int length, int width, int height) { this.length = length; this.width = width; this.height = height; System.out.println("Three arg construtor in Box class"); } @ProgramLog(name="paranthaman",bugNo=5) public double volume(){ return length*width*height; } } package com.annotation; import java.lang.annotation.Annotation; import java.lang.reflect.*; public class ReflectionMain { public static void main(String args[]) throws SecurityException,ClassNotFoundException { for (Method method : Class.forName("com.annotation.Box").getMethods()) { if (method.isAnnotationPresent(com.annotation.ProgramLog.class)) { try { for (Annotation anno : method.getDeclaredAnnotations()) { System.out.println("Annotation in Method '" + method + "' : " + anno); ProgramLog a = method.getAnnotation(ProgramLog.class); System.out.println("programmer Name is"+a.name()); System.out.println("Bug No is"+a.bugNo()); } } catch (Throwable ex) { ex.printStackTrace(); } } } } }
133
Generics It would be nice if we could write a single sort method that could sort the elements in an Integer array, a String array or an array of any type that supports ordering. Java Generic methods and generic classes enable programmers to specify, with a single method declaration, a set of related methods or, with a single class declaration, a set of related types, respectively. Generics also provide compile-time type safety that allows programmers to catch invalid types at compile time. Using Java Generic concept we might write a generic method for sorting an array of objects, then invoke the generic method with Integer arrays, Double arrays, String arrays and so on, to sort the array elements.
Object Type : package com.generic; public class Box { private Object length,width,height; public Box() { System.out.println("Default construtor in Box class"); } public Box(Object length, Object width, Object height) { this.length = length; this.width = width; this.height = height; System.out.println("Three arg construtor in Box class"); } public Object getLength() { return length; } public void setLength(Object length) { this.length = length; } public Object getWidth() { return width; } public void setWidth(Object width) {
Limited Access for Syntel Employees only
134
this.width = width; } public Object getHeight() { return height; } public void setHeight(Object height) { this.height = height; } }
package com.generic; public class GenericMain { public static void main(String[] args) { Box b1=new Box(10,20,30); Box b2=new Box(10.10,20.20,30.30); //Explicit Type casting int length1=(Integer)b1.getLength(); double length2=(Double)b2.getLength(); //ClassCastExcetpion at runtime int length3=(Integer)b2.getLength(); } }
Type Parameter Naming Conventions By convention, type parameter names are single, uppercase letters. This stands in sharp contrast to the variable naming conventions that you already know about, and with good reason: Without this convention, it would be difficult to tell the difference between a type variable and an ordinary class or interface name. The most commonly used type parameter names are:
E - Element (used extensively by the Java Collections Framework) K - Key N - Number T - Type V - Value S,U,V etc. - 2nd, 3rd, 4th types 135
public class Box<S> { private S length,width,height; public Box() { System.out.println("Default construtor in Box class"); } public Box(S length, S width, S height) { this.length = length; this.width = width; this.height = height; System.out.println("Three arg construtor in Box class"); } public S getLength() { return length; } public void setLength(S length) { this.length = length; } public S getWidth() { return width; } public void setWidth(S width) { this.width = width; } public S getHeight() { return height; } public void setHeight(S height) { this.height = height; } }
136
package com.generic; public class GenericMain { public static void main(String[] args) { Box<Integer> b1=new Box<Integer>(10,20,30); Box b2=new Box(); Box<Double> b3=new Box<Double>(10.10,20.20,30.30); //Compile time error //by default numbers are integer type in java. Box<Byte> b4=new Box<Byte>(10,20,30); } } Multi Type Generic Class and Generic Method and Raw Type package com.generic; package com.generic; public class Box<S,U,V> { private S length; private U width; private V height; public Box(S length, U width, V height) { this.length = length; this.width = width; this.height = height; System.out.println("Three arg construtor in Box class"); } public S getLength() { return length; } public void setLength(S length) { this.length = length; } public U getWidth() { return width; } public void setWidth(U width) { this.width = width; } public V getHeight() {
Limited Access for Syntel Employees only
137
return height; } public void setHeight(V height) { this.height = height; } public static <K, E> boolean compare(K p1,E p2) { return p1.equals(p2); } } package com.generic; public class GenericMain { public static void main(String[] args) { Box<Integer,Double,Long> Box<Integer,Double,Long>(10,20.00,30l); //Raw Type Box b2=new Box(10,20,30); } } b1=new
Bounded Type Parameters package com.generic; public class Box<S extends Number,U extends Number,V extends Number> { private S length; private U width; private V height; public Box(S length, U width, V height) { this.length = length; this.width = width; this.height = height; System.out.println("Three arg construtor in Box class"); } public S getLength() { return length; }
Limited Access for Syntel Employees only
138
public void setLength(S length) { this.length = length; } public U getWidth() { return width; } public void setWidth(U width) { this.width = width; } public V getHeight() { return height; } public void setHeight(V height) { this.height = height; } public static <K, E> boolean compare(K p1,E p2) { return p1.equals(p2); } } package com.generic; public class GenericMain { public static void main(String[] args) { Box<Integer,Double,Long> Box<Integer,Double,Long>(10,20.00,30l); //Compile time error beacause String is not a subclass of Number Box<String,String,String> b2=new Box<String, String>("100","200","300"); } } b1=new
String,
139
public class Box<S,U,V> { private S length; private U width; private V height; public Box(S length, U width, V height) { this.length = length; this.width = width; this.height = height; System.out.println("Three arg construtor in Box class"); } public S getLength() { return length; } public void setLength(S length) { this.length = length; } public U getWidth() { return width; } public void setWidth(U width) { this.width = width;
Limited Access for Syntel Employees only
140
} public V getHeight() { return height; } public void setHeight(V height) { this.height = height; } public static <K, E> boolean compare(K p1,E p2) { return p1.equals(p2); } } package com.generic; public class GenericMain { public static void test(Box<? extends Number,? extends Number,? extends Integer> box){ } public static void main(String[] args) { Box<? extends Number,? extends Number,? extends Integer> b1; b1=new Box<Long,Double,Integer>(10l,202.20,40); test(b1); //compile time error //Box<? extends Number,? extends Number,? extends Integer> b2; //b2=new Box<String,String,Integer>("10l","202.20",40); //test(b2); //compile time error //Box<? extends Number,? extends Number,? extends Integer> b2; //b1=new Box<Long,Double,Long>(10l,202.20,40l); //test(b3);
} }
141
public class Box<S,U,V> { private S length; private U width; private V height; public Box(S length, U width, V height) { this.length = length; this.width = width; this.height = height; System.out.println("Three arg construtor in Box class"); } public S getLength() { return length; } public void setLength(S length) { this.length = length; } public U getWidth() { return width; } public void setWidth(U width) { this.width = width; } public V getHeight() { return height; } public void setHeight(V height) { this.height = height; } public static <K, E> boolean compare(K p1,E p2) { return p1.equals(p2); } }
142
package com.generic; public class GenericMain { public static void main(String[] args) { Box<? super Number,? super Number,? extends Integer> b1; b1=new Box<Object,Object, Integer>(100,200,300);
} } Type Erasure Generics were introduced to the Java language to provide tighter type checks at compile time and to support generic programming. To implement generics, the Java compiler applies type erasure to:
Replace all type parameters in generic types with their bounds or Object if the type parameters are unbounded. The produced bytecode, therefore, contains only ordinary classes, interfaces, and methods. Insert type casts if necessary to preserve type safety. Generate bridge methods to preserve polymorphism in extended generic types.
Type erasure ensures that no new classes are created for parameterized types; consequently, generics incur no runtime overhead.
143
Exception Handling What are the different types of Error in JAVA? 1) Compile time error 2) Runtime Error 3) Logical Error What is Exception? Definition: An exception is an event, which occurs during the execution of a program that disrupts the normal flow of the program's instructions. An exception is a problem that arises during the execution of a program. An exception can occur for many different reasons, including the following:
A user has entered invalid data. A file that needs to be opened cannot be found. A network connection has been lost in the middle of communications, or the JVM has run out of memory.
Propagating Error in Java programming Method has been called in this order
144
How to handle Exception in JAVA? Java gives Exception API Classes and 5 keywords to handle the runtime errors. Keywords 1) try 2) catch 3) final 4) throw 5) throws
145
Exception Classes hierarchy Checked Exception Classes External Error Internal Error
Checked exceptions: A checked exception is an exception that is typically a user error or a problem that cannot be foreseen by the programmer. For example, if a file is to be opened, but the file cannot be found, an exception occurs. These exceptions cannot simply be ignored at the time of compilation. Runtime exceptions: A runtime exception is an exception that occurs that probably could have been avoided by the programmer. As opposed to checked exceptions, runtime exceptions are ignored at the time of compilation. Errors: These are not exceptions at all, but problems that arise beyond the control of the user or the programmer. Errors are typically ignored in your code because you can rarely do anything about an error. For example, if a stack overflow occurs, an error will arise. They are also ignored at the time of compilation.
ClassNotFoundException Class not found. CloneNotSupportedException Attempt to clone an object that does not implement the Cloneable interface. IllegalAccessException Access to a class is denied. InstantiationException Attempt to create an object of an abstract class or interface. InterruptedException One thread has been interrupted by another thread. NoSuchFieldException A requested field does not exist. NoSuchMethodException A requested method does not exist. 146
ArithmeticException Arithmetic error, such as divide-by-zero. ArrayIndexOutOfBoundsException Array index is out-of-bounds. ArrayStoreException Assignment to an array element of an incompatible type. ClassCastException Invalid cast. IllegalArgumentException Illegal argument used to invoke a method. IllegalMonitorStateException Illegal monitor operation, such as waiting on an unlocked thread. IllegalStateException Environment or application is in incorrect state. IllegalThreadStateException Requested operation not compatible with current thread state. IndexOutOfBoundsException Some type of index is out-of-bounds. NegativeArraySizeException Array created with a negative size. NullPointerException Invalid use of a null reference. NumberFormatException Invalid conversion of a string to a numeric format. SecurityException Attempt to violate security. StringIndexOutOfBounds Attempt to index outside the bounds of a string. UnsupportedOperationException An unsupported operation was encountered.
Exceptions Methods: Following is the list of important methods available in the Throwable class. SN Methods with Description public String getMessage() Returns a detailed message about the exception that has occurred. This message is initialized in the Throwable constructor. public Throwable getCause() Returns the cause of the exception as represented by a Throwable object. public String toString() Returns the name of the class concatenated with the result of getMessage() public void printStackTrace() Prints the result of toString() along with the stack trace to System.err, the error output stream. public StackTraceElement [] getStackTrace() Returns an array containing each element on the stack trace. The element at index 0 147
represents the top of the call stack, and the last element in the array represents the method at the bottom of the call stack. public Throwable fillInStackTrace() Fills the stack trace of this Throwable object with the current stack trace, adding to any previous information in the stack trace.
Examples 1: public void testExceptionDemo(){ try{ //try block is grouping set of programming statements //if any exception is occurred it could be handled... } catch(Exception e){ //catch block is called an exception handler //This capable to handle the Exception if the Exception // instance matching with arguments type instance. } }
public void testExceptionDemo(){ System.out.println("Line 1"); System.out.println("Line 2"); try{ System.out.println("Line 3"); System.out.println("Line 4"); System.out.println("Line 5"); } catch(Exception e){ System.out.println("Line 6"); } System.out.println("Line 7"); } What will happen if Exception thrown in line 1? What will happen if Exception thrown in line 2? What will happen if Exception thrown in line 4? What will happen if Exception thrown in line 7?
148
Examples 2: public void testExceptionDemo(){ Scanner in=new Scanner(System.in); int a,b,result; a=b=result=0; try{ System.out.println("Enter the first number"); a=in.nextInt(); System.out.println("Enter the second number"); b=in.nextInt(); result=a/b; System.out.println("Division Result "+result); } catch(InputMismatchException e){ System.out.println("User input value is invalid"); } catch(ArithmeticException e){ System.out.println("Number cannot divide by zero"); } catch(Exception e){ System.out.println("Some Exception occurred pls contact dministrator"); } System.out.println("Continue the work here"); } What will happen if first input value incorrect? What will happen if second input value incorrect? What will happen if zero as a second input value?
Examples 3: //Try, Catch and Finally Block Exception public void testExceptionDemo(){ FileInputStream in=null; try{ in=new FileInputStream("data.txt");//line 1 } catch(FileNotFoundException e){ System.out.println("File is not found"); } catch(IOException e){ System.out.println("Reading is failure"); }
Limited Access for Syntel Employees only
149
catch(Exception e){ System.out.println("Some exception occured pls contact adminitrator"); } finally{ System.out.println("Close the file"); try{ in.close(); } catch(IOException e){ System.out.println("Error in File closing"); } } System.out.println("Continue the work here"); }
1) What will happen if line 1written outside the try block? 2) Why is the file closed inside the finally?
Example 4: public void testExceptionDemo(){ Scanner in=new Scanner(System.in); System.out.println("Enter the first number"); int a=in.nextInt(); //above line throws unchecked exception so you may or may not handle this exception FileInputStream in1=new FileInputStream("data.txt"); //above line throws Exception so you must handle this exception } What will happen if you compile this class? public class Test{ public void testExceptionDemo(){ try{ } catch(RuntimeException e){ } } }
150
What will happen if you compile this class? public class Test{ public void testExceptionDemo(){ try{ } catch(IOException e){ } } }
Example 5: //How to avoid the exception handling in the method //who will handle this execption? public void testExceptionDemo() throws IOException{ FileInputStream in=new FileInputStream("data.txt"); } public void testcalling(){ try{ testExceptionDemo(); } catch(Exception e){ } }
151
Example 6: Creating User defined (own) Exception Classes //Creating Checked Exception Class public class AgeInvalidException extends Exception{ public AgeInvalidException(){ } } //Creating Unchecked Exception Class public class AgeInvalidException extends RunTimeException{ public AgeInvalidException(){ } }
How to throw User Defined Exception public void testExceptionDemo(int age)throws AgeInvalidException{ if(age<18 && age>60){ throw new AgeInvalidException(); } }
Correct the mistake if any and predict the output of the program Exercise:1 public class ExceptionType { public static void main(String args[]) { String s = null; try { System.out.println(s.length()); } catch(Exception e) { System.out.println("Exception 1"); }
152
finally { try { generateException(); } catch(Exception e) { System.out.println("Exception 2"); } } } static void generateException() throws IllegalArgumentException { throw new IllegalArgumentException(); } }
Exercise:2 public class Except { private void method1() throws Exception { throw new RuntimeException(); } public void method2() { try { method1(); } catch (RuntimeException e) { System.out.println("Caught Exception"); } catch (Exception e) { System.out.println("Caught Runtime Exception"); } } public static void main(String args[]) { Except e = new Except(); e.method2(); } }
153
Exercise:3 class Exp4 { static String s = "smile!.."; public static void main(String[] args) { new Exp4().s1(); System.out.println(s); } void s1() { try { s2(); } catch (Exception e) { s += "morning"; } } void s2() throws Exception { s3(); s += "evening"; s3(); s += "good"; } void s3() throws Exception { throw new Exception(); } } }
Exercise:4 class UserDefinedException extends Error { } class CheckedException extends RuntimeException { } class UncheckedException extends Exception { } public class TasteIt { public static void main(String args[]) { try { try { throw new Error(); } catch (UserDefinedException u1) {
Limited Access for Syntel Employees only
154
throw u1; } catch (Exception e1) { System.out.println("This is the required output"); } finally { throw new UserDefinedException(); } } catch (UserDefinedException u2) { System.out.println("This is not the output"); } catch (Error e2) { System.out.println("This is the output"); } } }
Exercise:5 class UserDefinedException extends Error { } class CheckedException extends RuntimeException { } class UncheckedException extends Exception { } public class Check { public static void main(String args[]) { generateException1(); generateException2(); } private static void generateException1() { throw new CheckedException(); } private static void generateException2() { throw new UncheckedException(); } }
155
Input and Output in JAVA What is stream? Moving the collection bytes from source place to the destination towards a particular direction is called Stream. What is InputStream? A program is receiving the data from other sources like Program and exacta. Keyboard, File, Another
What is OutputStream? A program is sending the data to destination like Monitor, File and Exactra.
IO is two types in JAVA. 1) Binary input and output Binary IO is transferring collection byte data. 2) Character input and output Character IO is transferring collection char data. Java IO Purposes and Features The Java IO classes, which mostly consists of streams and readers / writers, are addressing various purposes. That is why there are so many different classes. The purposes addressed are summarized below:
156
File Access Network Access Internal Memory Buffer Access Inter-Thread Communication (Pipes) Buffering Filtering Parsing Reading and Writing Text (Readers / Writers) Reading and Writing Primitive Data (long, int etc.) Reading and Writing Objects
Java IO Class Overview Table Having discussed sources, destinations, input, output and the various IO purposes targeted by the Java IO classes, this text will finish off with a table of most (if not all) Java IO classes divided by input, output, being byte based or character based, and any more specific purpose they may be addressing, like buffering, parsing etc.
Java IO Classes
Byte Based Input Basic Arrays Files Pipes Buffering Filtering Parsing Strings Data
Character Based Output Input Reader InputStream OutputStream InputStreamReader ByteArrayInputStream ByteArrayOutputStream CharArrayReader FileInputStream FileOutputStream RandomAccessFile RandomAccessFile FileReader PipedInputStream PipedOutputStream PipedReader BufferedInputStream BufferedOutputStream BufferedReader FilterInputStream FilterOutputStream FilterReader PushbackInputStream PushbackReader StreamTokenizer LineNumberReader StringReader DataInputStream DataOutputStream
StringWriter
157
PrintStream ObjectOutputStream
PrintWriter
Byte Streams Programs use byte streams to perform input and output of 8-bit bytes.
Character Streams The Java platform stores character values using Unicode conventions. Character stream I/O automatically translates this internal format to and from the local character set. In Western locales, the local character set is usually an 8-bit superset of ASCII. Character Streams that Use Byte Streams
Character streams are often "wrappers" for byte streams. The character stream uses the byte stream to perform the physical I/O, while the character stream handles translation between characters and bytes. FileReader, for example, uses FileInputStream, while FileWriter uses FileOutputStream.
158
File Operation Introduction The Java.io.File class is an abstract representation of file and directory pathnames. Following are the important points about File:
Instances may or may not denote an actual file-system object such as a file or a directory. If it does denote such an object then that object resides in a partition. A partition is an operating system-specific portion of storage for a file system. A file system may implement restrictions to certain operations on the actual filesystem object, such as reading, writing, and executing. These restrictions are collectively known as access permissions. Instances of the File class are immutable; that is, once created, the abstract pathname represented by a File object will never change.
Class constructors
File(File parent, String child) This method creates a new File instance from a parent abstract pathname and a child pathname string. File(String pathname) This method creates a new File instance by converting the given pathname string into an abstract pathname. File(String parent, String child) This method creates a new File instance from a parent pathname string and a child pathname string. File(URI uri) This method Creates a new File instance by converting the given file: URI into an abstract pathname.
159
File management in JAVA Application File f = null; String fileName = "C:\\paranthaman\\sample.txt"; f = new File(fileName); if (!f.exists()) { System.out.println("File does not exist already"); System.out.println("Create a new file"); try { f.createNewFile(); } catch (Exception e) { System.out.println("File could not be created"); }
File f = new File(fileName); System.out.println("is it executeable? " + f.canExecute()); System.out.println("is it readable? " + f.canExecute()); System.out.println("is it writable? " + f.canExecute()); System.out.println("File location is " + f.getAbsolutePath()); System.out.println("is it directory? " + f.isDirectory()); System.out.println("is it File? " + f.isFile()); File f = new File(fileName); System.out.println("Delete the file if Exist"); f.deleteOnExit(); // boolean result=f.delete(); File folder = new File("C:\\paranthaman\\data"); if (!folder.exists()) { System.out.println("Folder does not exist"); System.out.println("create a folder"); folder.mkdir(); } //To retrieve the all files and sub folders from current location File[] files = folder.listFiles();
//Moving the File File afile = new File("C:\\paranthaman\\data\\myphoto.jpg"); if (afile.renameTo(new File("C:\\paranthaman\\data\\temp\\myphoto.jpg"))) { System.out.println("File is moved successful!"); }
Limited Access for Syntel Employees only
160
Methods in InputStream Class Method Summary int available() Returns an estimate of the number of bytes that can be read (or skipped over) from this input stream without blocking by the next invocation of a method for this input stream. close() Closes this input stream and releases any system resources associated with the stream. mark(int readlimit) Marks the current position in this input stream.
void
void
boolean markSupported() Tests if this input stream supports the mark and reset methods. abstract read() int Reads the next byte of data from the input stream. int read(byte[] b) Reads some number of bytes from the input stream and stores them into the buffer array b. read(byte[] b, int off, int len) Reads up to len bytes of data from the input stream into an array of bytes. reset() Repositions this stream to the position at the time the mark method was last called on this input stream. skip(long n) Skips over and discards n bytes of data from this input stream.
int void
long
161
Methods are in OutputStream Class Method Summary void close() Closes this output stream and releases any system resources associated with this stream. flush() Flushes this output stream and forces any buffered output bytes to be written out. write(byte[] b) Writes b.length bytes from the specified byte array to this output stream. write(byte[] b, int off, int len) Writes len bytes from the specified byte array starting at offset off to this output stream.
void
void void
abstract write(int b) void Writes the specified byte to this output stream. Methods in Reader Class Method Summary abstract close() void Closes the stream and releases any system resources associated with it. void mark(int readAheadLimit) Marks the present position in the stream.
boolean markSupported() Tells whether this stream supports the mark() operation. int int read() Reads a single character. read(char[] cbuf) Reads characters into an array. int len)
abstract read(char[] cbuf, int off, int Reads characters into a portion of an array. int read(CharBuffer target) Attempts to read characters into the specified character buffer.
boolean ready() Tells whether this stream is ready to be read. void reset() Resets the stream.
162
long
Methods are in Writer Class Method Summary Writer append(char c) Appends the specified character to this writer. Writer append(CharSequence csq) Appends the specified character sequence to this writer. Writer append(CharSequence csq, int start, int end) Appends a subsequence of the specified character sequence to this writer. abstract close() void Closes the stream, flushing it first. abstract flush() void Flushes the stream. void write(char[] cbuf) Writes an array of characters. int len)
abstract write(char[] cbuf, int off, void Writes a portion of an array of characters. void void void write(int c) Writes a single character. write(String str) Writes a string. write(String str, Writes a portion of a string. int off,
int len)
163
Exception Classes
164
InputStream Classes
165
OutputStream Classes
Reading Data From Console System.in System.in is an InputStream which is typically connected to keyboard input of console programs. System.in is not used as often since data is commonly passed to a command line Java application via command line arguments, or configuration files. In applications
166
with GUI the input to the application is given via the GUI. This is a separate input mechanism from Java IO. System.out System.out is a PrintStream. System.out normally outputs the data you write to it to the console. This is often used from console-only programs like command line tools. This is also often used to print debug statements of from a program (though it may arguably not be the best way to get debug info out of a program). System.err System.err is a PrintStream. System.err works like System.out except it is normally only used to output error texts. Some programs (like Eclipse) will show the output to System.err in red text, to make it more obvious that it is error text. Reading Character one by one from Console try{ BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); char c; System.out.println("Enter characters, 'q' to quit."); // read characters do { c = (char) br.read(); System.out.println(c); } while (c != 'q'); } catch(IOException e){ System.out.println("Reading is failure"); } Reading String one by one from Console try{ BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); String str; System.out.println("Enter lines of text."); System.out.println("Enter 'end' to quit."); do { str = br.readLine(); System.out.println(str); } while(!str.equals("end")); }
Limited Access for Syntel Employees only
167
catch(IOException e){ } Read the Byte Data from File using FileInputSteam public static void main(String[] args) { InputStream input =null; try{ input= new FileInputStream("output.txt"); // input=new BufferedInputStream(new FileInputStream("output.txt")); int data = input.read(); while(data != -1){ System.out.print((char)data); data = input.read(); } } catch(IOException e){ System.out.println("IO Excetpion occured"); } finally{ try{ input.close(); }catch(Exception e){ System.out.println("file closing error"); } System.out.println("\nDone ...."); } } Writing Byte Data to File using FileOutputStream public static void read() { OutputStream output =null; try{ output= new FileOutputStream("output.txt"); //output= new BufferedOutputStream(FileOutputStream("output.txt")); output.write("Hello World".getBytes()); } catch(IOException e){ System.out.println("IO Excetpion occured"); } finally{ try{ output.close(); }
Limited Access for Syntel Employees only
168
catch(Exception e){ System.out.println("file closing error"); } System.out.println("Done ...."); } } Read the Byte Data from File using BufferedInputStream public static void main(String[] args) { BufferedInputStream input =null; try{ input=new BufferedInputStream(new FileInputStream("output.txt")); int data = input.read(); while(data != -1){ System.out.print((char)data); data = input.read(); } } catch(IOException e){ System.out.println("IO Excetpion occured"); } finally{ try{ input.close(); }catch(Exception e){ System.out.println("file closing error"); } System.out.println("\nDone ...."); } } Writing Byte Data to File using BufferedOutputStream public static void read() { BufferedOutputStream output =null; try{ output= new BufferedOutputStream(FileOutputStream("output.txt")); output.write("Hello World".getBytes()); } catch(IOException e){ System.out.println("IO Excetpion occured"); } finally{ try{ output.close();
Limited Access for Syntel Employees only
169
} catch(Exception e){ System.out.println("file closing error"); } System.out.println("Done ...."); } } Read Data From File using FileReader public static void main(String[] args) { Reader reader = null; try { reader = new FileReader("c:\\paranthaman\\input.txt"); int data = reader.read(); while (data != -1) { System.out.println(data); data = reader.read(); } reader.close(); } catch (IOException e) { System.out.println("IO Excetpion occured"); } finally { try { reader.close(); } catch (Exception e) { System.out.println("file closing error"); } System.out.println("\nDone ...."); } } Write Data to File using FileWriter public static void main(String[] args) { Writer writer = null; try { writer = new FileWriter("c:\\paranthaman\\input.txt"); writer.write("Hi Welcome to IO in JAVA"); } catch (IOException e) { System.out.println("IO Excetpion occured"); } finally { try { writer.close(); } catch (Exception e) { System.out.println("file closing error");
Limited Access for Syntel Employees only
170
} System.out.println("\nDone ...."); } } How to convert from InputStream to Reader InputStream inputStream = new FileInputStream("c:\\data\\input.txt"); Reader reader = new InputStreamReader(inputStream); How to convert from OutputStream to Writer OutputStream outputStream = new FileOutputStream("c:\\data\\output.txt"); Writer writer = new OutputStreamWriter(outputStream);
How to read other types of Data in JAVA public static void main(String[] args) { DataInputStream input = null; try { input = new DataInputStream(new FileInputStream("binary.data")); int aByte = input.read(); int anInt = input.readInt(); float aFloat = input.readFloat(); double aDouble = input.readDouble(); System.out.println(aByte + " " + anInt + " " + aFloat + " " + aDouble); } catch (IOException e) { System.out.println("IO Excetpion occured"); } finally { try { input.close(); } catch (Exception e) { System.out.println("file closing error"); } System.out.println("\nDone ...."); } } How to Write other types of Data in JAVA public static void main(String[] args) { DataOutputStream output = null; try { output = new DataOutputStream(new FileOutputStream("binary.data")); output.write(45); // byte data output.writeInt(4545); // int data output.writeFloat(109.123f); // float data output.writeDouble(109.123); // double data
Limited Access for Syntel Employees only
171
} catch (IOException e) { System.out.println("IO Excetpion occured"); } finally { try { output.close(); } catch (Exception e) { System.out.println("file closing error"); } System.out.println("\nDone ...."); } } How to write Object in File What is Serialization? Convert from object type to stream type so it can be transferred. This process is called a serialization. package com.file.io; import java.io.Serializable; public class Box implements Serializable{ private int length,width,height; //static cannot be serialized private static int count; //transient cannot be serialized private transient int id; //default constructor public Box() { System.out.println("Default construtor in Box class"); } //three arguments constructor public Box(int length, int width, int height) { this.length = length; this.width = width; this.height = height; System.out.println("Three arg construtor in Box class"); } //one argument constructor public Box(int side){ this.length=this.width=this.height=side;
Limited Access for Syntel Employees only
172
System.out.println("One arg construtor in Box class"); } //Cloning process public Box(Box org){ this.length=org.length; this.width=org.width; this.height=org.height; System.out.println("box type arg construtor in Box class"); } //static block static{ count=0; System.out.println("static block in Box class"); } //local block { this.id=++count; System.out.println("local block in Box class"); } public int getLength() { return length; } public void setLength(int length) { this.length = length; } public int getWidth() { return width; } public void setWidth(int width) { this.width = width; } public int getHeight() { return height; } public void setHeight(int height) { this.height = height; } public static int getCount() { return count; } public static void setCount(int count) { Box.count = count;
Limited Access for Syntel Employees only
173
} public int getId() { return id; } public void setId(int id) { this.id = id; } }
package com.file.io; import java.io.*; import java.util.Scanner; public class IOMain { public static void write(Box b1) { ObjectOutputStream in = null; try { in = new ObjectOutputStream(new FileOutputStream("data.dat",true)); in.writeObject(b1); } catch (Exception e) { System.out.println("IO Excetpion occured"+e); } finally { try { in.close(); } catch (Exception e) { System.out.println("file closing error"+e); } System.out.println("\nDone ...."); } } public static void read() { ObjectInputStream in = null; try { in = new ObjectInputStream(new FileInputStream("data.dat")); Box b1 = null; b1 = (Box) in.readObject(); while (b1 != null) { System.out.println("Length is "+b1.getLength()); System.out.println("Width is "+b1.getWidth()); System.out.println("Height is"+b1.getHeight()); b1 = (Box) in.readObject();
Limited Access for Syntel Employees only
174
} } catch (Exception e) { System.out.println("IO Excetpion occured"+e); } finally { try { in.close(); } catch (Exception e) { System.out.println("file closing error"); } System.out.println("\nDone ...."); } } public static void main(String[] args) { Scanner in=new Scanner(System.in); System.out.println("1.Write"); System.out.println("2.Read"); int opt=in.nextInt(); switch(opt){ case 1: System.out.println("Enter Box lenght*width*height"); Box b1=new Box(in.nextInt(),in.nextInt(),in.nextInt()); write(b1); System.out.println("Stored successfully"); break; case 2: read(); } } } Reading random data from file package com.file.io; import java.io.IOException; import java.io.RandomAccessFile; public class MainIO { public static void main(String[] args) { try{ RandomAccessFile file = new RandomAccessFile("data.txt", "rw"); file.seek(10); //reading 11 position character System.out.println((char)file.read()); //Replacing the 12 to 15 position value
Limited Access for Syntel Employees only
175
176
Threads Concurrency Computer users take it for granted that their systems can do more than one thing at a time. They assume that they can continue to work in a word processor, while other applications download files, manage the print queue, and stream audio. Even a single application is often expected to do more than one thing at a time. For example, that streaming audio application must simultaneously read the digital audio off the network, decompress it, manage playback, and update its display. Even the word processor should always be ready to respond to keyboard and mouse events, no matter how busy it is reformatting text or updating the display. Software that can do such things is known as concurrent software. Processes and Threads In concurrent programming, there are two basic units of execution: processes and threads. In the Java programming language, concurrent programming is mostly concerned with threads. However, processes are also important. A computer system normally has many active processes and threads. This is true even in systems that only have a single execution core, and thus only have one thread actually executing at any given moment. Processing time for a single core is shared among processes and threads through an OS feature called time slicing. It's becoming more and more common for computer systems to have multiple processors or processors with multiple execution cores. This greatly enhances a system's capacity for concurrent execution of processes and threads but concurrency is possible even on simple systems, without multiple processors or execution cores. Processes A process has a self-contained execution environment. A process generally has a complete, private set of basic run-time resources; in particular, each process has its own memory space. Processes are often seen as synonymous with programs or applications. However, what the user sees as a single application may in fact be a set of cooperating processes. To facilitate communication between processes, most operating systems support Inter Process Communication (IPC) resources, such as pipes and sockets. IPC is used not just for communication between processes on the same system, but processes on different systems.
177
Threads Threads are sometimes called lightweight processes. Both processes and threads provide an execution environment, but creating a new thread requires fewer resources than creating a new process. Threads exist within a process every process has at least one. Threads share the process's resources, including memory and open files. This makes for efficient, but potentially problematic, communication. Multithreaded execution is an essential feature of the Java platform. Every application has at least one thread or several, if you count "system" threads that do things like memory management and signal handling. But from the application programmer's point of view, you start with just one thread, called the main thread. This thread has the ability to create additional threads, as we'll demonstrate in the next section. Thread Objects Each thread is associated with an instance of the class Thread. There are two basic strategies for using Thread objects to create a concurrent application. To directly control thread creation and management, simply instantiate Thread each time the application needs to initiate an asynchronous task.
To abstract thread management from the rest of your application, pass the application's tasks to an executor.
Defining and Starting a Thread public class HelloRunnable implements Runnable { public void run() { System.out.println("Hello from a thread!"); } public static void main(String args[]) { (new Thread(new HelloRunnable())).start(); System.out.println("Hello from Main Thread"); } } public class HelloThread extends Thread { public void run() { System.out.println("Hello from a thread!"); }
178
public static void main(String args[]) { (new HelloThread()).start(); System.out.println("Hello from Main Thread"); } }
Sleep Method public class HelloThread extends Thread { public void run() { while(true){ try{ Thread.sleep(1000); Date t=new Date(); System.out.println(t.getHours()+":"+t.getMinutes()+":"+t.getSeconds()); } catch(InterruptedException e){ System.out.println("disturbed in sleeping"); } } } public static void main(String args[]) { (new HelloThread()).start(); System.out.println("Hello from Main Thread"); } } Interrupte Method import java.util.Date; public class HelloThread extends Thread { public void run() { while(true){ try{ Thread.sleep(1000); Date t=new Date(); System.out.println(t.getHours()+":"+t.getMinutes()+":"+t.getSeconds()); } catch(InterruptedException e){
Limited Access for Syntel Employees only
179
System.out.println("Thread is disturbed in sleeping"); } } } public static void main(String args[]) { Thread t=new HelloThread(); t.start(); try{ t.sleep(1000); } catch(InterruptedException e){ } t.interrupt(); } } Join Method import java.util.Date; public class HelloThread extends Thread { public void run() { for(int i=1;i<=10;i++) try{ Thread.sleep(1000); Date t=new Date(); System.out.println(t.getHours()+":"+t.getMinutes()+":"+t.getSeconds()); } catch(InterruptedException e){ System.out.println("Thread is disturbed in sleeping"); } } public static void main(String args[]) { Thread t=new HelloThread(); t.start(); try{ t.join(5000); } catch(InterruptedException e){ System.out.println("Main is disturbed"); } System.out.println("Main Thread"); }}
Limited Access for Syntel Employees only
180
Introduction to Collections A collection sometimes called a container is simply an object that groups multiple elements into a single unit. Collections are used to store, retrieve, manipulate, and communicate aggregate data. Typically, they represent data items that form a natural group, such as a poker hand (a collection of cards), a mail folder (a collection of letters), or a telephone directory (a mapping of names to phone numbers). If you have used the Java programming language or just about any other programming language you are already familiar with collections. What Is a Collections Framework? A collections framework is a unified architecture for representing and manipulating collections. All collections frameworks contain the following:
Interfaces: These are abstract data types that represent collections. Interfaces allow collections to be manipulated independently of the details of their representation. In object-oriented languages, interfaces generally form a hierarchy. Implementations: These are the concrete implementations of the collection interfaces. In essence, they are reusable data structures. Algorithms: These are the methods that perform useful computations, such as searching and sorting, on objects that implement collection interfaces. The algorithms are said to be polymorphic: that is, the same method can be used on many different implementations of the appropriate collection interface. In essence, algorithms are reusable functionality.
Apart from the Java Collections Framework, the best-known examples of collections frameworks are the C++ Standard Template Library (STL) and Smalltalk's collection hierarchy. Historically, collections frameworks have been quite complex, which gave them a reputation for having a steep learning curve. We believe that the Java Collections Framework breaks with this tradition, as you will learn for yourself in this chapter. Benefits of the Java Collections Framework The Java Collections Framework provides the following benefits:
Reduces programming effort: By providing useful data structures and algorithms, the Collections Framework frees you to concentrate on the important parts of your program rather than on the low-level "plumbing" required to make it work. By facilitating interoperability among unrelated APIs, the Java Collections Framework frees you from writing adapter objects or conversion code to connect APIs.
181
Increases program speed and quality: This Collections Framework provides high-performance, high-quality implementations of useful data structures and algorithms. The various implementations of each interface are interchangeable, so programs can be easily tuned by switching collection implementations. Because you're freed from the drudgery of writing your own data structures, you'll have more time to devote to improving programs' quality and performance.
Allows interoperability among unrelated APIs: The collection interfaces are the vernacular by which APIs pass collections back and forth. If my network administration API furnishes a collection of node names and if your GUI toolkit expects a collection of column headings, our APIs will interoperate seamlessly, even though they were written independently.
Reduces effort to learn and to use new APIs: Many APIs naturally take collections on input and furnish them as output. In the past, each such API had a small sub-API devoted to manipulating its collections. There was little consistency among these ad hoc collections sub-APIs, so you had to learn each one from scratch, and it was easy to make mistakes when using them. With the advent of standard collection interfaces, the problem went away.
Reduces effort to design new APIs: This is the flip side of the previous advantage. Designers and implementers don't have to reinvent the wheel each time they create an API that relies on collections; instead, they can use standard collection interfaces.
Fosters software reuse: New data structures that conform to the standard collection interfaces are by nature reusable. The same goes for new algorithms that operate on objects that implement these interfaces.
182
183
The general-purpose implementations are summarized in the following table. General-purpose Implementations Resizable Hash table Tree Linked list Interfac array Implementati Implementati Implementati es Implementati ons ons ons ons Set List Queue Deque Map HashMap (HashTable) ArrayDeque TreeMap LinkedList LinkedHashM ap HashSet ArrayList (Vector) TreeSet LinkedList
List
Set
Map
Queue
java.util.LinkedList java.util.PriorityQueue
Commonly used methods of Collection interface There are many methods declared in the Collection interface. They are as follows: 1. public boolean add(object element): is used to insert an element in this collection. 2. public boolean addAll(collection c):is used to insert the specifed collection elements in the invoking collection. 3. public boolean remove(object element):is used to delete an element from this collection. 4. public boolean removeAll(Collection c):is used to delete all the elements of specified collection from the invoking collection. 5. public boolean retainAll(Collection c):is used to delete all the elements of invoking collection except the specified collection. 6. public int size():return the total number of elements in the collection. 7. public void clear():removes the total no of element from the collection. 8. public boolean contains(object element):is used to search an element. 9. public boolean containsAll(collection c):is used to search the specified collection in this collection. 10. public Iterator iterator():returns an iterator. Iterator interface Iterator interface provides the facility of iterating the elements in forward direction only.
Methods of Iterator interface There are only three methods in the Iterator interface. They are 1) public boolean hasNext() it returns true if iterator has more elements. 2) public object next() it returns the element and moves the cursor pointer to the next element. 3) public void remove() it removes the last elements returned by the iterator. It is rarely used.
Limited Access for Syntel Employees only
185
186
187
Iterator and ListIterator Interface package com.collection; import java.util.*; public class ArrayListMain { public static void main(String[] args) { List<Integer> list=new ArrayList<Integer>(); System.out.println(list.add(10)); System.out.println(list.add(20)); System.out.println(list.add(30)); System.out.println(list.add(40)); System.out.println(list.add(50)); Iterator<Integer> it=list.iterator(); while(it.hasNext()){ System.out.println(it.next()); } ListIterator<Integer> it1=list.listIterator(); while(it1.hasNext()){ System.out.println(it1.next()); } while(it1.hasPrevious()){ int n=it1.previous(); if(n%100==0){ it1.set(100); } if(n%7==0){ it.remove(); } System.out.println(n); } } }
188
189
190
191
192
193
194
195
196
197
198
199
200
What is JDBC? JDBC stands for Java Database Connectivity, which is a standard Java API for databaseindependent connectivity between the Java programming language and a wide range of databases. The JDBC library includes APIs for each of the tasks commonly associated with database usage:
Making a connection to a database Creating SQL or MySQL statements Executing that SQL or MySQL queries in the database Viewing & Modifying the resulting records
Fundamentally, JDBC is a specification that provides a complete set of interfaces that allows for portable access to an underlying database. Java can be used to write different types of executables, such as:
Java Applications Java Applets Java Servlets Java ServerPages (JSPs) Enterprise JavaBeans (EJBs)
All of these different executables are able to use a JDBC driver to access a database and take advantage of the stored data. JDBC provides the same capabilities as ODBC, allowing Java programs to contain database-independent code. Pre-Requisite: Before progressing on this tutorial you need to have good understanding on the following two subjects:
201
JDBC Architecture: The JDBC API supports both two-tier and three-tier processing models for database access but in general JDBC Architecture consists of two layers:
JDBC API: This provides the application-to-JDBC Manager connection. JDBC Driver API: This supports the JDBC Manager-to-Driver Connection.
The JDBC API uses a driver manager and database-specific drivers to provide transparent connectivity to heterogeneous databases. The JDBC driver manager ensures that the correct driver is used to access each data source. The driver manager is capable of supporting multiple concurrent drivers connected to multiple heterogeneous databases. Following is the architectural diagram, which shows the location of the driver manager with respect to the JDBC drivers and the Java application:
202
Common JDBC Components: The JDBC API provides the following interfaces and classes:
DriverManager: This class manages a list of database drivers. Matches connection requests from the java application with the proper database driver using communication subprotocol. The first driver that recognizes a certain subprotocol under JDBC will be used to establish a database Connection. Driver: This interface handles the communications with the database server. You will interact directly with Driver objects very rarely. Instead, you use DriverManager objects, which manages objects of this type. It also abstracts the details associated with working with Driver objects Connection : This interface with all methods for contacting a database. The connection object represents communication context, i.e., all communication with database is through connection object only. Statement : You use objects created from this interface to submit the SQL statements to the database. Some derived interfaces accept parameters in addition to executing stored procedures. ResultSet: These objects hold data retrieved from a database after you execute an SQL query using Statement objects. It acts as an iterator to allow you to move through its data. SQLException: This class handles any errors that occur in a database application.
The JDBC 4.0 Packages The java.sql and javax.sql are the primary packages for JDBC 4.0. This is the latest JDBC version at the time of writing this tutorial. It offers the main classes for interacting with your data sources. The new features in these packages include changes in the following areas:
Automatic database driver loading Exception handling improvements Enhanced BLOB/CLOB functionality Connection and statement interface enhancements National character set support SQL ROWID access 203
Structured Query Language (SQL) is a standardized language that allows you to perform operations on a database, such as creating entries, reading content, updating content, and deleting entries. SQL is supported by all most any database you will likely use, and it allows you to write database code independently of the underlying database. This tutorial gives an overview of SQL, which is a pre-requisite to understand JDBC concepts. This tutorial gives you enough SQL to be able to Create, Read, Update, and Delete (often referred to as CRUD operations) data from a database. For a detailed understanding on SQL, you can read our MySQL Tutorial. Create Database: The CREATE DATABASE statement is used for creating a new database. The syntax is: SQL> CREATE DATABASE DATABASE_NAME; Example: The following SQL statement creates a Database named EMP: SQL> CREATE DATABASE EMP; Drop Database: The DROP DATABASE statement is used for deleting an existing database. The syntax is: SQL> DROP DATABASE DATABASE_NAME; Note: To create or drop a database you should have administrator privilege on your database server. Be careful, deleting a database would loss all the data stored in database. Create Table: The CREATE TABLE statement is used for creating a new table. The syntax is: SQL> CREATE TABLE table_name
Limited Access for Syntel Employees only
204
( column_name column_data_type, column_name column_data_type, column_name column_data_type ... ); Example: The following SQL statement creates a table named Employees with four columns: SQL> CREATE TABLE Employees ( id INT NOT NULL, age INT NOT NULL, first VARCHAR(255), last VARCHAR(255), PRIMARY KEY ( id ) ); Drop Table: The DROP TABLE statement is used for deleting an existing table. The syntax is: SQL> DROP TABLE table_name; Example: The following SQL statement deletes a table named Employees: SQL> DROP TABLE Employees; INSERT Data: The syntax for INSERT looks similar to the following, where column1, column2, and so on represent the new data to appear in the respective columns:
205
SQL> INSERT INTO table_name VALUES (column1, column2, ...); Example: The following SQL INSERT statement inserts a new row in the Employees database created earlier: SQL> INSERT INTO Employees VALUES (100, 18, 'Zara', 'Ali'); SELECT Data: The SELECT statement is used to retrieve data from a database. The syntax for SELECT is: SQL> SELECT column_name, column_name, ... FROM table_name WHERE conditions; The WHERE clause can use the comparison operators such as =, !=, <, >, <=,and >=, as well as the BETWEEN and LIKE operators. Example: The following SQL statement selects the age, first and last columns from the Employees table where id column is 100: SQL> SELECT first, last, age FROM Employees WHERE id = 100; The following SQL statement selects the age, first and last columns from the Employees table where first column contains Zara: SQL> SELECT first, last, age FROM Employees WHERE first LIKE '%Zara%'; UPDATE Data: The UPDATE statement is used to update data. The syntax for UPDATE is:
Limited Access for Syntel Employees only
206
SQL> UPDATE table_name SET column_name = value, column_name = value, ... WHERE conditions; The WHERE clause can use the comparison operators such as =, !=, <, >, <=,and >=, as well as the BETWEEN and LIKE operators. Example: The following SQL UPDATE statement changes the age column of the employee whose id is 100: SQL> UPDATE Employees SET age=20 WHERE id=100; DELETE Data: The DELETE statement is used to delete data from tables. The syntax for DELETE is: SQL> DELETE FROM table_name WHERE conditions; The WHERE clause can use the comparison operators such as =, !=, <, >, <=,and >=, as well as the BETWEEN and LIKE operators. Example: The following SQL DELETE statement delete the record of the employee whose id is 100: SQL> DELETE FROM Employees WHERE id=100;
To start developing with JDBC setup your JDBC environment by following the steps shown below. We assume that you are working on a Windows platform. This tutorial provides an example of how to create a simple JDBC application. This will show you how to open a database connection, execute a SQL query, and display the results. All the steps mentioned in this template example, would be explained in subsequent chapters of this tutorial.
207
Creating JDBC Application: There are following six steps involved in building a JDBC application:
Import the packages . Requires that you include the packages containing the JDBC classes needed for database programming. Most often, using import java.sql.* will suffice. Register the JDBC driver . Requires that you initialize a driver so you can open a communications channel with the database. Open a connection . Requires using the DriverManager.getConnection() method to create a Connection object, which represents a physical connection with the database. Execute a query . Requires using an object of type Statement for building and submitting an SQL statement to the database. Extract data from result set . Requires that you use the appropriate ResultSet.getXXX() method to retrieve the data from the result set. Clean up the environment . Requires explicitly closing all database resources versus relying on the JVM's garbage collection.
What is JDBC Driver ? JDBC drivers implement the defined interfaces in the JDBC API for interacting with your database server. For example, using JDBC drivers enable you to open database connections and to interact with it by sending SQL or database commands then receiving results with Java. The Java.sql package that ships with JDK contains various classes with their behaviours defined and their actual implementaions are done in third-party drivers. Third party vendors implements the java.sql.Driver interface in their database driver. JDBC Drivers Types: JDBC driver implementations vary because of the wide variety of operating systems and hardware platforms in which Java operates. Sun has divided the implementation types into four categories, Types 1, 2, 3, and 4, which is explained below:
208
Type 1: JDBC-ODBC Bridge Driver: In a Type 1 driver, a JDBC bridge is used to access ODBC drivers installed on each client machine. Using ODBC requires configuring on your system a Data Source Name (DSN) that represents the target database. When Java first came out, this was a useful driver because most databases only supported ODBC access but now this type of driver is recommended only for experimental use or when no other alternative is available.
The JDBC-ODBC bridge that comes with JDK 1.2 is a good example of this kind of driver. Type 2: JDBC-Native API: In a Type 2 driver, JDBC API calls are converted into native C/C++ API calls which are unique to the database. These drivers typically provided by the database vendors and used in the same manner as the JDBC-ODBC Bridge, the vendor-specific driver must be installed on each client machine. If we change the Database we have to change the native API as it is specific to a database and they are mostly obsolete now but you may realize some speed increase with a Type 2 driver, because it eliminates ODBC's overhead.
209
The Oracle Call Interface (OCI) driver is an example of a Type 2 driver. Type 3: JDBC-Net pure Java: In a Type 3 driver, a three-tier approach is used to accessing databases. The JDBC clients use standard network sockets to communicate with an middleware application server. The socket information is then translated by the middleware application server into the call format required by the DBMS, and forwarded to the database server. This kind of driver is extremely flexible, since it requires no code installed on the client and a single driver can actually provide access to multiple databases.
210
You can think of the application server as a JDBC "proxy," meaning that it makes calls for the client application. As a result, you need some knowledge of the application server's configuration in order to effectively use this driver type. Your application server might use a Type 1, 2, or 4 driver to communicate with the database, understanding the nuances will prove helpful. Type 4: 100% pure Java: In a Type 4 driver, a pure Java-based driver that communicates directly with vendor's database through socket connection. This is the highest performance driver available for the database and is usually provided by the vendor itself. This kind of driver is extremely flexible, you don't need to install special software on the client or server. Further, these drivers can be downloaded dynamically.
MySQL's Connector/J driver is a Type 4 driver. Because of the proprietary nature of their network protocols, database vendors usually supply type 4 drivers. Which Driver should be used? If you are accessing one type of database, such as Oracle, Sybase, or IBM, the preferred driver type is 4. If your Java application is accessing multiple types of databases at the same time, type 3 is the preferred driver.
211
Type 2 drivers are useful in situations where a type 3 or type 4 driver is not available yet for your database. The type 1 driver is not considered a deployment-level driver and is typically used for development and testing purposes only.
After you've installed the appropriate driver, it's time to establish a database connection using JDBC. The programming involved to establish a JDBC connection is fairly simple. Here are these simple four steps:
Import JDBC Packages: Add import statements to your Java program to import required classes in your Java code. Register JDBC Driver: This step causes the JVM to load the desired driver implementation into memory so it can fulfill your JDBC requests. Database URL Formulation: This is to create a properly formatted address that points to the database to which you wish to connect. Create Connection Object: Finally, code a call to the DriverManager object's getConnection( ) method to establish actual database connection.
Import JDBC Packages: The Import statements tell the Java compiler where to find the classes you reference in your code and are placed at the very beginning of your source code. To use the standard JDBC package, which allows you to select, insert, update, and delete data in SQL tables, add the following imports to your source code: import java.sql.* ; // for standard JDBC programs import java.math.* ; // for BigDecimal and BigInteger support Register JDBC Driver: You must register the your driver in your program before you use it. Registering the driver is the process by which the Oracle driver's class file is loaded into memory so it can be utilized as an implementation of the JDBC interfaces. You need to do this registration only once in your program. You can register a driver in one of two ways.
Limited Access for Syntel Employees only
212
Approach (I) - Class.forName(): The most common approach to register a driver is to use Java's Class.forName() method to dynamically load the driver's class file into memory, which automatically registers it. This method is preferable because it allows you to make the driver registration configurable and portable. The following example uses Class.forName( ) to register the Oracle driver: try { Class.forName("oracle.jdbc.driver.OracleDriver"); } catch(ClassNotFoundException ex) { System.out.println("Error: unable to load driver class!"); System.exit(1); } You can use getInstance() method to work around noncompliant JVMs, but then you'll have to code for two extra Exceptions as follows: try { Class.forName("oracle.jdbc.driver.OracleDriver").newInstance(); } catch(ClassNotFoundException ex) { System.out.println("Error: unable to load driver class!"); System.exit(1); catch(IllegalAccessException ex) { System.out.println("Error: access problem while loading!"); System.exit(2); catch(InstantiationException ex) { System.out.println("Error: unable to instantiate driver!"); System.exit(3); }
213
Approach (II) - DriverManager.registerDriver(): The second approach you can use to register a driver is to use the static DriverManager.registerDriver() method. You should use the registerDriver() method if you are using a non-JDK compliant JVM, such as the one provided by Microsoft. The following example uses registerDriver() to register the Oracle driver: try { Driver myDriver = new oracle.jdbc.driver.OracleDriver(); DriverManager.registerDriver( myDriver ); } catch(ClassNotFoundException ex) { System.out.println("Error: unable to load driver class!"); System.exit(1); } Database URL Formulation: After you've loaded the driver, you can establish a connection using the DriverManager.getConnection() method. For easy reference, let me list the three overloaded DriverManager.getConnection() methods:
getConnection(String url) getConnection(String url, Properties prop) getConnection(String url, String user, String password)
Here each form requires a database URL. A database URL is an address that points to your database. Formulating a database URL is where most of the problems associated with establishing a connection occur. Following table lists down popular JDBC driver names and database URL. RDBMS JDBC driver name URL format
214
MySQL
com.mysql.jdbc.Driver
ORACLE oracle.jdbc.driver.OracleDriver
DB2
COM.ibm.db2.jdbc.net.DB2Driver
Sybase
com.sybase.jdbc.SybDriver
All the highlighted part in URL format is static and you need to change only remaining part as per your database setup.
Create Connection Object: Using a database URL with a username and password: I listed down three forms of DriverManager.getConnection() method to create a connection object. The most commonly used form of getConnection() requires you to pass a database URL, a username, and a password: Assuming you are using Oracle's thin driver, you'll specify a host:port:databaseName value for the database portion of the URL. If you have a host at TCP/IP address 192.0.0.1 with a host name of amrood, and your Oracle listener is configured to listen on port 1521, and your database name is EMP, then complete database URL would then be: jdbc:oracle:thin:@localhost:1521:orcl Now you have to call getConnection() method with appropriate username and password to get a Connection object as follows: String URL = " jdbc:oracle:thin:@localhost:1521:orcl"; String USER = "scott"; String PASS = "syntel123$" Connection conn = DriverManager.getConnection(URL, USER, PASS);
Limited Access for Syntel Employees only
215
Using only a database URL: A second form of the DriverManager.getConnection( ) method requires only a database URL: DriverManager.getConnection(String url); However, in this case, the database URL includes the username and password and has the following general form: jdbc:oracle:driver:username/password@database So the above connection can be created as follows: String URL = " jdbc:oracle:thin:@localhost:1521:orcl "; Connection conn = DriverManager.getConnection(URL); Using a database URL and a Properties object: A third form of the DriverManager.getConnection( ) method requires a database URL and a Properties object: DriverManager.getConnection(String url, Properties info); A Properties object holds a set of keyword-value pairs. It's used to pass driver properties to the driver during a call to the getConnection() method. To make the same connection made by the previous examples, use the following code: import java.util.*;
String URL = " jdbc:oracle:thin:@localhost:1521:orcl "; Properties info = new Properties( ); info.put( "user", "username" ); info.put( "password", "password" );
216
Connection conn = DriverManager.getConnection(URL, info); Closing JDBC connections: At the end of your JDBC program, it is required explicitly close all the connections to the database to end each database session. However, if you forget, Java's garbage collector will close the connection when it cleans up stale objects. Relying on garbage collection, especially in database programming, is very poor programming practice. You should make a habit of always closing the connection with the close() method associated with connection object. To ensure that a connection is closed, you could provide a finally block in your code. A finally block always executes, regardless if an exception occurs or not. To close above opened connection you should call close() method as follows: conn.close(); Explicitly closing a connection conserves DBMS resources, which will make your database administrator happy.
Once a connection is obtained we can interact with the database. The JDBC Statement, CallableStatement, and PreparedStatement interfaces define the methods and properties that enable you to send SQL or PL/SQL commands and receive data from your database. They also define methods that help bridge data type differences between Java and SQL data types used in a database. Following table provides a summary of each interface's purpose to understand how do you decide which interface to use? Interfaces Recommended Use Use for general-purpose access to your database. Useful when you are using static SQL statements at runtime. The Statement interface cannot accept parameters. Use when you plan to use the SQL statements many times. The PreparedStatement interface accepts input parameters at runtime.
Statement
PreparedStatement
217
CallableStatement
Use when you want to access database stored procedures. The CallableStatement interface can also accept runtime input parameters.
Creating Statement Object: Before you can use a Statement object to execute a SQL statement, you need to create one using the Connection object's createStatement( ) method, as in the following example: Statement stmt = null; try { stmt = conn.createStatement( ); ... } catch (SQLException e) { ... } finally { ... } Once you've created a Statement object, you can then use it to execute a SQL statement with one of its three execute methods.
boolean execute(String SQL) : Returns a boolean value of true if a ResultSet object can be retrieved; otherwise, it returns false. Use this method to execute SQL DDL statements or when you need to use truly dynamic SQL. int executeUpdate(String SQL) : Returns the numbers of rows affected by the execution of the SQL statement. Use this method to execute SQL statements for which you expect to get a number of rows affected - for example, an INSERT, UPDATE, or DELETE statement.
218
ResultSet executeQuery(String SQL) : Returns a ResultSet object. Use this method when you expect to get a result set, as you would with a SELECT statement.
Closing Statement Obeject: Just as you close a Connection object to save database resources, for the same reason you should also close the Statement object. A simple call to the close() method will do the job. If you close the Connection object first it will close the Statement object as well. However, you should always explicitly close the Statement object to ensure proper cleanup. Statement stmt = null; try { stmt = conn.createStatement( ); ... } catch (SQLException e) { ... } finally { stmt.close(); } For a better understanding, I would suggest to study Statement - Example Code. The PreparedStatement Objects: The PreparedStatement interface extends the Statement interface which gives you added functionality with a couple of advantages over a generic Statement object. This statement gives you the flexibility of supplying arguments dynamically. Creating PreparedStatement Object: PreparedStatement pstmt = null; try { String SQL = "Update Employees SET age = ? WHERE id = ?";
Limited Access for Syntel Employees only
219
pstmt = conn.prepareStatement(SQL); ... } catch (SQLException e) { ... } finally { ... } All parameters in JDBC are represented by the ? symbol, which is known as the parameter marker. You must supply values for every parameter before executing the SQL statement. The setXXX() methods bind values to the parameters, where XXX represents the Java data type of the value you wish to bind to the input parameter. If you forget to supply the values, you will receive an SQLException. Each parameter marker is referred to by its ordinal position. The first marker represents position 1, the next position 2, and so forth. This method differs from that of Java array indices, which start at 0. All of the Statement object's methods for interacting with the database (a) execute(), (b) executeQuery(), and (c) executeUpdate() also work with the PreparedStatement object. However, the methods are modified to use SQL statements that can take input the parameters. Closing PreparedStatement Obeject: Just as you close a Statement object, for the same reason you should also close the PreparedStatement object. A simple call to the close() method will do the job. If you close the Connection object first it will close the PreparedStatement object as well. However, you should always explicitly close the PreparedStatement object to ensure proper cleanup. PreparedStatement pstmt = null; try { String SQL = "Update Employees SET age = ? WHERE id = ?";
Limited Access for Syntel Employees only
220
pstmt = conn.prepareStatement(SQL); ... } catch (SQLException e) { ... } finally { pstmt.close(); } For a better understanding, I would suggest to study Prepare - Example Code. The CallableStatement Objects: Just as a Connection object creates the Statement and PreparedStatement objects, it also creates the CallableStatement object which would be used to execute a call to a database stored procedure. Three types of parameters exist: IN, OUT, and INOUT. The PreparedStatement object only uses the IN parameter. The CallableStatement object can use all three. Here are the definitions of each: Parameter Description A parameter whose value is unknown when the SQL statement is created. You bind values to IN parameters with the setXXX() methods. A parameter whose value is supplied by the SQL statement it returns. You retrieve values from theOUT parameters with the getXXX() methods. A parameter that provides both input and output values. You bind variables with the setXXX() methods and retrieve values with the getXXX() methods.
IN
OUT
INOUT
The String variable SQL represents the stored procedure, with parameter placeholders.
Limited Access for Syntel Employees only
221
Using CallableStatement objects is much like using PreparedStatement objects. You must bind values to all parameters before executing the statement, or you will receive an SQLException. If you have IN parameters, just follow the same rules and techniques that apply to a PreparedStatement object; use the setXXX() method that corresponds to the Java data type you are binding. When you use OUT and INOUT parameters you must employ an additional CallableStatement method, registerOutParameter(). The registerOutParameter() method binds the JDBC data type to the data type the stored procedure is expected to return. Once you call your stored procedure, you retrieve the value from the OUT parameter with the appropriate getXXX() method. This method casts the retrieved value of SQL type to a Java data type. Closing CallableStatement Obeject: Just as you close other Statement object, for the same reason you should also close the CallableStatement object. A simple call to the close() method will do the job. If you close the Connection object first it will close the CallableStatement object as well. However, you should always explicitly close the CallableStatement object to ensure proper cleanup. CallableStatement cstmt = null; try { String SQL = "{call getEmpName (?, ?)}"; cstmt = conn.prepareCall (SQL); ... } catch (SQLException e) { ... } finally { cstmt.close(); }
222
The SQL statements that read data from a database query return the data in a result set. The SELECT statement is the standard way to select rows from a database and view them in a result set. The java.sql.ResultSet interface represents the result set of a database query. A ResultSet object maintains a cursor that points to the current row in the result set. The term "result set" refers to the row and column data contained in a ResultSet object. The methods of the ResultSet interface can be broken down into three categories:
Navigational methods: used to move the cursor around. Get methods: used to view the data in the columns of the current row being pointed to by the cursor. Update methods: used to update the data in the columns of the current row. The updates can then be updated in the underlying database as well.
The cursor is movable based on the properties of the ResultSet. These properties are designated when the corresponding Statement that generated the ResultSet is created. JDBC provides following connection methods to create statements with desired ResultSet:
createStatement(int RSType, int RSConcurrency); prepareStatement(String SQL, int RSType, int RSConcurrency); prepareCall(String sql, int RSType, int RSConcurrency);
The first argument indicate the type of a ResultSet object and the second argument is one of two ResultSet constants for specifying whether a result set is read-only or updatable. Type of ResultSet: The possible RSType are given below, If you do not specify any ResultSet type, you will automatically get one that is TYPE_FORWARD_ONLY. Type Description The cursor can only move forward in the result set.
ResultSet.TYPE_FORWARD_ONLY
223
The cursor can scroll forwards and backwards, and the result set is not sensitive ResultSet.TYPE_SCROLL_INSENSITIVE to changes made by others to the database that occur after the result set was created. The cursor can scroll forwards and backwards, and the result set is sensitive to changes made by others to the database that occur after the result set was created.
ResultSet.TYPE_SCROLL_SENSITIVE.
Concurrency of ResultSet: The possible RSConcurrency are given below, If you do not specify any Concurrency type, you will automatically get one that is CONCUR_READ_ONLY. Concurrency Description
ResultSet.CONCUR_READ_ONLY Creates a read-only result set. This is the default ResultSet.CONCUR_UPDATABLE Creates an updateable result set.
Our all the examples written so far can be written as follows which initializes a Statement object to create a forward-only, read only ResultSet object: try { Statement stmt = conn.createStatement( ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY); } catch(Exception ex) { .... } finally {
Limited Access for Syntel Employees only
224
.... }
Navigating a Result Set: There are several methods in the ResultSet interface that involve moving the cursor, including: S.N. Methods & Description public void beforeFirst() Moves the cursor to just before the first row public void afterLast() Moves the cursor to just after the last row public boolean Moves the cursor to the first row first() throws SQLException
throws
SQLException
throws
SQLException
public void last() Moves the cursor to the last row. public boolean absolute(int Moves the cursor to the specified row row)
throws
SQLException
throws
SQLException
public boolean relative(int row) throws SQLException Moves the cursor the given number of rows forward or backwards from where it currently is pointing. public boolean previous() throws SQLException Moves the cursor to the previous row. This method returns false if the previous row is off the result set public boolean next() throws SQLException Moves the cursor to the next row. This method returns false if there are no more rows in the result set
225
public int getRow() throws Returns the row number that the cursor is pointing to.
SQLException
10
public void moveToInsertRow() throws SQLException Moves the cursor to a special row in the result set that can be used to insert a new row into the database. The current cursor location is remembered. public void moveToCurrentRow() throws SQLException Moves the cursor back to the current row if the cursor is currently at the insert row; otherwise, this method does nothing
11
For a better understanding, I would suggest to study Navigate - Example Code. Viewing a Result Set: The ResultSet interface contains dozens of methods for getting the data of the current row. There is a get method for each of the possible data types, and each get method has two versions:
One that takes in a column name. One that takes in a column index.
For example, if the column you are interested in viewing contains an int, you need to use one of the getInt() methods of ResultSet: S.N. Methods & Description public int getInt(String columnName) throws SQLException Returns the int in the current row in the column named columnName public int getInt(int columnIndex) throws SQLException Returns the int in the current row in the specified column index. The column index starts at 1, meaning the first column of a row is 1, the second column of a row is 2, and so on.
Similarly there are get methods in the ResultSet interface for each of the eight Java primitive types, as well as common types such as java.lang.String, java.lang.Object, and java.net.URL
Limited Access for Syntel Employees only
226
There are also methods for getting SQL data types java.sql.Date, java.sql.Time, java.sql.TimeStamp, java.sql.Clob, and java.sql.Blob. Check the documentation for more information about using these SQL data types. For a better understanding, I would suggest to study Viewing - Example Code. Updating a Result Set: The ResultSet interface contains a collection of update methods for updating the data of a result set. As with the get methods, there are two update methods for each data type:
One that takes in a column name. One that takes in a column index.
For example, to update a String column of the current row of a result set, you would use one of the following updateString() methods: S.N. Methods & Description public void updateString(int columnIndex, String s) throws SQLException Changes the String in the specified column to the value of s. public void updateString(String columnName, String s) throws SQLException Similar to the previous method, except that the column is specified by its name instead of its index.
There are update methods for the eight primitive data types, as well as String, Object, URL, and the SQL data types in the java.sql package. Updating a row in the result set changes the columns of the current row in the ResultSet object, but not in the underlying database. To update your changes to the row in the database, you need to invoke one of the following methods. S.N. Methods & Description public void updateRow() Updates the current row by updating the corresponding row in the database.
227
deleteRow()
public void refreshRow() Refreshes the data in the result set to reflect any recent changes in the database. public void Cancels any updates made on the current row. cancelRowUpdates()
public void insertRow() Inserts a row into the database. This method can only be invoked when the cursor is pointing to the insert row.
The JDBC driver converts the Java data type to the appropriate JDBC type before sending it to the database. It uses a default mapping for most data types. For example, a Java int is converted to an SQL INTEGER. Default mappings were created to provide consistency between drivers. The following table summarizes the default JDBC data type that the Java data type is converted to when you call the setXXX() method of the PreparedStatement or CallableStatement object or the ResultSet.updateXXX() method. SQL VARCHAR CHAR LONGVARCHAR BIT NUMERIC TINYINT JDBC/Java java.lang.String java.lang.String java.lang.String boolean setXXX setString setString setString setBoolean updateXXX updateString updateString updateString updateBoolean updateBigDecimal updateByte
228
SMALLINT INTEGER BIGINT REAL FLOAT DOUBLE VARBINARY BINARY DATE TIME TIMESTAMP CLOB BLOB ARRAY REF STRUCT
short int long float float double byte[ ] byte[ ] java.sql.Date java.sql.Time java.sql.Timestamp java.sql.Clob java.sql.Blob java.sql.Array java.sql.Ref java.sql.Struct
setShort setInt setLong setFloat setFloat setDouble setBytes setBytes setDate setTime setTimestamp setClob setBlob setARRAY SetRef SetStruct
updateShort updateInt updateLong updateFloat updateFloat updateDouble updateBytes updateBytes updateDate updateTime updateTimestamp updateClob updateBlob updateARRAY updateRef updateStruct
JDBC 3.0 has enhanced support for BLOB, CLOB, ARRAY, and REF data types. The ResultSet object now has updateBLOB(), updateCLOB(), updateArray(), and updateRef() methods that enable you to directly manipulate the respective data on the server.
Limited Access for Syntel Employees only
229
The setXXX() and updateXXX() methods enable you to convert specific Java types to specific JDBC data types. The methods, setObject() and updateObject(), enable you to map almost any Java type to a JDBC data type. ResultSet object provides corresponding getXXX() method for each data type to retrieve column value. Each method can be used with column name or by its ordinal position. SQL VARCHAR CHAR LONGVARCHAR BIT NUMERIC TINYINT SMALLINT INTEGER BIGINT REAL FLOAT DOUBLE VARBINARY JDBC/Java java.lang.String java.lang.String java.lang.String boolean setXXX setString setString setString setBoolean getXXX getString getString getString getBoolean getBigDecimal getByte getShort getInt getLong getFloat getFloat getDouble getBytes
java.math.BigDecimal setBigDecimal byte short int long float float double byte[ ] setByte setShort setInt setLong setFloat setFloat setDouble setBytes
230
Date & Time Data Types: The java.sql.Date class maps to the SQL DATE type, and the java.sql.Time and java.sql.Timestamp classes map to the SQL TIME and SQL TIMESTAMP data types, respectively. Following examples shows how the Date and Time classes format standard Java date and time values to match the SQL data type requirements. import java.sql.Date; import java.sql.Time; import java.sql.Timestamp; import java.util.*;
public class SqlDateTime { public static void main(String[] args) { //Get standard date and time
Limited Access for Syntel Employees only
231
java.util.Date javaDate = new java.util.Date(); long javaTime = javaDate.getTime(); System.out.println("The Java Date is:" + javaDate.toString());
//Get and display SQL DATE java.sql.Date sqlDate = new java.sql.Date(javaTime); System.out.println("The SQL DATE is: " + sqlDate.toString());
//Get and display SQL TIME java.sql.Time sqlTime = new java.sql.Time(javaTime); System.out.println("The SQL TIME is: " + sqlTime.toString()); //Get and display SQL TIMESTAMP java.sql.Timestamp sqlTimestamp = new java.sql.Timestamp(javaTime); System.out.println("The SQL TIMESTAMP is: " + sqlTimestamp.toString()); }//end main }//end SqlDateTime Now let us compile above example as follows: C:\>javac SqlDateTime.java C:\> When you run JDBCExample, it produces following result: C:\>java SqlDateTime The Java Date is:Tue Aug 18 13:46:02 GMT+04:00 2009
Limited Access for Syntel Employees only
232
The SQL DATE is: 2009-08-18 The SQL TIME is: 13:46:02 The SQL TIMESTAMP is: 2009-08-18 13:46:02.828 C:\> SQLException: Exception handling allows you to handle exceptional conditions such as program-defined errors in a controlled fashion. When an exception condition occurs, an exception is thrown. The term thrown means that current program execution stops, and control is redirected to the nearest applicable catch clause. If no applicable catch clause exists, then the program's execution ends. JDBC Exception handling is very similar to Java Excpetion handling but for JDBC, the most common exception you'll deal with is java.sql.SQLException. SQLException Methods: A SQLException can occur both in the driver and the database. When such an exception occurs, an object of type SQLException will be passed to the catch clause. The passed SQLException object has the following methods available for retrieving additional information about the exception: Method Description Gets the error number associated with the exception. Gets the JDBC driver's error message for an error handled by the driver or gets the Oracle error number and message for a database error. Gets the XOPEN SQLstate string. For a JDBC driver error, no useful information is returned from this method. For a database error, the five-digit XOPEN SQLstate code is returned. This method can return null.
getErrorCode( )
getMessage( )
getSQLState( )
233
getNextException( )
Gets the next Exception object in the exception chain. Prints the current exception, or throwable, and its backtrace to a standard error stream. Prints this throwable and its backtrace to the print stream you specify. Prints this throwable and its backtrace to the print writer you specify.
printStackTrace( )
printStackTrace(PrintStream s)
printStackTrace(PrintWriter w)
Batch Processing Batch Processing allows you to group related SQL statements into a batch and submit them with one call to the database. When you send several SQL statements to the database at once, you reduce the amount of communication overhead, thereby improving performance.
JDBC drivers are not required to support this feature. You should use the DatabaseMetaData.supportsBatchUpdates() method to determine if the target database supports batch update processing. The method returns true if your JDBC driver supports this feature. The addBatch() method of Statement, PreparedStatement, and CallableStatement is used to add individual statements to the batch. The executeBatch() is used to start the execution of all the statements grouped together. The executeBatch() returns an array of integers, and each element of the array represents the update count for the respective update statement. Just as you can add statements to a batch for processing, you can remove them with the clearBatch() method. This method removes all the statements you added with the addBatch() method. However, you cannot selectively choose which statement to remove.
234
Batching with Statement Object: Here is a typical sequence of steps to use Batch Processing with Statment Object:
Create a Statement object using either createStatement() methods. Set auto-commit to false using setAutoCommit(). Add as many as SQL statements you like into batch using addBatch() method on created statement object. Execute all the SQL statements using executeBatch() method on created statement object. Finally, commit all the changes using commit() method.
Example: The following code snippet provides an example of a batch update using Statement object: // Create statement object Statement stmt = conn.createStatement();
// Create SQL statement String SQL = "INSERT INTO Employees (id, first, last, age) " + "VALUES(200,'Zia', 'Ali', 30)"; // Add above SQL statement in the batch. stmt.addBatch(SQL);
// Create one more SQL statement String SQL = "INSERT INTO Employees (id, first, last, age) " + "VALUES(201,'Raj', 'Kumar', 35)"; // Add above SQL statement in the batch. stmt.addBatch(SQL);
Limited Access for Syntel Employees only
235
// Create one more SQL statement String SQL = "UPDATE Employees SET age = 35 " + "WHERE id = 100"; // Add above SQL statement in the batch. stmt.addBatch(SQL);
236
Batching with PrepareStatement Object: Here is a typical sequence of steps to use Batch Processing with PrepareStatement Object:
Create SQL statements with placeholders. Create PrepareStatement object using either prepareStatement() methods. Set auto-commit to false using setAutoCommit(). Add as many as SQL statements you like into batch using addBatch() method on created statement object. Execute all the SQL statements using executeBatch() method on created statement object. Finally, commit all the changes using commit() method.
The following code snippet provides an example of a batch update using PrepareStatement object: // Create SQL statement String SQL = "INSERT INTO Employees (id, first, last, age) " + "VALUES(?, ?, ?, ?)";
// Set the variables pstmt.setInt( 1, 400 ); pstmt.setString( 2, "Pappu" ); pstmt.setString( 3, "Singh" ); pstmt.setInt( 4, 33 );
Limited Access for Syntel Employees only
237
// Set the variables pstmt.setInt( 1, 401 ); pstmt.setString( 2, "Pawan" ); pstmt.setString( 3, "Singh" ); pstmt.setInt( 4, 31 ); // Add it to the batch pstmt.addBatch();
//add more batches . . . . //Create an int[] to hold returned values int[] count = stmt.executeBatch();
238