What is spring and Why spring So popular?
spring is open source frame work.
spring is so popular because spring is very loosley coupled, easily maintainable,
less coding, good security etc.
spring components are as follows.
Spring IOC, AOP, ORM, Web, MVC,DAO,spring context
these components are also called as spring modules.
Thursday, March 11, 2010
Tuesday, December 29, 2009
Core Java Tutorial
Java Versions:
JDK 1.0 :
Codename Oak. Initial release.
JDK 1.1 :
• AWT
• inner classes added to the language
• JavaBeans
• JDBC
• RMI
JDK 1.2 :
• strictfp keyword
• reflection which supported Introspection only, no modification at runtime was possible.
• the Swing graphical API was integrated into the core classes
• Sun's JVM was equipped with a JIT compiler for the first time
• Java Plug-in
• Java IDL, an IDL implementation for CORBA interoperability
• Collections framework
JDK 1.3 :
• HotSpot JVM included (the HotSpot JVM was first released in April, 1999 for the J2SE 1.2 JVM)
• RMI was modified to support optional compatibility with CORBA
• JavaSound
• Java Naming and Directory Interface (JNDI) included in core libraries (previously available as an extension)
• Java Platform Debugger Architecture (JPDA)
JDK 1.4 :
• assert keyword (Specified in JSR 41.)
• regular expressions modeled after Perl regular expressions
• exception chaining allows an exception to encapsulate original lower-level exception
• Internet Protocol version 6 (IPv6) support
• non-blocking NIO (New Input/Output) (Specified in JSR 51.)
• logging API (Specified in JSR 47.)
• image I/O API for reading and writing images in formats like JPEG and PNG
• integrated XML parser and XSLT processor (JAXP) (Specified in JSR 5 and JSR 63.)
• integrated security and cryptography extensions (JCE, JSSE, JAAS)
• Java Web Start included (Java Web Start was first released in March, 2001 for J2SE 1.3) (Specified in JSR 56.)
JDK 5.0 :
• Generics: Provides compile-time (static) type safety for collections and eliminates the need for most typecasts (type conversion). (Specified by JSR 14.)
• Metadata: Also called annotations; allows language constructs such as classes and methods to be tagged with additional data, which can then be processed by metadata-aware utilities. (Specified by JSR 175.)
• Autoboxing/unboxing: Automatic conversions between primitive types (such as int) and primitive wrapper classes (such as Integer). (Specified by JSR 201.)
• Enumerations: The enum keyword creates a typesafe, ordered list of values (such as Day.MONDAY, Day.TUESDAY, etc.). Previously this could only be achieved by non-typesafe constant integers or manually constructed classes (typesafe enum pattern). (Specified by JSR 201.)
• Swing: New skinnable look and feel, called synth.
• Varargs: The last parameter of a method can now be declared using a type name followed by three dots (e.g. void drawtext(String... lines)). In the calling code any number of parameters of that type can be used and they are then placed in an array to be passed to the method, or alternatively the calling code can pass an array of that type.
• Enhanced for each loop: The for loop syntax is extended with special syntax for iterating over each member of either an array or any Iterable, such as the standard Collection classes, using a construct of the form:
void displayWidgets (Iterable widgets) {
for (Widget w: widgets) {
w.display();
}
This example iterates over the Iterable object widgets, assigning each of its items in turn to the variable w, and then calling the Widget method display() for each item. (Specified by JSR 201.)
• Fix the previously broken semantics of the Java Memory Model, which defines how threads interact through memory.
• Automatic stub generation for RMI objects.
• static imports
• 1.5.0_18 (5u18) is the last release of Java to officially support the Microsoft Windows 9x line (Windows 95, Windows 98, Windows ME). [1] Unofficially, Java SE 6 Update 7 (1.6.0.7) is the last version of Java to be shown working on this family of operating systems. [2]
• The concurrency utilities in package java.util.concurrent.[11]
• Scanner class for parsing data from various input streams and buffers.
Java SE 6:
1. Improved Web Service support through JAX-WS (JSR 224)
2. JDBC 4.0 support (JSR 221)..
3. Support for pluggable annotations
Java is a programming language originally developed by Sun Microsystems and released in 1995 as a core component of Sun Microsystems' Java platform. The language derives much of its syntax from C and C++ .Java applications are typically compiled to bytecode that can run on any Java virtual machine (JVM) regardless of computer architecture.
Why Java Is Important to the Internet:
In a network, two very broad categories of objects are transmitted between the server and your personal computer: passive information and dynamic, active programs. For example, when you read your e-mail, you are viewing passive data. Even when you download a program, the program's code is still only passive data until you execute it. However, a second type of object can be transmitted to your computer: a dynamic, self-executing program
Java Applets and Applications
An application is a program that runs on your computer.it is Java's ability to create applets that makes it important.An applet is an application designed to be transmitted over the Internet and executed by
a Java-compatible Web browser
Security
Prior to Java, most users did not download executable programs frequently, and those who did scanned them for viruses prior to execution.
When you use a Java-compatible Web browser, you can safely download Java applets without fear of viral infection or malicious intent. Java achieves this protection by Confining a Java program to the Java execution environment and not allowing it access to other parts of the computer.
Portability
many types of computers and operating systems are connected to the Internet. For programs to be
dynamically downloaded to all the various types of platforms connected to the Internet,
some means of generating portable executable code is needed.
Byte Code java’s magic for solve above to problems(security and portability):
The output of a Java compiler is not executable code. Rather, it is bytecode. Bytecode is a highly optimized set of instructions designed to be executed by the Java run-time system, which is called the Java Virtual Machine (JVM). That is, in its standard form, the JVM is an interpreter for bytecode only the JVM needs to be implemented for each platform. Once the run-time package exists for a given system, any Java program can run on it. Remember, although the details of the JVM will differ from
platform to platform, all interpret the same Java bytecode.
The Java Buzzwords
Although the fundamental forces that necessitated the invention of Java are portability
and security, other factors also played an important role
Simple: Java was designed to be easy for the professional programmer to learn and use effectively
Object-oriented
Robust : memory management mistakes and mishandled exceptional conditions
Multithreaded: Java supports multithreaded programming, which allows you to write programs that do many things simultaneously
Architecture-neutral : there was no garantee today programs run and tomorrow also run in same manner. Java achieved.
• Interpreted & High performance: Java enables the creation of cross-platform programs by compiling into an intermediate representation called Java bytecode. This code can be interpreted
on any system that provides a Java Virtual Machine
java was designed to perform well on very low-power CPUs.
• Distributed: Java is designed for the distributed environment of the Internet, because it handles
TCP/IP protocols.
• Dynamic: Java programs carry with them substantial amounts of run-time type information that is
used to verify and resolve accesses to objects at run time.
process-oriented model: a program can be conceptually organized around its code then code is acting on data,
Object-oriented programming: a program can be conceptually organized around its data.
The four OOP Principles:
Abstraction: Humans manage complexity through abstraction. Hiding inner details of system how its been working internally. Only explore the essentials details to end user. Ex car-breaks-engine etc.
Java Example : Any application that defines a Class that is used to instantiate objects is one that demonstrates abstraction.
Encapsulation: Encapsulation is the mechanism that binds together code and the data it manipulates, and keeps both safe from outside interference and misuse.
Java Example:
class Box {
// what are the properties or fields
private int length,width,height;
public setters for above all.
public int displayVolume()
{return (length*width*height);}
}
class BoxVol {
public static void main (String args[]) {
Box ob1 = new Box();
double vol;
ob1.setLength(120);
ob1.setWidth(100);
ob1.setHeight(90);
vol = ob1.displayVolume();
System.out.println("Volume is : " + vol);
}
}
private keyword use top specifies encapsulated. By keeping your data private(encapsulated)out side entity(other methods and data) can not misuse it or alter it with out your permission. you can only allow them to use it but you will not allow them to alter it.
Inheritance: Inheritance is the process by which one object acquires the properties of another object.
Different kinds of objects often have a certain amount in common with each other.
Object-oriented programming allows classes to inherit commonly used state and behavior from other classes.
Polymorphism: Polymorphism (from the Greek, meaning "many forms") same name with different forms.
Overloaded methods are methods with the same name signature but either a different number of parameters or different types in the parameter list.
Overridden methods are methods that are redefined within an inherited or subclass. They have the same signature and the subclass definition is used.
Polymorphism is the capability of an action or method to do different things based on the object that it is acting upon. This is the third basic principle of object oriented programming. Overloading and overriding are two types of polymorphism . Now we will look at the third type: dynamic method binding.
Covariant Returns: when subclass want to change its overridden method’s return type it should match its inherited vertion exactly.
dynamic method binding, when the compiler can't determine which method implementation to use in advance, the runtime system (JVM) selects the appropriate method at runtime, based on the class of the object
Assume that three subclasses (Cow, Dog and Snake) have been created based on the Animal abstract class, each having their own speak() method.
Notice that although each method reference was to an Animal (but no animal objects exist), the program is able to resolve the correct method related to the subclass object at runtime. This is known as dynamic (or late) method binding.
What is an object?
An object is a software construct that encapsulates data, along with the ability to use or modify and inspect that data, into a software entity.
What is a class?
A class is a blueprint for objects: A class is a collection of data and methods that operate on that data. it defines a type of object according to the data the object can hold and the operations the object can perform.
The Object Class
The Object class is the highest superclass (ie. root class) of Java. All other classes are subclasses (children or descendants) of the Object class. The Object class includes methods such as:
clone() equals() copy(Object src) finalize() getClass()
hashCode() notify() notifyAll() toString() wait()
The equals() method of java.lang.Object acts the same as the == operator; that is, it tests for object identity rather than object equality
If you override equals(), you must override hashCode() as well.
Hash code is not an unique number for an object.If two objects are equals(means ob1.equals(ob2))then these two objects return same hash code.so we have to implement hashcode() of a class in such way that if two objects are equals(that is compared by equal() of that class)then those two objects must return same hash code.
Key facts to remember about comparing variables:
1. The rule is the same for reference variables and primitive variables:
== returns true if the two bit patterns are identical.
2. Primitive variables must use ==; they cannot use the equals() method.
3. For reference variables, == means that both reference variables are referring to the same object.
4.The StringBuffer class has not overridden equals().
5. The String and wrapper classes are final and have overridden equals().
However,it’s important to know that all of the wrapper class’ equals() methods only return true if both the primitive values and the wrapper’s classes are the same.
What It Means if You Don’t Override equals()
There’s a potential limitation lurking here: if you don’t override the
equals() method, you won’t be able to use the object as a key in a hashtable.(ex car and person in hasMap then after some time u r searching for car)
Cloning of Java objects
Parent class of all objects in java is "Object" which contains several important methos. One of them is "clone" which is used to make a copy of object. There are certain things which you should keep in mind while using clone method of Object.
- implement "Cloneable" interface to each class which you want to clone. If a class does not implement "Cloneable" interface, clone method will throw "CloneNotSupportedException". This interface does not contain any methods. It is just a marker interface
Obtain cloned object through super.clone
- if your class only contains primitive attributes or wrappers of primitive attributes or immutable object like String, then you don't need to do anything special inside clone method because clone method automatically makes a copy of primitive data types and immutable objects.
by default clone method makes shallow copy and does not make a Deep copy of object. Deep copy means if your object contains references of other objects or collections, it will not make a copy of those referenced objects and will use same references as was in origianl objects.
In order to do deep copy of Book class, we will aso have to implement "Cloneable" interface in "Publisher" class + override clone method in Publisher class too. If Publisher class contains references of other objects, then you will have to implement Cloneable interface + override clone method in each sub class too.
http://javainnovations.blogspot.com/2008/06/cloning-of-java-objects.html
Perpose of Marker interfaces:
Marker interfaces are also called "tag" interfaces since they tag all the derived classes into a category based on their purpose. For example, all classes that implement the Cloneable interface can be cloned (i.e., the clone() method can be called on them). The Java compiler checks to make sure that if the clone() method is called on a class and the class implements the Cloneable interface. For example, consider the following call to the clone() method on an object o:
SomeObject o = new SomeObject();
SomeObject ref = (SomeObject)(o.clone());
If the class SomeObject does not implement the interface Cloneable (and Cloneable is not implemented by any of the superclasses that SomeObject inherits from), the compiler will mark this line as an error. This is because the clone() method may only be called by objects of type "Cloneable." Hence, even though Cloneable is an empty interface, it serves an important purpose.
------------------------------------------------------------------------------------------------------------------------------
Class Access: access means visibility
Default Access: has no modifier preceding it in the declaration. Think of default access as package-level access, because a class with default access can be seen only by classes within the same package
Public Access: all classes in the Java Universe (JU) have access to a public class. Don't forget, though, that if a public class you're trying to use is in a different package from the class you're writing, you'll still need to import the public class.
Non access Class Modifiers: You can modify a class declaration using the keyword final, abstract, or strictfp. These modifiers are in addition to whatever access control is on the class,
so you could, for example, declare a class as both public and final. But you can't
always mix nonaccess modifiers. You're free to use strictfp in combination with
final, for example, but you must never, ever, ever mark a class as both final and
abstract.
Final Classes When used in a class declaration, the final keyword means the class can't be subclassed
Why class need to make final?
You should make a final class only if you need an absolute guarantee that none of the methods in that class will ever be overridden.
Abstract Classes An abstract class can never be instantiated. Its sole purpose, mission in life, raison d'ĂȘtre, is to be extended (subclassed).
Why class need to make abstract?.
For example, imagine you have a class Car that has generic methods common to all vehicles. But you don't want anyone actually creating a generic, abstract Car object.
Strictfp: The strictfp keyword may be applied to both classes and methods. For classes (and interfaces), it specifies that all of the expressions in all of the methods of the class are FP-strict. For methods, it specifies that all of the expressions in that method are FP-strict.
FP-strict? If you do not specify strictfp then the compiler & runtime system may be more aggressive in how they deal with floating-point expressions. Whereas with strictfp specified, the compiler and runtime system must toe the line very precisely according to the IEEE-754 floating-point specification.
If u mention strictfp : floating-point expressions in your code are fast or predictable in all platforms(consistent across multiple platforms).
-------------------------------------------------------------------------------------
Interface
When you create an interface, you're defining a contract for what a class can do, without saying anything about how the class will do it. An interface is a contract.
• All interface methods are implicitly public and abstract.
• All variables defined in an interface must be public, static, and final(constants)
• Interface methods must not be static.
• Because interface methods are abstract, they cannot be marked final,strictfp, or native.
• An interface can extend one or more other interfaces.
• An interface cannot extend anything but another interface.
• An interface cannot implement another interface or class.
----------------------------------------------------------------------------------------
Access Modifiers: Access modifiers in Java determine the visibility and the scope of the Java elements.
Whereas a class can use just two of the four access control levels (default or public), members can use all four:
n public: Public modifier achieves the highest level of accessibility. When a method or variable member is declared public, it means all other classes, regardless of the package they belong to, can access the member (assuming the class itself is visible).
n protected & n default: The protected and default access control levels are almost identical, but with one critical difference. A default member may be accessed only if the class accessing the member belongs to the same package, whereas a protected member can be accessed (through inheritance) by a subclass even if the subclass is in a different package.
n private: Members marked private can't be accessed by code in any class other than the
class in which the private member was declared
For better understanding, member level access is formulated as a table:
Access Modifier Same Class Same Package Subclass Other packages
public Y Y Y Y
protected Y Y Y N
no modifier Y Y N N
private Y N N N
Nonaccess Member Modifiers:
Final Methods
The final keyword prevents a method from being overridden in a subclass. For example, the Thread
class has a method called isAlive() that checks whether a thread is still active. If you extend the Thread class, though, there is really no way that you can correctly implement this method yourself (it uses native code, for one thing), so the designers have made it final. Just as you can't subclass the String class (because we need to be able to trust in the behavior of a String object), you can't override many of the
methods in the core class libraries.(String class in ‘final)
Final Arguments:
which of course means it can't be modified within the method. In this case, "modified" means reassigning a new value to the variable.
Final Variables
Declaring a variable with the final keyword makes it impossible to reinitialize that
variable once it has been initialized with an explicit value
A reference variable marked final can't ever be reassigned to refer to a different object. The data within
the object can be modified, but the reference variable cannot be changed. In other words, a final reference still allows you to modify the state of the object it refers to, but you can't modify the reference variable to make it refer to a different object.
Abstract Methods
An abstract method is a method that's been declared (as abstract) but not implemented
The first concrete subclass of an abstract class must implement all abstract
methods of the superclass.
It is illegal to have even a single abstract method in a class that is not explicitly
declared abstract
Synchronized Methods
The synchronized keyword indicates that a method can be accessed by only one thread at a time.
Synchrozing is process of control the mothed by access multiple threads at a same time.
Native Methods
The native modifier indicates that a method is implemented in platform-dependent code, that native can be applied only to methods—not classes, not variables, just methods.Note that a native method's body must be a semicolon (;) (like abstract methods),indicating that the implementation is omitted.
Strictfp Methods: same as strictfp class.
Methods with Variable Argument Lists (var-args):
As of 5.0, Java allows you to create methods that can take a variable number of arguments.
arguments The things you specify between the parentheses when you're
invoking a method:
doStuff("a", 2); // invoking doStuff, so a & 2 are arguments
n parameters The things in the method's signature that indicate what the
method must receive when it's invoked:
void doStuff(String s, int a) { }
Rules:1) you must specify the type of the argument(s) this parameter of your method can receive.
2) you follow the type with an ellipsis (...), a space, and then the name of the array that will
hold the parameters received.
3) It's legal to have other parameters in a method that uses a var-arg.
4) The var-arg must be the last parameter in the method's signature, and you only one var-arg in a method.
Constructor Declarations:
Every time you make a new object, at least one constructor is invoked. Every class has a constructor, although if you don't create one explicitly, the compiler will build one for you.
1.
Variable Declarations: There are two types of variables in Java:
Primitives A primitive can be one of eight types:
A reference variable is used to refer to (or access) an object.
Type Bits Bytes min max its Bytes Minimum Range Maximum Range
byte 8 1 -27 27-1
short 16 2 -215 215-1
int 32 4 -231 231-1
long 64 8 -263 263-1
float 32 4 n/a n/a
double 64 8 n/a n/a
Declaring Reference Variables
Reference variables can be declared as static variables, instance variables, method parameters, or local variables.
Instance Variables
Instance variables are defined inside the class, but outside of any method, and are only initialized when the class is instantiated.
Final Variables
Declaring a variable with the final keyword makes it impossible to reinitialize that
variable once it has been initialized with an explicit value
A reference variable marked final can't ever be reassigned to refer to a different object. The data within
the object can be modified, but the reference variable cannot be changed. In other words, a final reference still allows you to modify the state of the object it refers to, but you can't modify the reference variable to make it refer to a different object.
Array Declarations
In Java, arrays are objects that store multiple variables of the same type, or variables that are all subclasses of the same type. Arrays can hold either primitives or object references, but the array itself will always be an object on the heap, even if the array is declared to hold primitive elements. In other words, there is no such thing as a primitive array, but you can make an array of primitives.
Declaring an Array of Primitives
int[] key; // Square brackets before name (recommended)
int key []; // Square brackets after name (legal but less
// readable)
Declaring an Array of Object References
Thread[] threads; // Recommended
Thread threads []; // Legal but less readable
• An array can only hold one type of objects (including primitives).
• Arrays are fixed size.
Transient Variables
If you mark an instance variable as transient, you're telling the JVM to skip (ignore) this variable when you attempt to serialize the object containing it.
Volatile Variables
If you are working with the multi-threaded programming, the volatile keyword will be more useful. When multiple threads using the same variable, each thread will have its own copy of the local cache for that variable. So, when it's updating the value, it is actually updated in the local cache not in the main variable memory. The other thread which is using the same variable doesn't know anything about the values changed by the another thread. To avoid this problem, if you declare a variable as volatile, then it will not be stored in the local cache. Whenever thread are updating the values, it is updated to the main memory. So, other threads can access the updated value.
(or) volatile is used to indicate that a variable's value will be modified by different threads.
the variable is modified asynchronously by concurrently running threads.The volatile keyword is used on variables that may be modified simultaneously by other threads.
Static Variables and Methods
The static modifier is used to create variables and methods that will exist independently of any instances created for the class. In other words, static members exist before you ever make a new instance of a class, and there will be only one copy of the static member regardless of the number of instances of that class.
All static members belong to the class, not to any instance.
Static imports:
Definition: The normal import declaration imports classes from packages, so that they can be used without package reference. Similarly the static import declaration imports static members from classes and allowing them to be used without class reference.
Static blocks: The code in a static block is loaded/executed only once i.e. when the class is first initialized. A class can have any number of static blocks. Static block is not member of a class they do not have a return statement and they cannot be called directly. Cannot contain this or super. They are primarily used to initialize static fields.
Great explanation: http://www.codestyle.org/java/faq-Static.shtml
Declaring Enums : variable restriction
As of 5.0, Java lets you restrict a variable to having one of only a few pre-defined values—in other words, one value from an enumerated list. (The items in the enumerated list are called, surprisingly, enums.)
An enum is NOT a String or an int; an enum constant's type is the enum type. For example, WINTER, SPRING, SUMMER, and FALL
enum constructors can NEVER be invoked directly in code. They are always called automatically when an enum is initialized.
An enum declared outside a class must NOT be marked static, final, abstract, protected, or private.
Stack and Heap:
the various pieces (methods, variables, and objects) of Java programs live in one of two places in memory: the stack or the heap.
• Instance variables and objects live on the heap.
• n Local variables live on the stack.
Autoboxing:
Auto-boxing and Auto-Unboxing enables the primitive types to be converted into respective wrapper objects and the other way around.
Boxing, ==, and equals():
The API developers decided that for all the wrapper classes, two objects are equal if they are of the same type and have the same value. It shouldn't be surprising that
Integer i1 = 1000;
Integer i2 = 1000;
if(i1 != i2) System.out.println("different objects");
if(i1.equals(i2)) System.out.println("meaningfully equal");
Produces the output:
different objects
meaningfully equal
It's just two wrapper objects that happen to have the same value. Because they have the same int value, the equals() method considers them to be "meaningfully equivalent", and therefore returns true. How about this one:
Integer i3 = 10;
Integer i4 = 10;
if(i3 == i4) System.out.println("same object");
if(i3.equals(i4)) System.out.println("meaningfully equal");
This example produces the output:
same object
meaningfully equal
Yikes! The equals() method seems to be working, but what happened with ==
and != ? Why is != telling us that i1 and i2 are different objects, when == is saying
that i3 and i4 are the same object? In order to save memory, two instances of the
following wrapper objects will always be == when their primitive values are the same:
garbage collection :
In computing, garbage collection (also known as GC) is a form of automatic memory management. The garbage collector or collector attempts to reclaim the memory used by objects that will never be accessed again by the application or mutator. Garbage collection was invented by John McCarthy around 1959 to solve the problems of manual memory management in his recently devised Lisp programming language.
There are several basic strategies for garbage collection: reference counting, mark-sweep, mark-compact, and copying.
Forcing Garbage Collection:
System.gc();
Cleaning Up Before Garbage Collection—the finalize() Method:
Every class inherits finalize() method from Object class and method is usually called by the garbage collector when ensures that no more references to the object exist .object class finalize method performs no significant action so normally it is overridden by a java class for clean up code e.g. close a file, closing database connections etc.
The purpose of finalization is to give an unreachable ob
ject the opportunity to perform any cleanup processing before the object is garbage collected.
protected void finalize() throws Throwable {}
break and continue:
The break statement causes the program to stop execution of the innermost looping and start processing the next line of code after the block.
The continue statement causes the program to stop execution of the current iteration(no statements will get execute after countinue statement).control will return to next iteration.
Exceptions:
An exception is an event that occurs during the execution of a program, JVM encounters an abnormal condition, which disturb the normal flow of execution.
Exceptions are of two types:
1. Compiler-enforced exceptions, or checked exceptions
2. Runtime exceptions, or unchecked exceptions
3. Error exceptions
checked exceptions:Compiler-enforced (checked) exceptions are instances of the Exception class or one of its subclasses -- excluding the RuntimeException branch. The compiler expects all checked exceptions to be appropriately handled.
When a method throws a checked exception (e.g., IOException), the client code must handle the exception by either defining a try-caught block or delay the exception handling by propagating the exception event up to a higher level code.
ClassNotFoundException, CloneNotSupportedException, NoSuchFieldException, NoSuchMethodException, IOException, InterruptedException, ParseException
Unchecked exceptions are all exceptions that subclass from java.lang.RuntimeException. Unlike the checked exceptions, when a method throws unchecked exceptions, the client code is not required to define explicit code to handle the exceptions — e.g., NullPointerException.
With an unchecked exception, however, the compiler doesn't force client programmers either to catch the exception or declare it in a throws clause. In fact, client programmers may not even know that the exception could be thrown. eg, StringIndexOutOfBoundsException thrown by String's charAt() method.
ArithmeticException, ArrayIndexOutOfBoundsException, ClassCastException, IllegalArgumentException, IndexOutOfBoundsException, NullPointerException
Error exceptions:
The third kind of exception is the error. These are exceptional conditions that are external to the application, and that the application usually cannot anticipate or recover from. For example, suppose that an application successfully opens a file for input, but is unable to read the file because of a hardware or system malfunction. The unsuccessful read will throw java.io.IOError. An application might choose to catch this exception, in order to notify the user of the problem — but it also might make sense for the program to print a stack trace and exit.
Errors are not subject to the Catch or Specify Requirement. Errors are those exceptions indicated by Error and its subclasses.
Try & catch: Exceptions that are thrown by java runtime systems can be handled by Try and catch blocks.
The finally Block
The finally block always executes when the try block exits. This ensures that the finally block is executed even if an unexpected exception occurs. But finally is useful for more than just exception handling — it allows the programmer to avoid having cleanup code accidentally bypassed by a return, continue, or break. Putting cleanup code in a finally block is always a good practice, even when no exceptions are anticipated.
Throw:
The Throw clause can be used in any part of code where you feel a specific exception needs to be thrown to the calling method.
You can also create your own exception classes to represent problems that can occur within the classes you write. In fact, if you are a package developer, you might have to create your own set of exception classes to allow users to differentiate an error that can occur in your package from errors that occur in the Java platform or other packages.
Throws:
If a method is capable of causing an exception that it does not handle, it must specify this behavior so that callers of the method can guard themselves against that exception. You do this by including a throws clause in the method’s declaration.
Chained Exceptions:
An application often responds to an exception by throwing another exception. In effect, the first exception causes the second exception. It can be very helpful to know when one exception causes another. Chained Exceptions help the programmer do this.
You are trying to read a number from the disk and using it to divide a number. Think the method throws an ArithmeticException because of an attempt to divide by zero (number we got). However, the problem was that an I/O error occurred, which caused the divisor to be set improperly (set to zero). Although the method must certainly throw an ArithmeticException, since that is the error that occurred, you might also want to let the calling code know that the underlying cause was an I/O error. This is the place where chained exceptions come in to picture.
The following are the methods and constructors in Throwable that support chained exceptions.
Throwable getCause()
Throwable initCause(Throwable)
Throwable(String, Throwable)
Throwable(Throwable)
The Throwable argument to initCause and the Throwable constructors is the exception that caused the current exception. getCause returns the exception that caused the current exception, and initCause sets the current exception's cause.
Customizing and Writing your Own
If you've derived your own classes from other libraries, making your own exceptions is fairly straightforward. We'll begin by creating the exception classes used in the previous example:
public class MyCheckedException extends Exception{
//It can also extend RuntimeException if you need it to be unchecked
}
Consequently, you also have access to features of the Exception class. Such as an error message. You can write your own constructor and pass whatever error message you want to it, creating your own personal error messages for effective error reporting and debugging. You can even pass the constructor another Throwable such as a RuntimeException or other Exception that caused this error in the first place. The implications of this will be covered in a future article, but this data can be abstracted by other functions to give a more accurate picture of what caused the problem.
public class MyCheckedException extends Exception{
public MyCheckedException(String msg){
super(msg);
}
public MyCheckedException(String msg, Throwable t){
super(msg,t);
}
}
Rethrowing an exception
Sometimes you’ll want to rethrow the exception that you just caught, particularly when you use Exception to catch any exception. Since you already have the reference to the current exception, you can simply rethrow that reference:
catch(Exception e) {
System.err.println("An exception was thrown");
throw e;
}
Rethrowing an exception causes it to go to the exception handlers in the next-higher context. Any further catch clauses for the same try block are still ignored. In addition, everything about the exception object is preserved, so the handler at the higher context that catches the specific exception type can extract all the information from that object.
Assertions: Assertions let you test your assumptions during development, but the assertion
code—in effect—evaporates when the program is deployed,
Assertions work quite simply. You always assert that something is true. If it is, no
problem. Code keeps running. But if your assertion turns out to be wrong (false),
then a stop-the-world AssertionError is thrown
Assertions come in two flavors: simple and really simple, as follows:
Really Simple
private void doStuff() {
assert (y > x);
// more code assuming y is greater than x
}
Simple
private void doStuff() {
assert (y > x): "y is " + y " " x is " + x;
// more code assuming y is greater than x
}
The difference between them is that the simple version adds a second expression,
separated from the first (boolean expression) by a colon, that adds a little more
information to the stack trace.
Assertion checking defaults to off at runtime. You should always turn them on.
String Class:
StringBuffer Class: The StringBuffer class should be used when you have to make a lot of modifications to strings of characters.String objects are
immutable, so if you choose to do a lot of manipulations with String objects, you will end up with a lot of abandoned String objects in the String pool. On the other hand, objects of type StringBuffer can be modified over and over again without leaving behind a great effluence of discarded String objects.
StringBuffer sb = new StringBuffer("abc");
sb.append("def");
StringBuffer objects are changeable
Important Methods in the StringBuffer Class:
public synchronized StringBuffer append(String s);
public synchronized StringBuffer insert(int offset, String s);
public synchronized StringBuffer reverse();
public String toString();
Differnces:
String is immutable whereas StringBuffer and StringBuilder can change their values.
The only difference between StringBuffer and StringBuilder is that StringBuilder is unsynchronized whereas StringBuffer is synchronized. So when the application needs to be run only in a single thread then it is better to use StringBuilder. StringBuilder is more efficient than StringBuffer.
java.lang.Math Class:
Wrapper Classes:
There is a wrapper class for every primitive in Java.
Wrapper objects are immutable. Once they have been given a value, that value cannot be
changed.
Creating Wrapper Objects:
Integer i1 = new Integer(42);
Integer i2 = new Integer("42");
The valueOf() Methods: Integer i2 = Integer.valueOf("101011", 2);
Wrapper to primitives:
Integer i2 = new Integer(42); // make a new wrapper object
byte b = i2.byteValue();
double d4 = Double.parseDouble("3.14");
Java Reflection API:
It allows the user to get the complete information about interfaces, classes, constructors, fields and various methods being used.
1)
Class c = Class.forName(args[0]);
Method m[] = c.getDeclaredMethods();
2) Class cls = Class.forName("A");
boolean b1 = cls.isInstance(new Integer(37));
3) Method m = methlist[i];
System.out.println("name = " + m.getName());
// returns method name
4) SOP("decl class = " + m.getDeclaringClass());
// returns class name
5) Class pvec[] = m.getParameterTypes();
//return all parameters types
6) m.getReturnType()
//Returns return type of the method.
7) Constructor ctorlist[] = cls.getDeclaredConstructors();
//Return declared constructor list
8) ct.getDeclaringClass()
//return declaring class
9) Class cls = Class.forName("field1");
Field fieldlist[] = cls.getDeclaredFields();
10) Object retobj = ct.newInstance(arglist);
// Create object
Java Collection Classes
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.
The Collections Framework is made up of a set of interfaces for working with groups of objects. The different interfaces describe the different types of groups.
Benefits of the Java Collections Framework
• Reduces programming effort
• Increases program speed and quality:
• Allows interoperability among unrelated APIs:
• Reduces effort to learn and to use new APIs:
• Reduces effort to design new APIs:
The following list describes the core collection interfaces:
Ordered When a collection is ordered, it means you can iterate through the collection in a specific (not-random) order.
Sorted:a sorted collection means a collection sorted by natural order.
Collection — the root of the collection hierarchy, Some types of collections allow duplicate elements, and others do not. Some are ordered and others are unordered. The Java platform doesn't provide any direct implementations of this interface but provides implementations of more specific subinterfaces, such as Set and List.
A Collection represents a group of objects known as its elements.
int size();
boolean isEmpty();
boolean contains(Object element);
boolean add(E element); //optional
boolean remove(Object element); //optional
Iterator iterator();
// Bulk operations
boolean containsAll(Collection c);
boolean addAll(Collection c); //optional
boolean removeAll(Collection c); //optional
boolean retainAll(Collection c); //optional
void clear(); //optional
List — A List cares about the index so list is an ordered collection (sometimes called a sequence). Lists can contain duplicate elements.
ArrayList: is ordered and unsynchronized collection.Think of this as a growable array. It gives you fast iteration and fast random access. an ArrayList is a variable-length array of object references. That is, an ArrayList can dynamically increase or decrease in size. Array lists are created with an initial size. When this size is exceeded, the collection is automatically enlarged. When objects are removed, the array may be shrunk.
add(o) Appends the specified element to the end of this list.
public void add(int index, E element) : Inserts the specified element at the specified position in this
*list. Shifts the element currently at that position (if any) and any subsequent elements to the right (adds one to their indices).
public E remove(int index): Removes the element at the specified position in this list.
* Shifts any subsequent elements to the left (subtracts one from their indices).
Vector: Synchronized order collection. Vector and ArrayList both uses Array internally as data structure.Null can be added to Vector
public synchronized E firstElement()
public synchronized void addElement(E obj)
public synchronized E lastElement()
public synchronized boolean removeElement(Object obj)
LinkedList: permits all elements (including null),and provided extra methods get,remove,insert an element at the beginning and end of the list. These operations allow linked lists to be used as a stack, queue, or double-ended queue (deque).
Sorted Set
A SortedSet is a Set that maintains its elements in ascending order. Several additional operations are provided to take advantage of the ordering. The SortedSet interface is used for things like word lists and membership rolls.
SortedMap
A SortedMap is a Map that maintains its mappings in ascending key order. It is the Map analogue of SortedSet. The SortedMap interface is used for apps like dictionaries and telephone directories.
Set — a collection that cannot contain duplicate elements.unOrdered collection.
add(E)
,remove(Object)
,containsAll(Collection),
addAll(Collection)
retainAll(Collection),
removeAll(Collection)
HashSet: It makes no guarantees as to the iteration order of the set; in particular, it does not guarantee that the order will remain constant over time. This class permits the null element.
TreeSet: This class guarantees that the sorted set will be in ascending element order, sorted according to the natural order of the elements (see Comparable), or by the comparator provided at set creation time, depending on which constructor is used.
LinkedHashSet: which is the order in which elements were inserted into the set (insertion-order).
Map — an object that maps keys to values. A Map cannot contain duplicate keys;
HashTable: Any non-null object can be used as a key or as a value. To successfully store and retrieve objects from a hashtable, the objects used as keys must implement the hashCode method and the equals method. HashTable is synchronized,
HashMap: permits null values and the null key. (The HashMap class is roughly equivalent to Hashtable, except that it is unsynchronized and permits nulls.) This class makes no guarantees as to the order of the map; in particular, it does not guarantee that the order will remain constant over time.
LinkedHashMap: with predictable iteration order. This implementation differs from HashMap in that it maintains a doubly-linked list running through all of its entries. This linked list defines the iteration ordering, which is normally the order in which keys were inserted into the map (insertion-order).
TreeMap You can probably guess by now that a TreeMap is a sorted Map. And
you already know that this means “sorted by the natural order of the elements
Benefits and constraints of using different data structures.
Array
Benefits
• Data access is fast.
• Good for ordered data, which is not changed or searched frequently. • Inefficient if number of elements grow.
Constraints
• Inefficient if an element to be inserted in middle of collection.
• Provides no special search mechanism.
Linked List
Benefits
• Allows efficient inserts/delete at any location
• Allows arbitrary growth of collection.
• Applying order to the elements is easy.
Constraints
• Slower while accessing elements by index.
• No special search mechanism is provided.
Tree
Benefits
• Easy addition/deletion in middle.
• Allows arbitrary growth.
• A better and efficient search mechanism.
Constraints
• Ordering is peculiar and some comparison mechanism is required.
• Searching is not efficient for unevenly distributed data.
Hashtable
Benefits
• Efficient searching.
• Good access mechanism.
• Allows arbitrary growth of collection.
Constraints
• Not good for small data set because of overheads.
• Overhead for storing keys for the values in collection.
• Overhead of hashing scheme.
Enumeration Interface: The Enumeration interface defines a way to traverse all the members of a collection of objects.
The hasMoreElements() method checks to see if there are more elements and returns a boolean.
If there are more elements, nextElement() will return the next element as an Object.
If there are no more elements when nextElement() is called, the runtime NoSuchElementException will be thrown.
Enumeration e = v.elements();
while (e.hasMoreElements()) {
Object o = e.nextElement();
System.out.println(o);
}
Iterators - Similar to the familiar Enumeration interface, but more powerful, and with improved method names.
Iterator - In addition to the functionality of the Enumeration interface, allows the user to remove elements from the backing collection with well defined, useful semantics.
The Iterator interface has the following methods:
• hasNext.
• next.
• Remove
Iterator i = c.iterator();
while (i.hasNext()) {
System.out.println(i.next());
}
ListIterator - Iterator for use with lists. In addition to the functionality of the Iterator interface, supports bi-directional iteration, element replacement, element insertion and index retrieval.
ListIterator iter = list.listIterator();
• hasNext()
• next()
• hasPrevious()
• previous()
• nextIndex()
• previousIndex()
• remove()
• set(E)
• add(E)
Ordering
Comparable - Imparts a natural ordering to classes that implement it. The natural ordering may be used to sort a list or maintain order in a sorted set or map. Many classes have been retrofitted to implement this interface.
List of objects that implement this interface can be sorted automatically by sort method of the list interface. This interface has compareTo() method that is used by the sort() method of the list.
In this code Employee class is implementing Comparable interface and have method compareTO(). ComparableDemo.java is showing the use of this interface. This class first makes a list of objects of type Employee and call sort method of java.util.Collections, which internally uses compareTo() method of Employee class and sort the list accordingly.
This method compares this object with o1 object. Returned int value has the following meanings.
1. positive – this object is greater than o1
2. zero – this object equals to o1
3. negative – this object is less than o1
java.util.Collections.sort(List) and java.util.Arrays.sort(Object[]) methods can be used to sort using natural ordering of objects.
• Employee.java
public class Employee implements Comparable {
int EmpID;
String Ename;
double Sal;
static int i;
public Employee() {
EmpID = i++;
Ename = "dont know";
Sal = 0.0;
}
public Employee(String ename, double sal) {
EmpID = i++;
Ename = ename;
Sal = sal;
}
public String toString() {
return "EmpID " + EmpID + "\n" + "Ename " + Ename + "\n" + "Sal" + Sal;
}
public int compareTo(Object o1) {
if (this.Sal == ((Employee) o1).Sal)
return 0;
else if ((this.Sal) > ((Employee) o1).Sal)
return 1;
else
return -1;
}
}
• ComparableDemo.java
import java.util.*;
public class ComparableDemo{
public static void main(String[] args) {
List ts1 = new ArrayList();
ts1.add(new Employee ("Tom",40000.00));
ts1.add(new Employee ("Harry",20000.00));
ts1.add(new Employee ("Maggie",50000.00));
ts1.add(new Employee ("Chris",70000.00));
Collections.sort(ts1);
Iterator itr = ts1.iterator();
while(itr.hasNext()){
Object element = itr.next();
System.out.println(element + "\n");
}
}
}
---------------------------------------------------------------------------------------
Comparator - Represents an order relation, which may be used to sort a list or maintain order in a sorted set or map. Can override a type's natural ordering, or order objects of a type that does not implement the Comparable interface.
Sorting by other fields
If we need to sort using other fields of the employee, we’ll have to change the Employee class’s compareTo() method to use those fields. But then we’ll loose this empId based sorting mechanism. This is not a good alternative if we need to sort using different fields at different occasions. But no need to worry; Comparator is there to save us.
By writing a class that implements the java.lang.Comparator interface, you can sort Employees using any field as you wish even without touching the Employee class itself; Employee class does not need to implement java.lang.Comparable or java.lang.Comparator interface.
Sorting by name field
Following EmpSortByName class is used to sort Employee instances according to the name field. In this class, inside the compare() method sorting mechanism is implemented. In compare() method we get two Employee instances and we have to return which object is greater.
public class EmpSortByName implements Comparator{
public int compare(Employee o1, Employee o2) {
return o1.getName().compareTo(o2.getName());
}
}
Watch out: Here, String class’s compareTo() method is used in comparing the name fields (which are Strings).
Now to test this sorting mechanism, you must use the Collections.sort(List, Comparator) method instead of Collections.sort(List) method. Now change the TestEmployeeSort class as follows. See how the EmpSortByName comparator is used inside sort method.
import java.util.*;
public class TestEmployeeSort {
public static void main(String[] args) {
List coll = Util.getEmployees();
//Collections.sort(coll);
//use Comparator implementation
Collections.sort(coll, new EmpSortByName());
printList(coll);
}
private static void printList(List list) {
System.out.println("EmpId\tName\tAge");
for (Employee e: list) {
System.out.println(e.getEmpId() + "\t" + e.getName() + "\t" + e.getAge());
}
}
}
Now the result would be as follows. Check whether the employees are sorted correctly by the name String field. You’ll see that these are sorted alphabetically.
EmpId Name Age
6 Bill 34
4 Clerk 16
5 Frank 28
1 Jorge 19
8 Lee 40
2 Mark 30
3 Michel 10
7 Simp 8
Sorting by empId field
Even the ordering by empId (previously done using Comparable) can be implemented using Comparator; following class
does that.
public class EmpSortByEmpId implements Comparator{
public int compare(Employee o1, Employee o2) {
return o1.getEmpId().compareTo(o2.getEmpId());
}
}
Good website for collections:
http://www.java2s.com/Tutorial/Java/0140__Collections/Catalog0140__Collections.htm
Inner classes: define one class within another.
Inner Classes r 4 types:
• Inner Classes :
A “regular” inner class is declared inside the curly braces of another class, but outside any method or other code block. Can be declared abstract or final,p,p,p,strictfp
gives the inner class access to all of the outer class’ members, including those marked private.
->From code within the enclosing class, you can instantiate the inner class using only the name of the inner class, as follows: MyInner mi = new MyInner();
From code outside the enclosing class’ instance methods, you can instantiate the inner class only by using both the inner and outer class names, and a reference to the outer class as follows:
MyOuter mo = new MyOuter();
MyOuter.MyInner inner = mo.new MyInner();
This usage
class MyInner {
public void seeOuter() {
System.out.println("Outer x is " + x);
System.out.println("Inner class ref is " + this);
System.out.println("Outer class ref is " + MyOuter.this);
}
}
• Method-local Inner Classes
• Anonymous Inner Classes
An anonymous class in Java is a class with no specified name declared and instantiated at the same time. Because it has no name it can only be used once at place of declaration. Anonymous classes are given a name by the compiler and they are treated as local inner classes. This means that anonymous classes can access members of the enclosing class regardless of their access modifiers and they can access final variables declared in the enclosing block of code.
• Static Nested Classes:
Threads: There are two distinct types of multitasking: process-based and thread-based. process-based multitasking is the feature that allows your computer to run two or more programs concurrently.
a program can contain more than one thread, a single program can use multiple threads to perform two or more tasks at once.
To create a new thread, your program will either implement the Runnable interface or extend Thread. Both Runnable and Thread are packaged in java.lang. Thus, they are automatically available to all programs.
There are two ways to create a thread. The first is to declare a class that extends Thread. When the class is instantiated, the thread and object are created together and the object is automatically bound to the thread. By calling the object's start() method, the thread is started and immediately calls the object's run() method. Here is some code to demonstrate this method.
// This class extends Thread
class BasicThread1 extends Thread {
// This method is called when the thread runs
public void run() {
}
}
// Create and start the thread
Thread thread = new BasicThread1();
thread.start();
The second way is to create the thread and supply it an object with a run() method. This object will be permanently associated with the thread. The object's run() method will be invoked when the thread is started. This method of thread creation is useful if you want many threads sharing an object. Here is an example that creates a Runnable object and then creates a thread with the object.
class BasicThread2 implements Runnable {
// This method is called when the thread runs
public void run() {
}
}
// Create the object with the run() method
Runnable runnable = new BasicThread2();
// Create the thread supplying it with the runnable object
Thread thread = new Thread(runnable);
// Start the thread
thread.start();
The Thread Scheduler
The thread scheduler is the part of the JVM that decides which thread should run at any given moment, Any thread in the runnable state can be chosen by the scheduler to be the one and only running thread.
Yielding to other processes
A CPU intensive operation being executed may not allow other threads to be executed for a "large" period of time. To prevent this it can allow other threads to execute by invoking the yield() method. The thread on which yield() is invoked would move from running state to ready state.
For synchronizing a HashMap, you can use Collections.synchronizedMap() which will return a synchronized map for you, which is thread-safe.
Remember, synchronization will cause a performance problem. So, it needs to be used carefully, when really required.
wait(), notify(), and notifyAll() must be called from within a synchronized context! A thread can’t invoke a wait or notify method on an object unless it owns that object’s lock.
Deadlocking can occur when a locked object attempts to access another locked
object that is trying to access the first locked object. In other words, both
threads are waiting for each other’s locks to be released; therefore, the locks
will never be released! ThreadMXBean bean = ManagementFactory.getTreadMXBean();
bean.findMonitorDedlockedThreads(); To find all deadlocked threads.
Synchronized :
Java also offers three ways to define synchronized blocks.
Synchronized Class Method:
class class_name {
static synchronized type method_name() {
statement block
}
}
All the statements in the method become the synchronized block, and the class object is the lock.
Synchronized Instance Method:
class class_name {
synchronized type method_name() {
statement block
}
}
All the statements in the method become the synchronized block, and the instance object is the lock.
Synchronized Statement:
class class_name {
type method_name() {
synchronized (object) {
statement block
}
}
}
All the statements specified in the parentheses of the synchronized statement become the synchronized block, and the object specified in the statement is the lock.
Java applys the synchronization rule by assigning the ownership of the lock's monitor to the threads that are running the synchronized blocks. Here is how it works:
• When a synchronized clock is reached in an execution thread, it will try to gain the ownership of the monitor of the lock object. If another thread owns the lock's monitor, it will wait.
• Once the lock's monitor is free, the waiting thread will become the owner of the lock's monitor, and start to execute the synchronized block.
• Once the synchronized block is executed to the end, the lock's monitor will be freed again.
Note that one program can have many locks and each lock can be associated with many different synchronized blocks. But the synchronization rule only applies between the synchronized block and its associated lock.
For example, the following code defines two synchronized blocks. Both are associated with the same lock, the instance object.
class class_name {
type method_name() {
synchronized (this) {
statement block 1
}
}
synchronized type method_name() {
statement block 2
}
}
Block 1 will never be executed at the same time as block 2.
The following code defines two synchronized blocks. But they are associated with two different locks, one is the class object, and the other is the instance object. Those two synchronized blocks will never wait for each other.
class class_name {
type method_name() {
synchronized (this) {
statement block 1
}
}
static synchronized type method_name() {
statement block 2
}
}
Deadlock:
Deadlocking can occur when a locked object attempts to access another locked object that is trying to access the first locked object. In other words, both threads are waiting for each other’s locks to be released; therefore, the locks will never be released!
Observer and Observable
How are Observer and Observable usedObjects that subclass the Observable class maintain a list of observers. When anObservable object is updated it invokes the update() method of each of its observers to notify the observers that it has changed state. The Observer interface is implemented by objects that observe Observable objects.
Annotations in Java 5.0
Annotations are generally a way to add meta-data information to a java element (an element can be a class, method, field, or anything) and these meta-data are processed by the tools (compilers, javadoc, etc.). Annotations are differentiated from other elements like class, interface etc., by preceding an '@' symbol before it.
Consider the following class definition,
Employee. java
final class Employee
{
private String name;
private String id;
// Getters and setters for Employee class.
}
The above is a definition of a class, Employee. It can be noted that the class declaration is preceded with the final keyword which tells that this class cannot be sub-classed. So, the introduction of the final keyword adds some additional information (or adds some constraints) over the class definition telling that no other class in the word can extend the Employee class. Therefore, the final keyword forms a part in providing meta-data information in the class definition. So, this is one variation of Annotation.
Annotations can be applied to a program's declarations of classes, fields, methods, and other program elements.
Annotations Used by the Compiler
There are three annotation types that are predefined by the language specification itself: @Deprecated, @Override, and @SuppressWarnings.
@Deprecated—the @Deprecated annotation indicates that the marked element is deprecated and should no longer be used. The compiler generates a warning whenever a program uses a method, class, or field with the @Deprecated annotation. When an element is deprecated, it should also be documented using the Javadoc @deprecated tag, as shown in the following example. The use of the "@" symbol in both Javadoc comments and in annotations is not coincidental—they are related conceptually. Also, note that the Javadoc tag starts with a lowercase "d" and the annotation starts with an uppercase "D".
// Javadoc comment follows
/**
* @deprecated
* explanation of why it was deprecated
*/
@Deprecated
static void deprecatedMethod() { }
}
@Override—the @Override annotation informs the compiler that the element is meant to override an element declared in a superclass (overriding methods will be discussed in the the lesson titled "Interfaces and Inheritance").
// mark method as a superclass method
// that has been overridden
@Override
int overriddenMethod() { }
While it's not required to use this annotation when overriding a method, it helps to prevent errors. If a method marked with @Override fails to correctly override a method in one of its superclasses, the compiler generates an error.
@SuppressWarnings—the @SuppressWarnings annotation tells the compiler to suppress specific warnings that it would otherwise generate. In the example below, a deprecated method is used and the compiler would normally generate a warning. In this case, however, the annotation causes the warning to be suppressed.
// use a deprecated method and tell
// compiler not to generate a warning
@SuppressWarnings("deprecation")
void useDeprecatedMethod() {
objectOne.deprecatedMethod(); //deprecation warning - suppressed
}
Every compiler warning belongs to a category. The Java Language Specification lists two categories: "deprecation" and "unchecked." The "unchecked" warning can occur when interfacing with legacy code written before the advent of generics (discussed in the lesson titled "Generics"). To suppress more than one category of warnings, use the following syntax:
@SuppressWarnings({"unchecked", "deprecation"})
Serialization
Serialization is the process of saving an object's state to a sequence of bytes; deserialization is the process of rebuilding those bytes into a live object.
The Java Serialization API provides a standard mechanism for developers to handle object serialization.
Why is serialization required?
In today's world, a typical enterprise application will have multiple components and will be distributed across various systems and networks. In Java, everything is represented as objects; if two Java components want to communicate with each other, there needs be a mechanism to exchange data. One way to achieve this is to define your own protocol and transfer an object. This means that the receiving end must know the protocol used by the sender to re-create the object, which would make it very difficult to talk to third-party components. Hence, there needs to be a generic and efficient protocol to transfer the object between components. Serialization is defined for this purpose, and Java components use this protocol to transfer objects.
How to serialize an object
In order to serialize an object, you need to ensure that the class of the object implements the java.io.Serializable interface, as shown in Listing 1.
Listing 1. Implementing Serializable
import java.io.Serializable;
class TestSerial implements Serializable {
public byte version = 100;
public byte count = 0;
}
In Listing 1, the only thing you had to do differently from creating a normal class is implement the java.io.Serializable interface. The Serializable interface is a marker interface; it declares no methods at all. It tells the serialization mechanism that the class can be serialized.
Now that you have made the class eligible for serialization, the next step is to actually serialize the object. That is done by calling the writeObject() method of the java.io.ObjectOutputStream class, as shown in Listing 2.
Listing 2. Calling writeObject()
public static void main(String args[]) throws IOException {
FileOutputStream fos = new FileOutputStream("temp.out");
ObjectOutputStream oos = new ObjectOutputStream(fos);
TestSerial ts = new TestSerial();
oos.writeObject(ts);
oos.flush();
oos.close();
}
Three ways to customize serialization
– mark sensitive fields as transient
– implement Serializable and override
readObject() and writeObject()
– implement Externalizable and override
writeExternal() and readExternal()
public class SalesEntry implements Serializable {
private void writeObject(ObjectOutputStream out) throws IOException {
// Write all fields that are not transient or static,
// including those in base classes.
out.defaultWriteObject();
// Write transient field baseSalary as an encrypted String.
out.writeUTF(MyEncrypter.encryptInt(baseSalary));
}
private void readObject(ObjectInputStream in) throws IOException {
// Read all fields that are not transient or static
// including those in base classes.
in.defaultReadObject();
// Read transient field baseSalary from an encrypted String.
baseSalary = MyEncrypter.decryptInt(in.readUTF());
}
}
writeExternal() &readExternal()
public class SalesEntry implements Externalizable {
// A public no-arg constructor is required by
// Externalizable.readExternal.
public SalesEntry() {
}
// Method in the Externalizable interface.
public void writeExternal(ObjectOutput out) throws IOException {
// Can't use ObjectOutputStream.defaultWriteObject().
// If base class fields require serialization
// then code to perform that must be supplied here.
out.writeUTF(name);
out.writeObject(date); // use for objects and arrays
out.writeFloat(sales);
out.writeUTF(MyEncrypter.encryptInt(baseSalary));
}
// Method in the Externalizable interface.
public void readExternal(ObjectInput in) throws IOException,
ClassNotFoundException {
// Can't use ObjectInputStream.defaultReadObject().
// If base class fields require deserialization
// then code to perform that must be supplied here.
name = in.readUTF();
date = (Date) in.readObject(); // use for objects and arrays
sales = in.readFloat();
baseSalary = MyEncrypter.decryptInt(in.readUTF());
}
}
JDBC Programming:
The JDBC ( Java Database Connectivity) API defines interfaces and classes for writing database applications in Java by making database connections. Using JDBC you can send SQL, PL/SQL statements to almost any relational database.
JDBC Steps :
1.Loading a database driver: In this step of the jdbc connection process, we load the driver class by calling Class.forName() with the Driver class name as an argument. Class.forName(”sun.jdbc.odbc.JdbcOdbcDriver”);
2. Creating a oracle jdbc Connection: The JDBC DriverManager class defines objects which can connect Java applications to a JDBC driver.
Its getConnection() method is used to establish a connection to a database. It uses a username, password, and a jdbc url to establish a connection to the database and returns a connection object.
Connection dbConnection=DriverManager.getConnection(url,”loginName”,”Password”)
3. Creating a jdbc Statement object: Once a connection is obtained we can interact with the database. Connection interface defines methods for interacting with the database via the established connection. To execute SQL statements, you need to instantiate a Statement object from your connection object by using the createStatement() method.
Statement statement = dbConnection.createStatement();
A statement object is used to send and execute SQL statements to a database.
Three kinds of Statements
Statement: Execute simple sql queries without parameters.
Statement createStatement()
Creates an SQL Statement object.
Prepared Statement: Execute precompiled sql queries with or without parameters.
PreparedStatement prepareStatement(String sql)
returns a new PreparedStatement object. PreparedStatement objects are precompiled
SQL statements.
An example of a PreparedStatement object is
PreparedStatement pstmt = con.prepareStatement(”update Orders set pname = ? where Prod_Id = ?”);
pstmt.setInt(2, 100);
pstmt.setString(1, “Bob”);
pstmt.executeUpdate();
Callable Statement: Execute a call to a database stored procedure.
CallableStatement prepareCall(String sql)
returns a new CallableStatement object. CallableStatement objects are SQL stored procedure call statements.
4. Executing a SQL statement with the Statement object, and returning a jdbc resultSet.
Statement interface defines methods that are used to interact with database via the execution of SQL statements. The Statement class has three methods for executing statements:
executeQuery(), executeUpdate(), and execute(). For a SELECT statement, the method to use is executeQuery . For statements that create or modify tables, the method to use is executeUpdate. Note: Statements that create a table, alter a table, or drop a table are all examples of DDL
statements and are executed with the method executeUpdate. execute() executes an SQL
statement that is written as String object.
ResultSet provides access to a table of data generated by executing a Statement. The table rows are retrieved in sequence. A ResultSet maintains a cursor pointing to its current row of data. The next() method is used to successively step through the rows of the tabular results.
A cursor can be thought of as a pointer to the rows of the result set that has the ability to keep track of which row is currently being accessed. The JDBC API supports a cursor to move both forward and backward and also allowing it to move to a specified row or to a row whose position is relative to another row.
Types of ResultSets :
The sensitivity of the ResultSet object is determined by one of three different ResultSet types:
• TYPE_FORWARD_ONLY — the result set is not scrollable i.e. the cursor moves only forward, from before the first row to after the last row.
• TYPE_SCROLL_INSENSITIVE — the result set is scrollable; its cursor can move both forward and backward relative to the current position,
and it can move to an absolute position.
• TYPE_SCROLL_SENSITIVE — the result set is scrollable; its cursor can move both forward and backward relative to the current position, and it can move to an absolute position.
Statement stmt = con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,
ResultSet.CONCUR_READ_ONLY);
ResultSet srs = stmt.executeQuery(”…..”);
The first argument is one of three constants added to the ResultSet API to indicate the type of a ResultSet object: TYPE_FORWARD_ONLY, TYPE_SCROLL_INSENSITIVE, and TYPE_SCROLL_SENSITIVE. The second argument is one of two ResultSet constants for specifying whether a result set is read-only or updatable: CONCUR_READ_ONLY and CONCUR_UPDATABLE. If you do not specify any constants for the type and updatability of a ResultSet object, you will automatically get one that is TYPE_FORWARD_ONLY and CONCUR_READ_ONLY.
• next() - moves the cursor forward one row. Returns true if the cursor is now positioned on a row and false if the cursor is positioned after the last row.
• previous() - moves the cursor backwards one row. Returns true if the cursor is now positioned on a row and false if the cursor is positioned before the first row.
• first() - moves the cursor to the first row in the ResultSet object. Returns true if the cursor is now positioned on the first row and false if the ResultSet object
does not contain any rows.
• last() - moves the cursor to the last row in the ResultSet object. Returns true if the cursor is now positioned on the last row and false if the ResultSet object
does not contain any rows.
• beforeFirst() - positions the cursor at the start of the ResultSet object, before the first row. If the ResultSet object does not contain any rows, this method has
no effect.
• afterLast() - positions the cursor at the end of the ResultSet object, after the last row. If the ResultSet object does not contain any rows, this method has no effect.
• relative(int rows) - moves the cursor relative to its current position.
• absolute(int n) - positions the cursor on the n-th row of the ResultSet object.
ResultSetMetaData Interface holds information on the types and properties of the columns in a ResultSet. It is constructed from the Connection object.
Types Of Drivers : There are four types
A).JDBC-ODBC Bridge Driver(Bridge):
The Type 1 driver translates all JDBC calls into ODBC calls and sends them to the ODBC driver. ODBC is a generic API. The JDBC-ODBC Bridge driver is recommended only for experimental use or when no other alter native is available.
Advantage :
The JDBC-ODBC Bridge allows access to almost any database, since the database’s ODBC drivers are already available.
Disadvantages
1. Since the Bridge driver is not written fully in Java, Type 1 drivers are not portable.
2. A performance issue is seen as a JDBC call goes through the bridge to the ODBC driver, then to the database, and this applies even in the reverse process. They are the slowest of all driver types.
3. The client system requires the ODBC Installation to use the driver.
4. Not good for the Web.
b. Native API Partly Java Driver(Native)
The distinctive characteristic of type 2 jdbc drivers are that Type 2 drivers convert JDBC calls into database-specific calls i.e. this driver is specific to a particular database. Some distinctive characteristic of type 2 jdbc drivers are shown below. Example: Oracle will have oracle native api.
Advantage
The distinctive characteristic of type 2 jdbc drivers are that they are typically offer better performance than the JDBC-ODBC Bridge as the layers of communication (tiers) are less than that of Type
1 and also it uses Native api which is Database specific.
Disadvantage
1. Native API must be installed in the Client System and hence type 2 drivers cannot be used for the Internet.
2. Like Type 1 drivers, it’s not written in Java Language which forms a portability issue.
3. If we change the Database we have to change the native api as it is specific to a database
4. Mostly obsolete now
5. Usually not thread safe.
c. Net protocol pure Java Driver(Middleware)
Type 3 database requests are passed through the network to the middle-tier server. The middle-tier then translates the request to the database. If the middle-tier server can in turn use Type1, Type 2 or Type 4 drivers.
Advantage
1. This driver is server-based, so there is no need for any vendor database library to be present on client machines.
2. This driver is fully written in Java and hence Portable. It is suitable for the web.
3. There are many opportunities to optimize portability, performance, and scalability.
4. The net protocol can be designed to make the client JDBC driver very small and fast to load.
5. The type 3 driver typically provides support for features such as caching (connections, query results, and so on), load balancing, and advanced
system administration such as logging and auditing.
6. This driver is very flexible allows access to multiple databases using one driver.
7. They are the most efficient amongst all driver types.
Disadvantage
It requires another server application to install and maintain. Traversing the recordset may take longer, since the data comes through the backend server.
d. Native protocol Pure Java Driver(pure)
The Type 4 uses java networking libraries to communicate directly with the database server.
Advantage
1. The major benefit of using a type 4 jdbc drivers are that they are completely written in Java to achieve platform independence and eliminate deployment administration issues. It is most suitable for the web.
2. Number of translation layers is very less i.e. type 4 JDBC drivers don’t have to translate database requests to ODBC or a native connectivity interface or to pass the request on to another server, performance is typically quite good.
3. You don’t need to install special software on the client or server. Further, these drivers can be downloaded dynamically.
Disadvantage
With type 4 drivers, the user needs a different driver for each database.
When we create an instace of a class using new operator, it does two things
1. Load the class in to memory, if it is not loaded -
which means creating in-memory representation of the class from the .class file so that an instance can be created out of it. This includes initializing static variables (resolving of that class)
2. create an instance of that class and store the reference to the variable.
Class.forName does only the first thing.
It loads the class in to memory and return that reference as an instance of Class. If we want to create an instance then, we can call newInstance method of that class. which will invoke the default constructor (no argument constructor).
Note that if the default constructor is not accessible, then newInstance method will throw an IllegalAccessException. and if the class is an abstract class or interface or it does not have a default constructor, then it will throw an InstantiationException. If any exception araises during resolving of that class, it will throw an ExceptionInInitializerError.
If the default constructor is not defined, then we have to invoke the defiend constructor using reflection API.
But the main advantage with Class.forName is, it can accept the class name as a String argument. So we can pass the class name dynamically. But if we create an instance of a class using new operator, the class name can't be changed dynamically.
Class.forName() in turn will call loadClass method of the caller ClassLoader (ClassLoder of the class from where Class.forName is invoked).
By default, the Class.forName() resolve that class. which means, initialize all static variables inside that class.
same can be changed using the overloaded method of Class.forName(String name,boolean initialize,ClassLoader loader)
The main reason for loading jdbc driver using Class.forName() is, the driver can change dynamically.
in the static block all Drivers will create an instance of itself and register that class with DriverManager using DriverManager.registerDriver() method. Since the Class.forName(String className) by default resolve the class, it will initialize the static initializer.
So when we call Class.forName("com.sun.jdbc.odbc.JdbcOdbcDriver"),
the Driver class will be loaded, instanciated and registers with DriverManager
So if you are using new Operator you have to do the following things.
Driver drv = new com.sun.jdbc.odbc.JdbcOdbcDriver();
DriverManager.registerDriver(drv);
Design patterns: a design pattern is a template for software development. The purpose of the template is to define a particular behavior or technique that can be used as a building block for the construction of software - to solve universal problems that commonly face developers.
Singleton Design Pattern
Restriction to a class to have one and only one instance. This way the developer can ensure as well as can control how an object is instantiated and can prevent others from creating or copying multiple instances of the class.
Purpose: The main purpose is that if we have to use a resource then we can create a singleton class which can only access the resource and by making this instance available to other threads or any part of the application we can make sure that unnecessary objects are not getting created for accessing the resource.
Another purpose is that we have some utility classes which are being used by other java classes to do some calculations etc. Now if we make the utility class a singleton class then all objects and all parts of the application can use this one instance of the utility class and no extra instaces are required. There are lots of other uses also.
public class SingletonObject
{
private SingletonObject()
{
// no code req'd
}
public static SingletonObject getSingletonObject()
{
if (ref == null)
// it's ok, we can call this constructor
ref = new SingletonObject();
return ref;
}
private static SingletonObject ref;
}
Preventing thread problems with your singleton
public static synchronized
SingletonObject getSingletonObject()
Here's where most articles on singletons fall down, because they forget about cloning. Examine the following code snippet, which clones a singleton object.
public class Clone
{
public static void main(String args[])
throws Exception
{
// Get a singleton
SingletonObject obj =
SingletonObject.getSingletonObject();
// Buahahaha. Let's clone the object
SingletonObject clone =
(SingletonObject) obj.clone();
}
}
Okay, we're cheating a little here. There isn't a clone() method defined in SingletonObject, but there is in the java.lang.Object class which it is inherited from. By default, the clone() method is marked as protected, but if your SingletonObject extends another class that does support cloning, it is possible to violate the design principles of the singleton. So, to be absolutely positively 100% certain that a singleton really is a singleton, we must add a clone() method of our own, and throw a CloneNotSupportedException if anyone dares try!
Here's the final source code for a SingletonObject, which you can use as a template for your own singletons.
public class SingletonObject
{
private SingletonObject()
{
// no code req'd
}
public static SingletonObject getSingletonObject()
{
if (ref == null)
// it's ok, we can call this constructor
ref = new SingletonObject();
return ref;
}
public Object clone()
throws CloneNotSupportedException
{
throw new CloneNotSupportedException();
// that'll teach 'em
}
private static SingletonObject ref;
}
Some other design patterens
Proxy Design Pattern
Decorator
Factory
Composite view
Adopter/Inverter
JDK 1.0 :
Codename Oak. Initial release.
JDK 1.1 :
• AWT
• inner classes added to the language
• JavaBeans
• JDBC
• RMI
JDK 1.2 :
• strictfp keyword
• reflection which supported Introspection only, no modification at runtime was possible.
• the Swing graphical API was integrated into the core classes
• Sun's JVM was equipped with a JIT compiler for the first time
• Java Plug-in
• Java IDL, an IDL implementation for CORBA interoperability
• Collections framework
JDK 1.3 :
• HotSpot JVM included (the HotSpot JVM was first released in April, 1999 for the J2SE 1.2 JVM)
• RMI was modified to support optional compatibility with CORBA
• JavaSound
• Java Naming and Directory Interface (JNDI) included in core libraries (previously available as an extension)
• Java Platform Debugger Architecture (JPDA)
JDK 1.4 :
• assert keyword (Specified in JSR 41.)
• regular expressions modeled after Perl regular expressions
• exception chaining allows an exception to encapsulate original lower-level exception
• Internet Protocol version 6 (IPv6) support
• non-blocking NIO (New Input/Output) (Specified in JSR 51.)
• logging API (Specified in JSR 47.)
• image I/O API for reading and writing images in formats like JPEG and PNG
• integrated XML parser and XSLT processor (JAXP) (Specified in JSR 5 and JSR 63.)
• integrated security and cryptography extensions (JCE, JSSE, JAAS)
• Java Web Start included (Java Web Start was first released in March, 2001 for J2SE 1.3) (Specified in JSR 56.)
JDK 5.0 :
• Generics: Provides compile-time (static) type safety for collections and eliminates the need for most typecasts (type conversion). (Specified by JSR 14.)
• Metadata: Also called annotations; allows language constructs such as classes and methods to be tagged with additional data, which can then be processed by metadata-aware utilities. (Specified by JSR 175.)
• Autoboxing/unboxing: Automatic conversions between primitive types (such as int) and primitive wrapper classes (such as Integer). (Specified by JSR 201.)
• Enumerations: The enum keyword creates a typesafe, ordered list of values (such as Day.MONDAY, Day.TUESDAY, etc.). Previously this could only be achieved by non-typesafe constant integers or manually constructed classes (typesafe enum pattern). (Specified by JSR 201.)
• Swing: New skinnable look and feel, called synth.
• Varargs: The last parameter of a method can now be declared using a type name followed by three dots (e.g. void drawtext(String... lines)). In the calling code any number of parameters of that type can be used and they are then placed in an array to be passed to the method, or alternatively the calling code can pass an array of that type.
• Enhanced for each loop: The for loop syntax is extended with special syntax for iterating over each member of either an array or any Iterable, such as the standard Collection classes, using a construct of the form:
void displayWidgets (Iterable
for (Widget w: widgets) {
w.display();
}
This example iterates over the Iterable object widgets, assigning each of its items in turn to the variable w, and then calling the Widget method display() for each item. (Specified by JSR 201.)
• Fix the previously broken semantics of the Java Memory Model, which defines how threads interact through memory.
• Automatic stub generation for RMI objects.
• static imports
• 1.5.0_18 (5u18) is the last release of Java to officially support the Microsoft Windows 9x line (Windows 95, Windows 98, Windows ME). [1] Unofficially, Java SE 6 Update 7 (1.6.0.7) is the last version of Java to be shown working on this family of operating systems. [2]
• The concurrency utilities in package java.util.concurrent.[11]
• Scanner class for parsing data from various input streams and buffers.
Java SE 6:
1. Improved Web Service support through JAX-WS (JSR 224)
2. JDBC 4.0 support (JSR 221)..
3. Support for pluggable annotations
Java is a programming language originally developed by Sun Microsystems and released in 1995 as a core component of Sun Microsystems' Java platform. The language derives much of its syntax from C and C++ .Java applications are typically compiled to bytecode that can run on any Java virtual machine (JVM) regardless of computer architecture.
Why Java Is Important to the Internet:
In a network, two very broad categories of objects are transmitted between the server and your personal computer: passive information and dynamic, active programs. For example, when you read your e-mail, you are viewing passive data. Even when you download a program, the program's code is still only passive data until you execute it. However, a second type of object can be transmitted to your computer: a dynamic, self-executing program
Java Applets and Applications
An application is a program that runs on your computer.it is Java's ability to create applets that makes it important.An applet is an application designed to be transmitted over the Internet and executed by
a Java-compatible Web browser
Security
Prior to Java, most users did not download executable programs frequently, and those who did scanned them for viruses prior to execution.
When you use a Java-compatible Web browser, you can safely download Java applets without fear of viral infection or malicious intent. Java achieves this protection by Confining a Java program to the Java execution environment and not allowing it access to other parts of the computer.
Portability
many types of computers and operating systems are connected to the Internet. For programs to be
dynamically downloaded to all the various types of platforms connected to the Internet,
some means of generating portable executable code is needed.
Byte Code java’s magic for solve above to problems(security and portability):
The output of a Java compiler is not executable code. Rather, it is bytecode. Bytecode is a highly optimized set of instructions designed to be executed by the Java run-time system, which is called the Java Virtual Machine (JVM). That is, in its standard form, the JVM is an interpreter for bytecode only the JVM needs to be implemented for each platform. Once the run-time package exists for a given system, any Java program can run on it. Remember, although the details of the JVM will differ from
platform to platform, all interpret the same Java bytecode.
The Java Buzzwords
Although the fundamental forces that necessitated the invention of Java are portability
and security, other factors also played an important role
Simple: Java was designed to be easy for the professional programmer to learn and use effectively
Object-oriented
Robust : memory management mistakes and mishandled exceptional conditions
Multithreaded: Java supports multithreaded programming, which allows you to write programs that do many things simultaneously
Architecture-neutral : there was no garantee today programs run and tomorrow also run in same manner. Java achieved.
• Interpreted & High performance: Java enables the creation of cross-platform programs by compiling into an intermediate representation called Java bytecode. This code can be interpreted
on any system that provides a Java Virtual Machine
java was designed to perform well on very low-power CPUs.
• Distributed: Java is designed for the distributed environment of the Internet, because it handles
TCP/IP protocols.
• Dynamic: Java programs carry with them substantial amounts of run-time type information that is
used to verify and resolve accesses to objects at run time.
process-oriented model: a program can be conceptually organized around its code then code is acting on data,
Object-oriented programming: a program can be conceptually organized around its data.
The four OOP Principles:
Abstraction: Humans manage complexity through abstraction. Hiding inner details of system how its been working internally. Only explore the essentials details to end user. Ex car-breaks-engine etc.
Java Example : Any application that defines a Class that is used to instantiate objects is one that demonstrates abstraction.
Encapsulation: Encapsulation is the mechanism that binds together code and the data it manipulates, and keeps both safe from outside interference and misuse.
Java Example:
class Box {
// what are the properties or fields
private int length,width,height;
public setters for above all.
public int displayVolume()
{return (length*width*height);}
}
class BoxVol {
public static void main (String args[]) {
Box ob1 = new Box();
double vol;
ob1.setLength(120);
ob1.setWidth(100);
ob1.setHeight(90);
vol = ob1.displayVolume();
System.out.println("Volume is : " + vol);
}
}
private keyword use top specifies encapsulated. By keeping your data private(encapsulated)out side entity(other methods and data) can not misuse it or alter it with out your permission. you can only allow them to use it but you will not allow them to alter it.
Inheritance: Inheritance is the process by which one object acquires the properties of another object.
Different kinds of objects often have a certain amount in common with each other.
Object-oriented programming allows classes to inherit commonly used state and behavior from other classes.
Polymorphism: Polymorphism (from the Greek, meaning "many forms") same name with different forms.
Overloaded methods are methods with the same name signature but either a different number of parameters or different types in the parameter list.
Overridden methods are methods that are redefined within an inherited or subclass. They have the same signature and the subclass definition is used.
Polymorphism is the capability of an action or method to do different things based on the object that it is acting upon. This is the third basic principle of object oriented programming. Overloading and overriding are two types of polymorphism . Now we will look at the third type: dynamic method binding.
Covariant Returns: when subclass want to change its overridden method’s return type it should match its inherited vertion exactly.
dynamic method binding, when the compiler can't determine which method implementation to use in advance, the runtime system (JVM) selects the appropriate method at runtime, based on the class of the object
Assume that three subclasses (Cow, Dog and Snake) have been created based on the Animal abstract class, each having their own speak() method.
Notice that although each method reference was to an Animal (but no animal objects exist), the program is able to resolve the correct method related to the subclass object at runtime. This is known as dynamic (or late) method binding.
What is an object?
An object is a software construct that encapsulates data, along with the ability to use or modify and inspect that data, into a software entity.
What is a class?
A class is a blueprint for objects: A class is a collection of data and methods that operate on that data. it defines a type of object according to the data the object can hold and the operations the object can perform.
The Object Class
The Object class is the highest superclass (ie. root class) of Java. All other classes are subclasses (children or descendants) of the Object class. The Object class includes methods such as:
clone() equals() copy(Object src) finalize() getClass()
hashCode() notify() notifyAll() toString() wait()
The equals() method of java.lang.Object acts the same as the == operator; that is, it tests for object identity rather than object equality
If you override equals(), you must override hashCode() as well.
Hash code is not an unique number for an object.If two objects are equals(means ob1.equals(ob2))then these two objects return same hash code.so we have to implement hashcode() of a class in such way that if two objects are equals(that is compared by equal() of that class)then those two objects must return same hash code.
Key facts to remember about comparing variables:
1. The rule is the same for reference variables and primitive variables:
== returns true if the two bit patterns are identical.
2. Primitive variables must use ==; they cannot use the equals() method.
3. For reference variables, == means that both reference variables are referring to the same object.
4.The StringBuffer class has not overridden equals().
5. The String and wrapper classes are final and have overridden equals().
However,it’s important to know that all of the wrapper class’ equals() methods only return true if both the primitive values and the wrapper’s classes are the same.
What It Means if You Don’t Override equals()
There’s a potential limitation lurking here: if you don’t override the
equals() method, you won’t be able to use the object as a key in a hashtable.(ex car and person in hasMap then after some time u r searching for car)
Cloning of Java objects
Parent class of all objects in java is "Object" which contains several important methos. One of them is "clone" which is used to make a copy of object. There are certain things which you should keep in mind while using clone method of Object.
- implement "Cloneable" interface to each class which you want to clone. If a class does not implement "Cloneable" interface, clone method will throw "CloneNotSupportedException". This interface does not contain any methods. It is just a marker interface
Obtain cloned object through super.clone
- if your class only contains primitive attributes or wrappers of primitive attributes or immutable object like String, then you don't need to do anything special inside clone method because clone method automatically makes a copy of primitive data types and immutable objects.
by default clone method makes shallow copy and does not make a Deep copy of object. Deep copy means if your object contains references of other objects or collections, it will not make a copy of those referenced objects and will use same references as was in origianl objects.
In order to do deep copy of Book class, we will aso have to implement "Cloneable" interface in "Publisher" class + override clone method in Publisher class too. If Publisher class contains references of other objects, then you will have to implement Cloneable interface + override clone method in each sub class too.
http://javainnovations.blogspot.com/2008/06/cloning-of-java-objects.html
Perpose of Marker interfaces:
Marker interfaces are also called "tag" interfaces since they tag all the derived classes into a category based on their purpose. For example, all classes that implement the Cloneable interface can be cloned (i.e., the clone() method can be called on them). The Java compiler checks to make sure that if the clone() method is called on a class and the class implements the Cloneable interface. For example, consider the following call to the clone() method on an object o:
SomeObject o = new SomeObject();
SomeObject ref = (SomeObject)(o.clone());
If the class SomeObject does not implement the interface Cloneable (and Cloneable is not implemented by any of the superclasses that SomeObject inherits from), the compiler will mark this line as an error. This is because the clone() method may only be called by objects of type "Cloneable." Hence, even though Cloneable is an empty interface, it serves an important purpose.
------------------------------------------------------------------------------------------------------------------------------
Class Access: access means visibility
Default Access: has no modifier preceding it in the declaration. Think of default access as package-level access, because a class with default access can be seen only by classes within the same package
Public Access: all classes in the Java Universe (JU) have access to a public class. Don't forget, though, that if a public class you're trying to use is in a different package from the class you're writing, you'll still need to import the public class.
Non access Class Modifiers: You can modify a class declaration using the keyword final, abstract, or strictfp. These modifiers are in addition to whatever access control is on the class,
so you could, for example, declare a class as both public and final. But you can't
always mix nonaccess modifiers. You're free to use strictfp in combination with
final, for example, but you must never, ever, ever mark a class as both final and
abstract.
Final Classes When used in a class declaration, the final keyword means the class can't be subclassed
Why class need to make final?
You should make a final class only if you need an absolute guarantee that none of the methods in that class will ever be overridden.
Abstract Classes An abstract class can never be instantiated. Its sole purpose, mission in life, raison d'ĂȘtre, is to be extended (subclassed).
Why class need to make abstract?.
For example, imagine you have a class Car that has generic methods common to all vehicles. But you don't want anyone actually creating a generic, abstract Car object.
Strictfp: The strictfp keyword may be applied to both classes and methods. For classes (and interfaces), it specifies that all of the expressions in all of the methods of the class are FP-strict. For methods, it specifies that all of the expressions in that method are FP-strict.
FP-strict? If you do not specify strictfp then the compiler & runtime system may be more aggressive in how they deal with floating-point expressions. Whereas with strictfp specified, the compiler and runtime system must toe the line very precisely according to the IEEE-754 floating-point specification.
If u mention strictfp : floating-point expressions in your code are fast or predictable in all platforms(consistent across multiple platforms).
-------------------------------------------------------------------------------------
Interface
When you create an interface, you're defining a contract for what a class can do, without saying anything about how the class will do it. An interface is a contract.
• All interface methods are implicitly public and abstract.
• All variables defined in an interface must be public, static, and final(constants)
• Interface methods must not be static.
• Because interface methods are abstract, they cannot be marked final,strictfp, or native.
• An interface can extend one or more other interfaces.
• An interface cannot extend anything but another interface.
• An interface cannot implement another interface or class.
----------------------------------------------------------------------------------------
Access Modifiers: Access modifiers in Java determine the visibility and the scope of the Java elements.
Whereas a class can use just two of the four access control levels (default or public), members can use all four:
n public: Public modifier achieves the highest level of accessibility. When a method or variable member is declared public, it means all other classes, regardless of the package they belong to, can access the member (assuming the class itself is visible).
n protected & n default: The protected and default access control levels are almost identical, but with one critical difference. A default member may be accessed only if the class accessing the member belongs to the same package, whereas a protected member can be accessed (through inheritance) by a subclass even if the subclass is in a different package.
n private: Members marked private can't be accessed by code in any class other than the
class in which the private member was declared
For better understanding, member level access is formulated as a table:
Access Modifier Same Class Same Package Subclass Other packages
public Y Y Y Y
protected Y Y Y N
no modifier Y Y N N
private Y N N N
Nonaccess Member Modifiers:
Final Methods
The final keyword prevents a method from being overridden in a subclass. For example, the Thread
class has a method called isAlive() that checks whether a thread is still active. If you extend the Thread class, though, there is really no way that you can correctly implement this method yourself (it uses native code, for one thing), so the designers have made it final. Just as you can't subclass the String class (because we need to be able to trust in the behavior of a String object), you can't override many of the
methods in the core class libraries.(String class in ‘final)
Final Arguments:
which of course means it can't be modified within the method. In this case, "modified" means reassigning a new value to the variable.
Final Variables
Declaring a variable with the final keyword makes it impossible to reinitialize that
variable once it has been initialized with an explicit value
A reference variable marked final can't ever be reassigned to refer to a different object. The data within
the object can be modified, but the reference variable cannot be changed. In other words, a final reference still allows you to modify the state of the object it refers to, but you can't modify the reference variable to make it refer to a different object.
Abstract Methods
An abstract method is a method that's been declared (as abstract) but not implemented
The first concrete subclass of an abstract class must implement all abstract
methods of the superclass.
It is illegal to have even a single abstract method in a class that is not explicitly
declared abstract
Synchronized Methods
The synchronized keyword indicates that a method can be accessed by only one thread at a time.
Synchrozing is process of control the mothed by access multiple threads at a same time.
Native Methods
The native modifier indicates that a method is implemented in platform-dependent code, that native can be applied only to methods—not classes, not variables, just methods.Note that a native method's body must be a semicolon (;) (like abstract methods),indicating that the implementation is omitted.
Strictfp Methods: same as strictfp class.
Methods with Variable Argument Lists (var-args):
As of 5.0, Java allows you to create methods that can take a variable number of arguments.
arguments The things you specify between the parentheses when you're
invoking a method:
doStuff("a", 2); // invoking doStuff, so a & 2 are arguments
n parameters The things in the method's signature that indicate what the
method must receive when it's invoked:
void doStuff(String s, int a) { }
Rules:1) you must specify the type of the argument(s) this parameter of your method can receive.
2) you follow the type with an ellipsis (...), a space, and then the name of the array that will
hold the parameters received.
3) It's legal to have other parameters in a method that uses a var-arg.
4) The var-arg must be the last parameter in the method's signature, and you only one var-arg in a method.
Constructor Declarations:
Every time you make a new object, at least one constructor is invoked. Every class has a constructor, although if you don't create one explicitly, the compiler will build one for you.
1.
Variable Declarations: There are two types of variables in Java:
Primitives A primitive can be one of eight types:
A reference variable is used to refer to (or access) an object.
Type Bits Bytes min max its Bytes Minimum Range Maximum Range
byte 8 1 -27 27-1
short 16 2 -215 215-1
int 32 4 -231 231-1
long 64 8 -263 263-1
float 32 4 n/a n/a
double 64 8 n/a n/a
Declaring Reference Variables
Reference variables can be declared as static variables, instance variables, method parameters, or local variables.
Instance Variables
Instance variables are defined inside the class, but outside of any method, and are only initialized when the class is instantiated.
Final Variables
Declaring a variable with the final keyword makes it impossible to reinitialize that
variable once it has been initialized with an explicit value
A reference variable marked final can't ever be reassigned to refer to a different object. The data within
the object can be modified, but the reference variable cannot be changed. In other words, a final reference still allows you to modify the state of the object it refers to, but you can't modify the reference variable to make it refer to a different object.
Array Declarations
In Java, arrays are objects that store multiple variables of the same type, or variables that are all subclasses of the same type. Arrays can hold either primitives or object references, but the array itself will always be an object on the heap, even if the array is declared to hold primitive elements. In other words, there is no such thing as a primitive array, but you can make an array of primitives.
Declaring an Array of Primitives
int[] key; // Square brackets before name (recommended)
int key []; // Square brackets after name (legal but less
// readable)
Declaring an Array of Object References
Thread[] threads; // Recommended
Thread threads []; // Legal but less readable
• An array can only hold one type of objects (including primitives).
• Arrays are fixed size.
Transient Variables
If you mark an instance variable as transient, you're telling the JVM to skip (ignore) this variable when you attempt to serialize the object containing it.
Volatile Variables
If you are working with the multi-threaded programming, the volatile keyword will be more useful. When multiple threads using the same variable, each thread will have its own copy of the local cache for that variable. So, when it's updating the value, it is actually updated in the local cache not in the main variable memory. The other thread which is using the same variable doesn't know anything about the values changed by the another thread. To avoid this problem, if you declare a variable as volatile, then it will not be stored in the local cache. Whenever thread are updating the values, it is updated to the main memory. So, other threads can access the updated value.
(or) volatile is used to indicate that a variable's value will be modified by different threads.
the variable is modified asynchronously by concurrently running threads.The volatile keyword is used on variables that may be modified simultaneously by other threads.
Static Variables and Methods
The static modifier is used to create variables and methods that will exist independently of any instances created for the class. In other words, static members exist before you ever make a new instance of a class, and there will be only one copy of the static member regardless of the number of instances of that class.
All static members belong to the class, not to any instance.
Static imports:
Definition: The normal import declaration imports classes from packages, so that they can be used without package reference. Similarly the static import declaration imports static members from classes and allowing them to be used without class reference.
Static blocks: The code in a static block is loaded/executed only once i.e. when the class is first initialized. A class can have any number of static blocks. Static block is not member of a class they do not have a return statement and they cannot be called directly. Cannot contain this or super. They are primarily used to initialize static fields.
Great explanation: http://www.codestyle.org/java/faq-Static.shtml
Declaring Enums : variable restriction
As of 5.0, Java lets you restrict a variable to having one of only a few pre-defined values—in other words, one value from an enumerated list. (The items in the enumerated list are called, surprisingly, enums.)
An enum is NOT a String or an int; an enum constant's type is the enum type. For example, WINTER, SPRING, SUMMER, and FALL
enum constructors can NEVER be invoked directly in code. They are always called automatically when an enum is initialized.
An enum declared outside a class must NOT be marked static, final, abstract, protected, or private.
Stack and Heap:
the various pieces (methods, variables, and objects) of Java programs live in one of two places in memory: the stack or the heap.
• Instance variables and objects live on the heap.
• n Local variables live on the stack.
Autoboxing:
Auto-boxing and Auto-Unboxing enables the primitive types to be converted into respective wrapper objects and the other way around.
Boxing, ==, and equals():
The API developers decided that for all the wrapper classes, two objects are equal if they are of the same type and have the same value. It shouldn't be surprising that
Integer i1 = 1000;
Integer i2 = 1000;
if(i1 != i2) System.out.println("different objects");
if(i1.equals(i2)) System.out.println("meaningfully equal");
Produces the output:
different objects
meaningfully equal
It's just two wrapper objects that happen to have the same value. Because they have the same int value, the equals() method considers them to be "meaningfully equivalent", and therefore returns true. How about this one:
Integer i3 = 10;
Integer i4 = 10;
if(i3 == i4) System.out.println("same object");
if(i3.equals(i4)) System.out.println("meaningfully equal");
This example produces the output:
same object
meaningfully equal
Yikes! The equals() method seems to be working, but what happened with ==
and != ? Why is != telling us that i1 and i2 are different objects, when == is saying
that i3 and i4 are the same object? In order to save memory, two instances of the
following wrapper objects will always be == when their primitive values are the same:
garbage collection :
In computing, garbage collection (also known as GC) is a form of automatic memory management. The garbage collector or collector attempts to reclaim the memory used by objects that will never be accessed again by the application or mutator. Garbage collection was invented by John McCarthy around 1959 to solve the problems of manual memory management in his recently devised Lisp programming language.
There are several basic strategies for garbage collection: reference counting, mark-sweep, mark-compact, and copying.
Forcing Garbage Collection:
System.gc();
Cleaning Up Before Garbage Collection—the finalize() Method:
Every class inherits finalize() method from Object class and method is usually called by the garbage collector when ensures that no more references to the object exist .object class finalize method performs no significant action so normally it is overridden by a java class for clean up code e.g. close a file, closing database connections etc.
The purpose of finalization is to give an unreachable ob
ject the opportunity to perform any cleanup processing before the object is garbage collected.
protected void finalize() throws Throwable {}
break and continue:
The break statement causes the program to stop execution of the innermost looping and start processing the next line of code after the block.
The continue statement causes the program to stop execution of the current iteration(no statements will get execute after countinue statement).control will return to next iteration.
Exceptions:
An exception is an event that occurs during the execution of a program, JVM encounters an abnormal condition, which disturb the normal flow of execution.
Exceptions are of two types:
1. Compiler-enforced exceptions, or checked exceptions
2. Runtime exceptions, or unchecked exceptions
3. Error exceptions
checked exceptions:Compiler-enforced (checked) exceptions are instances of the Exception class or one of its subclasses -- excluding the RuntimeException branch. The compiler expects all checked exceptions to be appropriately handled.
When a method throws a checked exception (e.g., IOException), the client code must handle the exception by either defining a try-caught block or delay the exception handling by propagating the exception event up to a higher level code.
ClassNotFoundException, CloneNotSupportedException, NoSuchFieldException, NoSuchMethodException, IOException, InterruptedException, ParseException
Unchecked exceptions are all exceptions that subclass from java.lang.RuntimeException. Unlike the checked exceptions, when a method throws unchecked exceptions, the client code is not required to define explicit code to handle the exceptions — e.g., NullPointerException.
With an unchecked exception, however, the compiler doesn't force client programmers either to catch the exception or declare it in a throws clause. In fact, client programmers may not even know that the exception could be thrown. eg, StringIndexOutOfBoundsException thrown by String's charAt() method.
ArithmeticException, ArrayIndexOutOfBoundsException, ClassCastException, IllegalArgumentException, IndexOutOfBoundsException, NullPointerException
Error exceptions:
The third kind of exception is the error. These are exceptional conditions that are external to the application, and that the application usually cannot anticipate or recover from. For example, suppose that an application successfully opens a file for input, but is unable to read the file because of a hardware or system malfunction. The unsuccessful read will throw java.io.IOError. An application might choose to catch this exception, in order to notify the user of the problem — but it also might make sense for the program to print a stack trace and exit.
Errors are not subject to the Catch or Specify Requirement. Errors are those exceptions indicated by Error and its subclasses.
Try & catch: Exceptions that are thrown by java runtime systems can be handled by Try and catch blocks.
The finally Block
The finally block always executes when the try block exits. This ensures that the finally block is executed even if an unexpected exception occurs. But finally is useful for more than just exception handling — it allows the programmer to avoid having cleanup code accidentally bypassed by a return, continue, or break. Putting cleanup code in a finally block is always a good practice, even when no exceptions are anticipated.
Throw:
The Throw clause can be used in any part of code where you feel a specific exception needs to be thrown to the calling method.
You can also create your own exception classes to represent problems that can occur within the classes you write. In fact, if you are a package developer, you might have to create your own set of exception classes to allow users to differentiate an error that can occur in your package from errors that occur in the Java platform or other packages.
Throws:
If a method is capable of causing an exception that it does not handle, it must specify this behavior so that callers of the method can guard themselves against that exception. You do this by including a throws clause in the method’s declaration.
Chained Exceptions:
An application often responds to an exception by throwing another exception. In effect, the first exception causes the second exception. It can be very helpful to know when one exception causes another. Chained Exceptions help the programmer do this.
You are trying to read a number from the disk and using it to divide a number. Think the method throws an ArithmeticException because of an attempt to divide by zero (number we got). However, the problem was that an I/O error occurred, which caused the divisor to be set improperly (set to zero). Although the method must certainly throw an ArithmeticException, since that is the error that occurred, you might also want to let the calling code know that the underlying cause was an I/O error. This is the place where chained exceptions come in to picture.
The following are the methods and constructors in Throwable that support chained exceptions.
Throwable getCause()
Throwable initCause(Throwable)
Throwable(String, Throwable)
Throwable(Throwable)
The Throwable argument to initCause and the Throwable constructors is the exception that caused the current exception. getCause returns the exception that caused the current exception, and initCause sets the current exception's cause.
Customizing and Writing your Own
If you've derived your own classes from other libraries, making your own exceptions is fairly straightforward. We'll begin by creating the exception classes used in the previous example:
public class MyCheckedException extends Exception{
//It can also extend RuntimeException if you need it to be unchecked
}
Consequently, you also have access to features of the Exception class. Such as an error message. You can write your own constructor and pass whatever error message you want to it, creating your own personal error messages for effective error reporting and debugging. You can even pass the constructor another Throwable such as a RuntimeException or other Exception that caused this error in the first place. The implications of this will be covered in a future article, but this data can be abstracted by other functions to give a more accurate picture of what caused the problem.
public class MyCheckedException extends Exception{
public MyCheckedException(String msg){
super(msg);
}
public MyCheckedException(String msg, Throwable t){
super(msg,t);
}
}
Rethrowing an exception
Sometimes you’ll want to rethrow the exception that you just caught, particularly when you use Exception to catch any exception. Since you already have the reference to the current exception, you can simply rethrow that reference:
catch(Exception e) {
System.err.println("An exception was thrown");
throw e;
}
Rethrowing an exception causes it to go to the exception handlers in the next-higher context. Any further catch clauses for the same try block are still ignored. In addition, everything about the exception object is preserved, so the handler at the higher context that catches the specific exception type can extract all the information from that object.
Assertions: Assertions let you test your assumptions during development, but the assertion
code—in effect—evaporates when the program is deployed,
Assertions work quite simply. You always assert that something is true. If it is, no
problem. Code keeps running. But if your assertion turns out to be wrong (false),
then a stop-the-world AssertionError is thrown
Assertions come in two flavors: simple and really simple, as follows:
Really Simple
private void doStuff() {
assert (y > x);
// more code assuming y is greater than x
}
Simple
private void doStuff() {
assert (y > x): "y is " + y " " x is " + x;
// more code assuming y is greater than x
}
The difference between them is that the simple version adds a second expression,
separated from the first (boolean expression) by a colon, that adds a little more
information to the stack trace.
Assertion checking defaults to off at runtime. You should always turn them on.
String Class:
StringBuffer Class: The StringBuffer class should be used when you have to make a lot of modifications to strings of characters.String objects are
immutable, so if you choose to do a lot of manipulations with String objects, you will end up with a lot of abandoned String objects in the String pool. On the other hand, objects of type StringBuffer can be modified over and over again without leaving behind a great effluence of discarded String objects.
StringBuffer sb = new StringBuffer("abc");
sb.append("def");
StringBuffer objects are changeable
Important Methods in the StringBuffer Class:
public synchronized StringBuffer append(String s);
public synchronized StringBuffer insert(int offset, String s);
public synchronized StringBuffer reverse();
public String toString();
Differnces:
String is immutable whereas StringBuffer and StringBuilder can change their values.
The only difference between StringBuffer and StringBuilder is that StringBuilder is unsynchronized whereas StringBuffer is synchronized. So when the application needs to be run only in a single thread then it is better to use StringBuilder. StringBuilder is more efficient than StringBuffer.
java.lang.Math Class:
Wrapper Classes:
There is a wrapper class for every primitive in Java.
Wrapper objects are immutable. Once they have been given a value, that value cannot be
changed.
Creating Wrapper Objects:
Integer i1 = new Integer(42);
Integer i2 = new Integer("42");
The valueOf() Methods: Integer i2 = Integer.valueOf("101011", 2);
Wrapper to primitives:
Integer i2 = new Integer(42); // make a new wrapper object
byte b = i2.byteValue();
double d4 = Double.parseDouble("3.14");
Java Reflection API:
It allows the user to get the complete information about interfaces, classes, constructors, fields and various methods being used.
1)
Class c = Class.forName(args[0]);
Method m[] = c.getDeclaredMethods();
2) Class cls = Class.forName("A");
boolean b1 = cls.isInstance(new Integer(37));
3) Method m = methlist[i];
System.out.println("name = " + m.getName());
// returns method name
4) SOP("decl class = " + m.getDeclaringClass());
// returns class name
5) Class pvec[] = m.getParameterTypes();
//return all parameters types
6) m.getReturnType()
//Returns return type of the method.
7) Constructor ctorlist[] = cls.getDeclaredConstructors();
//Return declared constructor list
8) ct.getDeclaringClass()
//return declaring class
9) Class cls = Class.forName("field1");
Field fieldlist[] = cls.getDeclaredFields();
10) Object retobj = ct.newInstance(arglist);
// Create object
Java Collection Classes
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.
The Collections Framework is made up of a set of interfaces for working with groups of objects. The different interfaces describe the different types of groups.
Benefits of the Java Collections Framework
• Reduces programming effort
• Increases program speed and quality:
• Allows interoperability among unrelated APIs:
• Reduces effort to learn and to use new APIs:
• Reduces effort to design new APIs:
The following list describes the core collection interfaces:
Ordered When a collection is ordered, it means you can iterate through the collection in a specific (not-random) order.
Sorted:a sorted collection means a collection sorted by natural order.
Collection — the root of the collection hierarchy, Some types of collections allow duplicate elements, and others do not. Some are ordered and others are unordered. The Java platform doesn't provide any direct implementations of this interface but provides implementations of more specific subinterfaces, such as Set and List.
A Collection represents a group of objects known as its elements.
int size();
boolean isEmpty();
boolean contains(Object element);
boolean add(E element); //optional
boolean remove(Object element); //optional
Iterator
// Bulk operations
boolean containsAll(Collection c);
boolean addAll(Collection c); //optional
boolean removeAll(Collection c); //optional
boolean retainAll(Collection c); //optional
void clear(); //optional
List — A List cares about the index so list is an ordered collection (sometimes called a sequence). Lists can contain duplicate elements.
ArrayList: is ordered and unsynchronized collection.Think of this as a growable array. It gives you fast iteration and fast random access. an ArrayList is a variable-length array of object references. That is, an ArrayList can dynamically increase or decrease in size. Array lists are created with an initial size. When this size is exceeded, the collection is automatically enlarged. When objects are removed, the array may be shrunk.
add(o) Appends the specified element to the end of this list.
public void add(int index, E element) : Inserts the specified element at the specified position in this
*list. Shifts the element currently at that position (if any) and any subsequent elements to the right (adds one to their indices).
public E remove(int index): Removes the element at the specified position in this list.
* Shifts any subsequent elements to the left (subtracts one from their indices).
Vector: Synchronized order collection. Vector and ArrayList both uses Array internally as data structure.Null can be added to Vector
public synchronized E firstElement()
public synchronized void addElement(E obj)
public synchronized E lastElement()
public synchronized boolean removeElement(Object obj)
LinkedList: permits all elements (including null),and provided extra methods get,remove,insert an element at the beginning and end of the list. These operations allow linked lists to be used as a stack, queue, or double-ended queue (deque).
Sorted Set
A SortedSet is a Set that maintains its elements in ascending order. Several additional operations are provided to take advantage of the ordering. The SortedSet interface is used for things like word lists and membership rolls.
SortedMap
A SortedMap is a Map that maintains its mappings in ascending key order. It is the Map analogue of SortedSet. The SortedMap interface is used for apps like dictionaries and telephone directories.
Set — a collection that cannot contain duplicate elements.unOrdered collection.
add(E)
,remove(Object)
,containsAll(Collection),
addAll(Collection)
retainAll(Collection),
removeAll(Collection)
HashSet: It makes no guarantees as to the iteration order of the set; in particular, it does not guarantee that the order will remain constant over time. This class permits the null element.
TreeSet: This class guarantees that the sorted set will be in ascending element order, sorted according to the natural order of the elements (see Comparable), or by the comparator provided at set creation time, depending on which constructor is used.
LinkedHashSet: which is the order in which elements were inserted into the set (insertion-order).
Map — an object that maps keys to values. A Map cannot contain duplicate keys;
HashTable: Any non-null object can be used as a key or as a value. To successfully store and retrieve objects from a hashtable, the objects used as keys must implement the hashCode method and the equals method. HashTable is synchronized,
HashMap: permits null values and the null key. (The HashMap class is roughly equivalent to Hashtable, except that it is unsynchronized and permits nulls.) This class makes no guarantees as to the order of the map; in particular, it does not guarantee that the order will remain constant over time.
LinkedHashMap: with predictable iteration order. This implementation differs from HashMap in that it maintains a doubly-linked list running through all of its entries. This linked list defines the iteration ordering, which is normally the order in which keys were inserted into the map (insertion-order).
TreeMap You can probably guess by now that a TreeMap is a sorted Map. And
you already know that this means “sorted by the natural order of the elements
Benefits and constraints of using different data structures.
Array
Benefits
• Data access is fast.
• Good for ordered data, which is not changed or searched frequently. • Inefficient if number of elements grow.
Constraints
• Inefficient if an element to be inserted in middle of collection.
• Provides no special search mechanism.
Linked List
Benefits
• Allows efficient inserts/delete at any location
• Allows arbitrary growth of collection.
• Applying order to the elements is easy.
Constraints
• Slower while accessing elements by index.
• No special search mechanism is provided.
Tree
Benefits
• Easy addition/deletion in middle.
• Allows arbitrary growth.
• A better and efficient search mechanism.
Constraints
• Ordering is peculiar and some comparison mechanism is required.
• Searching is not efficient for unevenly distributed data.
Hashtable
Benefits
• Efficient searching.
• Good access mechanism.
• Allows arbitrary growth of collection.
Constraints
• Not good for small data set because of overheads.
• Overhead for storing keys for the values in collection.
• Overhead of hashing scheme.
Enumeration Interface: The Enumeration interface defines a way to traverse all the members of a collection of objects.
The hasMoreElements() method checks to see if there are more elements and returns a boolean.
If there are more elements, nextElement() will return the next element as an Object.
If there are no more elements when nextElement() is called, the runtime NoSuchElementException will be thrown.
Enumeration e = v.elements();
while (e.hasMoreElements()) {
Object o = e.nextElement();
System.out.println(o);
}
Iterators - Similar to the familiar Enumeration interface, but more powerful, and with improved method names.
Iterator - In addition to the functionality of the Enumeration interface, allows the user to remove elements from the backing collection with well defined, useful semantics.
The Iterator interface has the following methods:
• hasNext.
• next.
• Remove
Iterator i = c.iterator();
while (i.hasNext()) {
System.out.println(i.next());
}
ListIterator - Iterator for use with lists. In addition to the functionality of the Iterator interface, supports bi-directional iteration, element replacement, element insertion and index retrieval.
ListIterator iter = list.listIterator();
• hasNext()
• next()
• hasPrevious()
• previous()
• nextIndex()
• previousIndex()
• remove()
• set(E)
• add(E)
Ordering
Comparable - Imparts a natural ordering to classes that implement it. The natural ordering may be used to sort a list or maintain order in a sorted set or map. Many classes have been retrofitted to implement this interface.
List of objects that implement this interface can be sorted automatically by sort method of the list interface. This interface has compareTo() method that is used by the sort() method of the list.
In this code Employee class is implementing Comparable interface and have method compareTO(). ComparableDemo.java is showing the use of this interface. This class first makes a list of objects of type Employee and call sort method of java.util.Collections, which internally uses compareTo() method of Employee class and sort the list accordingly.
This method compares this object with o1 object. Returned int value has the following meanings.
1. positive – this object is greater than o1
2. zero – this object equals to o1
3. negative – this object is less than o1
java.util.Collections.sort(List) and java.util.Arrays.sort(Object[]) methods can be used to sort using natural ordering of objects.
• Employee.java
public class Employee implements Comparable {
int EmpID;
String Ename;
double Sal;
static int i;
public Employee() {
EmpID = i++;
Ename = "dont know";
Sal = 0.0;
}
public Employee(String ename, double sal) {
EmpID = i++;
Ename = ename;
Sal = sal;
}
public String toString() {
return "EmpID " + EmpID + "\n" + "Ename " + Ename + "\n" + "Sal" + Sal;
}
public int compareTo(Object o1) {
if (this.Sal == ((Employee) o1).Sal)
return 0;
else if ((this.Sal) > ((Employee) o1).Sal)
return 1;
else
return -1;
}
}
• ComparableDemo.java
import java.util.*;
public class ComparableDemo{
public static void main(String[] args) {
List ts1 = new ArrayList();
ts1.add(new Employee ("Tom",40000.00));
ts1.add(new Employee ("Harry",20000.00));
ts1.add(new Employee ("Maggie",50000.00));
ts1.add(new Employee ("Chris",70000.00));
Collections.sort(ts1);
Iterator itr = ts1.iterator();
while(itr.hasNext()){
Object element = itr.next();
System.out.println(element + "\n");
}
}
}
---------------------------------------------------------------------------------------
Comparator - Represents an order relation, which may be used to sort a list or maintain order in a sorted set or map. Can override a type's natural ordering, or order objects of a type that does not implement the Comparable interface.
Sorting by other fields
If we need to sort using other fields of the employee, we’ll have to change the Employee class’s compareTo() method to use those fields. But then we’ll loose this empId based sorting mechanism. This is not a good alternative if we need to sort using different fields at different occasions. But no need to worry; Comparator is there to save us.
By writing a class that implements the java.lang.Comparator interface, you can sort Employees using any field as you wish even without touching the Employee class itself; Employee class does not need to implement java.lang.Comparable or java.lang.Comparator interface.
Sorting by name field
Following EmpSortByName class is used to sort Employee instances according to the name field. In this class, inside the compare() method sorting mechanism is implemented. In compare() method we get two Employee instances and we have to return which object is greater.
public class EmpSortByName implements Comparator
public int compare(Employee o1, Employee o2) {
return o1.getName().compareTo(o2.getName());
}
}
Watch out: Here, String class’s compareTo() method is used in comparing the name fields (which are Strings).
Now to test this sorting mechanism, you must use the Collections.sort(List, Comparator) method instead of Collections.sort(List) method. Now change the TestEmployeeSort class as follows. See how the EmpSortByName comparator is used inside sort method.
import java.util.*;
public class TestEmployeeSort {
public static void main(String[] args) {
List coll = Util.getEmployees();
//Collections.sort(coll);
//use Comparator implementation
Collections.sort(coll, new EmpSortByName());
printList(coll);
}
private static void printList(List
System.out.println("EmpId\tName\tAge");
for (Employee e: list) {
System.out.println(e.getEmpId() + "\t" + e.getName() + "\t" + e.getAge());
}
}
}
Now the result would be as follows. Check whether the employees are sorted correctly by the name String field. You’ll see that these are sorted alphabetically.
EmpId Name Age
6 Bill 34
4 Clerk 16
5 Frank 28
1 Jorge 19
8 Lee 40
2 Mark 30
3 Michel 10
7 Simp 8
Sorting by empId field
Even the ordering by empId (previously done using Comparable) can be implemented using Comparator; following class
does that.
public class EmpSortByEmpId implements Comparator
public int compare(Employee o1, Employee o2) {
return o1.getEmpId().compareTo(o2.getEmpId());
}
}
Good website for collections:
http://www.java2s.com/Tutorial/Java/0140__Collections/Catalog0140__Collections.htm
Inner classes: define one class within another.
Inner Classes r 4 types:
• Inner Classes :
A “regular” inner class is declared inside the curly braces of another class, but outside any method or other code block. Can be declared abstract or final,p,p,p,strictfp
gives the inner class access to all of the outer class’ members, including those marked private.
->From code within the enclosing class, you can instantiate the inner class using only the name of the inner class, as follows: MyInner mi = new MyInner();
From code outside the enclosing class’ instance methods, you can instantiate the inner class only by using both the inner and outer class names, and a reference to the outer class as follows:
MyOuter mo = new MyOuter();
MyOuter.MyInner inner = mo.new MyInner();
This usage
class MyInner {
public void seeOuter() {
System.out.println("Outer x is " + x);
System.out.println("Inner class ref is " + this);
System.out.println("Outer class ref is " + MyOuter.this);
}
}
• Method-local Inner Classes
• Anonymous Inner Classes
An anonymous class in Java is a class with no specified name declared and instantiated at the same time. Because it has no name it can only be used once at place of declaration. Anonymous classes are given a name by the compiler and they are treated as local inner classes. This means that anonymous classes can access members of the enclosing class regardless of their access modifiers and they can access final variables declared in the enclosing block of code.
• Static Nested Classes:
Threads: There are two distinct types of multitasking: process-based and thread-based. process-based multitasking is the feature that allows your computer to run two or more programs concurrently.
a program can contain more than one thread, a single program can use multiple threads to perform two or more tasks at once.
To create a new thread, your program will either implement the Runnable interface or extend Thread. Both Runnable and Thread are packaged in java.lang. Thus, they are automatically available to all programs.
There are two ways to create a thread. The first is to declare a class that extends Thread. When the class is instantiated, the thread and object are created together and the object is automatically bound to the thread. By calling the object's start() method, the thread is started and immediately calls the object's run() method. Here is some code to demonstrate this method.
// This class extends Thread
class BasicThread1 extends Thread {
// This method is called when the thread runs
public void run() {
}
}
// Create and start the thread
Thread thread = new BasicThread1();
thread.start();
The second way is to create the thread and supply it an object with a run() method. This object will be permanently associated with the thread. The object's run() method will be invoked when the thread is started. This method of thread creation is useful if you want many threads sharing an object. Here is an example that creates a Runnable object and then creates a thread with the object.
class BasicThread2 implements Runnable {
// This method is called when the thread runs
public void run() {
}
}
// Create the object with the run() method
Runnable runnable = new BasicThread2();
// Create the thread supplying it with the runnable object
Thread thread = new Thread(runnable);
// Start the thread
thread.start();
The Thread Scheduler
The thread scheduler is the part of the JVM that decides which thread should run at any given moment, Any thread in the runnable state can be chosen by the scheduler to be the one and only running thread.
Yielding to other processes
A CPU intensive operation being executed may not allow other threads to be executed for a "large" period of time. To prevent this it can allow other threads to execute by invoking the yield() method. The thread on which yield() is invoked would move from running state to ready state.
For synchronizing a HashMap, you can use Collections.synchronizedMap(
Remember, synchronization will cause a performance problem. So, it needs to be used carefully, when really required.
wait(), notify(), and notifyAll() must be called from within a synchronized context! A thread can’t invoke a wait or notify method on an object unless it owns that object’s lock.
Deadlocking can occur when a locked object attempts to access another locked
object that is trying to access the first locked object. In other words, both
threads are waiting for each other’s locks to be released; therefore, the locks
will never be released! ThreadMXBean bean = ManagementFactory.getTreadMXBean();
bean.findMonitorDedlockedThreads(); To find all deadlocked threads.
Synchronized :
Java also offers three ways to define synchronized blocks.
Synchronized Class Method:
class class_name {
static synchronized type method_name() {
statement block
}
}
All the statements in the method become the synchronized block, and the class object is the lock.
Synchronized Instance Method:
class class_name {
synchronized type method_name() {
statement block
}
}
All the statements in the method become the synchronized block, and the instance object is the lock.
Synchronized Statement:
class class_name {
type method_name() {
synchronized (object) {
statement block
}
}
}
All the statements specified in the parentheses of the synchronized statement become the synchronized block, and the object specified in the statement is the lock.
Java applys the synchronization rule by assigning the ownership of the lock's monitor to the threads that are running the synchronized blocks. Here is how it works:
• When a synchronized clock is reached in an execution thread, it will try to gain the ownership of the monitor of the lock object. If another thread owns the lock's monitor, it will wait.
• Once the lock's monitor is free, the waiting thread will become the owner of the lock's monitor, and start to execute the synchronized block.
• Once the synchronized block is executed to the end, the lock's monitor will be freed again.
Note that one program can have many locks and each lock can be associated with many different synchronized blocks. But the synchronization rule only applies between the synchronized block and its associated lock.
For example, the following code defines two synchronized blocks. Both are associated with the same lock, the instance object.
class class_name {
type method_name() {
synchronized (this) {
statement block 1
}
}
synchronized type method_name() {
statement block 2
}
}
Block 1 will never be executed at the same time as block 2.
The following code defines two synchronized blocks. But they are associated with two different locks, one is the class object, and the other is the instance object. Those two synchronized blocks will never wait for each other.
class class_name {
type method_name() {
synchronized (this) {
statement block 1
}
}
static synchronized type method_name() {
statement block 2
}
}
Deadlock:
Deadlocking can occur when a locked object attempts to access another locked object that is trying to access the first locked object. In other words, both threads are waiting for each other’s locks to be released; therefore, the locks will never be released!
Observer and Observable
How are Observer and Observable usedObjects that subclass the Observable class maintain a list of observers. When anObservable object is updated it invokes the update() method of each of its observers to notify the observers that it has changed state. The Observer interface is implemented by objects that observe Observable objects.
Annotations in Java 5.0
Annotations are generally a way to add meta-data information to a java element (an element can be a class, method, field, or anything) and these meta-data are processed by the tools (compilers, javadoc, etc.). Annotations are differentiated from other elements like class, interface etc., by preceding an '@' symbol before it.
Consider the following class definition,
Employee. java
final class Employee
{
private String name;
private String id;
// Getters and setters for Employee class.
}
The above is a definition of a class, Employee. It can be noted that the class declaration is preceded with the final keyword which tells that this class cannot be sub-classed. So, the introduction of the final keyword adds some additional information (or adds some constraints) over the class definition telling that no other class in the word can extend the Employee class. Therefore, the final keyword forms a part in providing meta-data information in the class definition. So, this is one variation of Annotation.
Annotations can be applied to a program's declarations of classes, fields, methods, and other program elements.
Annotations Used by the Compiler
There are three annotation types that are predefined by the language specification itself: @Deprecated, @Override, and @SuppressWarnings.
@Deprecated—the @Deprecated annotation indicates that the marked element is deprecated and should no longer be used. The compiler generates a warning whenever a program uses a method, class, or field with the @Deprecated annotation. When an element is deprecated, it should also be documented using the Javadoc @deprecated tag, as shown in the following example. The use of the "@" symbol in both Javadoc comments and in annotations is not coincidental—they are related conceptually. Also, note that the Javadoc tag starts with a lowercase "d" and the annotation starts with an uppercase "D".
// Javadoc comment follows
/**
* @deprecated
* explanation of why it was deprecated
*/
@Deprecated
static void deprecatedMethod() { }
}
@Override—the @Override annotation informs the compiler that the element is meant to override an element declared in a superclass (overriding methods will be discussed in the the lesson titled "Interfaces and Inheritance").
// mark method as a superclass method
// that has been overridden
@Override
int overriddenMethod() { }
While it's not required to use this annotation when overriding a method, it helps to prevent errors. If a method marked with @Override fails to correctly override a method in one of its superclasses, the compiler generates an error.
@SuppressWarnings—the @SuppressWarnings annotation tells the compiler to suppress specific warnings that it would otherwise generate. In the example below, a deprecated method is used and the compiler would normally generate a warning. In this case, however, the annotation causes the warning to be suppressed.
// use a deprecated method and tell
// compiler not to generate a warning
@SuppressWarnings("deprecation")
void useDeprecatedMethod() {
objectOne.deprecatedMethod(); //deprecation warning - suppressed
}
Every compiler warning belongs to a category. The Java Language Specification lists two categories: "deprecation" and "unchecked." The "unchecked" warning can occur when interfacing with legacy code written before the advent of generics (discussed in the lesson titled "Generics"). To suppress more than one category of warnings, use the following syntax:
@SuppressWarnings({"unchecked", "deprecation"})
Serialization
Serialization is the process of saving an object's state to a sequence of bytes; deserialization is the process of rebuilding those bytes into a live object.
The Java Serialization API provides a standard mechanism for developers to handle object serialization.
Why is serialization required?
In today's world, a typical enterprise application will have multiple components and will be distributed across various systems and networks. In Java, everything is represented as objects; if two Java components want to communicate with each other, there needs be a mechanism to exchange data. One way to achieve this is to define your own protocol and transfer an object. This means that the receiving end must know the protocol used by the sender to re-create the object, which would make it very difficult to talk to third-party components. Hence, there needs to be a generic and efficient protocol to transfer the object between components. Serialization is defined for this purpose, and Java components use this protocol to transfer objects.
How to serialize an object
In order to serialize an object, you need to ensure that the class of the object implements the java.io.Serializable interface, as shown in Listing 1.
Listing 1. Implementing Serializable
import java.io.Serializable;
class TestSerial implements Serializable {
public byte version = 100;
public byte count = 0;
}
In Listing 1, the only thing you had to do differently from creating a normal class is implement the java.io.Serializable interface. The Serializable interface is a marker interface; it declares no methods at all. It tells the serialization mechanism that the class can be serialized.
Now that you have made the class eligible for serialization, the next step is to actually serialize the object. That is done by calling the writeObject() method of the java.io.ObjectOutputStream class, as shown in Listing 2.
Listing 2. Calling writeObject()
public static void main(String args[]) throws IOException {
FileOutputStream fos = new FileOutputStream("temp.out");
ObjectOutputStream oos = new ObjectOutputStream(fos);
TestSerial ts = new TestSerial();
oos.writeObject(ts);
oos.flush();
oos.close();
}
Three ways to customize serialization
– mark sensitive fields as transient
– implement Serializable and override
readObject() and writeObject()
– implement Externalizable and override
writeExternal() and readExternal()
public class SalesEntry implements Serializable {
private void writeObject(ObjectOutputStream out) throws IOException {
// Write all fields that are not transient or static,
// including those in base classes.
out.defaultWriteObject();
// Write transient field baseSalary as an encrypted String.
out.writeUTF(MyEncrypter.encryptInt(baseSalary));
}
private void readObject(ObjectInputStream in) throws IOException {
// Read all fields that are not transient or static
// including those in base classes.
in.defaultReadObject();
// Read transient field baseSalary from an encrypted String.
baseSalary = MyEncrypter.decryptInt(in.readUTF());
}
}
writeExternal() &readExternal()
public class SalesEntry implements Externalizable {
// A public no-arg constructor is required by
// Externalizable.readExternal.
public SalesEntry() {
}
// Method in the Externalizable interface.
public void writeExternal(ObjectOutput out) throws IOException {
// Can't use ObjectOutputStream.defaultWriteObject().
// If base class fields require serialization
// then code to perform that must be supplied here.
out.writeUTF(name);
out.writeObject(date); // use for objects and arrays
out.writeFloat(sales);
out.writeUTF(MyEncrypter.encryptInt(baseSalary));
}
// Method in the Externalizable interface.
public void readExternal(ObjectInput in) throws IOException,
ClassNotFoundException {
// Can't use ObjectInputStream.defaultReadObject().
// If base class fields require deserialization
// then code to perform that must be supplied here.
name = in.readUTF();
date = (Date) in.readObject(); // use for objects and arrays
sales = in.readFloat();
baseSalary = MyEncrypter.decryptInt(in.readUTF());
}
}
JDBC Programming:
The JDBC ( Java Database Connectivity) API defines interfaces and classes for writing database applications in Java by making database connections. Using JDBC you can send SQL, PL/SQL statements to almost any relational database.
JDBC Steps :
1.Loading a database driver: In this step of the jdbc connection process, we load the driver class by calling Class.forName() with the Driver class name as an argument. Class.forName(”sun.jdbc.odbc.JdbcOdbcDriver”);
2. Creating a oracle jdbc Connection: The JDBC DriverManager class defines objects which can connect Java applications to a JDBC driver.
Its getConnection() method is used to establish a connection to a database. It uses a username, password, and a jdbc url to establish a connection to the database and returns a connection object.
Connection dbConnection=DriverManager.getConnection(url,”loginName”,”Password”)
3. Creating a jdbc Statement object: Once a connection is obtained we can interact with the database. Connection interface defines methods for interacting with the database via the established connection. To execute SQL statements, you need to instantiate a Statement object from your connection object by using the createStatement() method.
Statement statement = dbConnection.createStatement();
A statement object is used to send and execute SQL statements to a database.
Three kinds of Statements
Statement: Execute simple sql queries without parameters.
Statement createStatement()
Creates an SQL Statement object.
Prepared Statement: Execute precompiled sql queries with or without parameters.
PreparedStatement prepareStatement(String sql)
returns a new PreparedStatement object. PreparedStatement objects are precompiled
SQL statements.
An example of a PreparedStatement object is
PreparedStatement pstmt = con.prepareStatement(”update Orders set pname = ? where Prod_Id = ?”);
pstmt.setInt(2, 100);
pstmt.setString(1, “Bob”);
pstmt.executeUpdate();
Callable Statement: Execute a call to a database stored procedure.
CallableStatement prepareCall(String sql)
returns a new CallableStatement object. CallableStatement objects are SQL stored procedure call statements.
4. Executing a SQL statement with the Statement object, and returning a jdbc resultSet.
Statement interface defines methods that are used to interact with database via the execution of SQL statements. The Statement class has three methods for executing statements:
executeQuery(), executeUpdate(), and execute(). For a SELECT statement, the method to use is executeQuery . For statements that create or modify tables, the method to use is executeUpdate. Note: Statements that create a table, alter a table, or drop a table are all examples of DDL
statements and are executed with the method executeUpdate. execute() executes an SQL
statement that is written as String object.
ResultSet provides access to a table of data generated by executing a Statement. The table rows are retrieved in sequence. A ResultSet maintains a cursor pointing to its current row of data. The next() method is used to successively step through the rows of the tabular results.
A cursor can be thought of as a pointer to the rows of the result set that has the ability to keep track of which row is currently being accessed. The JDBC API supports a cursor to move both forward and backward and also allowing it to move to a specified row or to a row whose position is relative to another row.
Types of ResultSets :
The sensitivity of the ResultSet object is determined by one of three different ResultSet types:
• TYPE_FORWARD_ONLY — the result set is not scrollable i.e. the cursor moves only forward, from before the first row to after the last row.
• TYPE_SCROLL_INSENSITIVE — the result set is scrollable; its cursor can move both forward and backward relative to the current position,
and it can move to an absolute position.
• TYPE_SCROLL_SENSITIVE — the result set is scrollable; its cursor can move both forward and backward relative to the current position, and it can move to an absolute position.
Statement stmt = con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,
ResultSet.CONCUR_READ_ONLY);
ResultSet srs = stmt.executeQuery(”…..”);
The first argument is one of three constants added to the ResultSet API to indicate the type of a ResultSet object: TYPE_FORWARD_ONLY, TYPE_SCROLL_INSENSITIVE, and TYPE_SCROLL_SENSITIVE. The second argument is one of two ResultSet constants for specifying whether a result set is read-only or updatable: CONCUR_READ_ONLY and CONCUR_UPDATABLE. If you do not specify any constants for the type and updatability of a ResultSet object, you will automatically get one that is TYPE_FORWARD_ONLY and CONCUR_READ_ONLY.
• next() - moves the cursor forward one row. Returns true if the cursor is now positioned on a row and false if the cursor is positioned after the last row.
• previous() - moves the cursor backwards one row. Returns true if the cursor is now positioned on a row and false if the cursor is positioned before the first row.
• first() - moves the cursor to the first row in the ResultSet object. Returns true if the cursor is now positioned on the first row and false if the ResultSet object
does not contain any rows.
• last() - moves the cursor to the last row in the ResultSet object. Returns true if the cursor is now positioned on the last row and false if the ResultSet object
does not contain any rows.
• beforeFirst() - positions the cursor at the start of the ResultSet object, before the first row. If the ResultSet object does not contain any rows, this method has
no effect.
• afterLast() - positions the cursor at the end of the ResultSet object, after the last row. If the ResultSet object does not contain any rows, this method has no effect.
• relative(int rows) - moves the cursor relative to its current position.
• absolute(int n) - positions the cursor on the n-th row of the ResultSet object.
ResultSetMetaData Interface holds information on the types and properties of the columns in a ResultSet. It is constructed from the Connection object.
Types Of Drivers : There are four types
A).JDBC-ODBC Bridge Driver(Bridge):
The Type 1 driver translates all JDBC calls into ODBC calls and sends them to the ODBC driver. ODBC is a generic API. The JDBC-ODBC Bridge driver is recommended only for experimental use or when no other alter native is available.
Advantage :
The JDBC-ODBC Bridge allows access to almost any database, since the database’s ODBC drivers are already available.
Disadvantages
1. Since the Bridge driver is not written fully in Java, Type 1 drivers are not portable.
2. A performance issue is seen as a JDBC call goes through the bridge to the ODBC driver, then to the database, and this applies even in the reverse process. They are the slowest of all driver types.
3. The client system requires the ODBC Installation to use the driver.
4. Not good for the Web.
b. Native API Partly Java Driver(Native)
The distinctive characteristic of type 2 jdbc drivers are that Type 2 drivers convert JDBC calls into database-specific calls i.e. this driver is specific to a particular database. Some distinctive characteristic of type 2 jdbc drivers are shown below. Example: Oracle will have oracle native api.
Advantage
The distinctive characteristic of type 2 jdbc drivers are that they are typically offer better performance than the JDBC-ODBC Bridge as the layers of communication (tiers) are less than that of Type
1 and also it uses Native api which is Database specific.
Disadvantage
1. Native API must be installed in the Client System and hence type 2 drivers cannot be used for the Internet.
2. Like Type 1 drivers, it’s not written in Java Language which forms a portability issue.
3. If we change the Database we have to change the native api as it is specific to a database
4. Mostly obsolete now
5. Usually not thread safe.
c. Net protocol pure Java Driver(Middleware)
Type 3 database requests are passed through the network to the middle-tier server. The middle-tier then translates the request to the database. If the middle-tier server can in turn use Type1, Type 2 or Type 4 drivers.
Advantage
1. This driver is server-based, so there is no need for any vendor database library to be present on client machines.
2. This driver is fully written in Java and hence Portable. It is suitable for the web.
3. There are many opportunities to optimize portability, performance, and scalability.
4. The net protocol can be designed to make the client JDBC driver very small and fast to load.
5. The type 3 driver typically provides support for features such as caching (connections, query results, and so on), load balancing, and advanced
system administration such as logging and auditing.
6. This driver is very flexible allows access to multiple databases using one driver.
7. They are the most efficient amongst all driver types.
Disadvantage
It requires another server application to install and maintain. Traversing the recordset may take longer, since the data comes through the backend server.
d. Native protocol Pure Java Driver(pure)
The Type 4 uses java networking libraries to communicate directly with the database server.
Advantage
1. The major benefit of using a type 4 jdbc drivers are that they are completely written in Java to achieve platform independence and eliminate deployment administration issues. It is most suitable for the web.
2. Number of translation layers is very less i.e. type 4 JDBC drivers don’t have to translate database requests to ODBC or a native connectivity interface or to pass the request on to another server, performance is typically quite good.
3. You don’t need to install special software on the client or server. Further, these drivers can be downloaded dynamically.
Disadvantage
With type 4 drivers, the user needs a different driver for each database.
When we create an instace of a class using new operator, it does two things
1. Load the class in to memory, if it is not loaded -
which means creating in-memory representation of the class from the .class file so that an instance can be created out of it. This includes initializing static variables (resolving of that class)
2. create an instance of that class and store the reference to the variable.
Class.forName does only the first thing.
It loads the class in to memory and return that reference as an instance of Class. If we want to create an instance then, we can call newInstance method of that class. which will invoke the default constructor (no argument constructor).
Note that if the default constructor is not accessible, then newInstance method will throw an IllegalAccessException. and if the class is an abstract class or interface or it does not have a default constructor, then it will throw an InstantiationException. If any exception araises during resolving of that class, it will throw an ExceptionInInitializerError.
If the default constructor is not defined, then we have to invoke the defiend constructor using reflection API.
But the main advantage with Class.forName is, it can accept the class name as a String argument. So we can pass the class name dynamically. But if we create an instance of a class using new operator, the class name can't be changed dynamically.
Class.forName() in turn will call loadClass method of the caller ClassLoader (ClassLoder of the class from where Class.forName is invoked).
By default, the Class.forName() resolve that class. which means, initialize all static variables inside that class.
same can be changed using the overloaded method of Class.forName(String name,boolean initialize,ClassLoader loader)
The main reason for loading jdbc driver using Class.forName() is, the driver can change dynamically.
in the static block all Drivers will create an instance of itself and register that class with DriverManager using DriverManager.registerDriver() method. Since the Class.forName(String className) by default resolve the class, it will initialize the static initializer.
So when we call Class.forName("com.sun.jdbc.odbc.JdbcOdbcDriver"),
the Driver class will be loaded, instanciated and registers with DriverManager
So if you are using new Operator you have to do the following things.
Driver drv = new com.sun.jdbc.odbc.JdbcOdbcDriver();
DriverManager.registerDriver(drv);
Design patterns: a design pattern is a template for software development. The purpose of the template is to define a particular behavior or technique that can be used as a building block for the construction of software - to solve universal problems that commonly face developers.
Singleton Design Pattern
Restriction to a class to have one and only one instance. This way the developer can ensure as well as can control how an object is instantiated and can prevent others from creating or copying multiple instances of the class.
Purpose: The main purpose is that if we have to use a resource then we can create a singleton class which can only access the resource and by making this instance available to other threads or any part of the application we can make sure that unnecessary objects are not getting created for accessing the resource.
Another purpose is that we have some utility classes which are being used by other java classes to do some calculations etc. Now if we make the utility class a singleton class then all objects and all parts of the application can use this one instance of the utility class and no extra instaces are required. There are lots of other uses also.
public class SingletonObject
{
private SingletonObject()
{
// no code req'd
}
public static SingletonObject getSingletonObject()
{
if (ref == null)
// it's ok, we can call this constructor
ref = new SingletonObject();
return ref;
}
private static SingletonObject ref;
}
Preventing thread problems with your singleton
public static synchronized
SingletonObject getSingletonObject()
Here's where most articles on singletons fall down, because they forget about cloning. Examine the following code snippet, which clones a singleton object.
public class Clone
{
public static void main(String args[])
throws Exception
{
// Get a singleton
SingletonObject obj =
SingletonObject.getSingletonObject();
// Buahahaha. Let's clone the object
SingletonObject clone =
(SingletonObject) obj.clone();
}
}
Okay, we're cheating a little here. There isn't a clone() method defined in SingletonObject, but there is in the java.lang.Object class which it is inherited from. By default, the clone() method is marked as protected, but if your SingletonObject extends another class that does support cloning, it is possible to violate the design principles of the singleton. So, to be absolutely positively 100% certain that a singleton really is a singleton, we must add a clone() method of our own, and throw a CloneNotSupportedException if anyone dares try!
Here's the final source code for a SingletonObject, which you can use as a template for your own singletons.
public class SingletonObject
{
private SingletonObject()
{
// no code req'd
}
public static SingletonObject getSingletonObject()
{
if (ref == null)
// it's ok, we can call this constructor
ref = new SingletonObject();
return ref;
}
public Object clone()
throws CloneNotSupportedException
{
throw new CloneNotSupportedException();
// that'll teach 'em
}
private static SingletonObject ref;
}
Some other design patterens
Proxy Design Pattern
Decorator
Factory
Composite view
Adopter/Inverter
Subscribe to:
Posts (Atom)