Friday, 19 June 2015

Java StringBuffer Class

StringBuffer is a peer class of String that provides much of the functionality of Strings. In contrast to String, StringBuffer represents growable and writeable character sequences.

StringBuffer may have characters and substrings inserted in the middle or appended to the end.

StringBuffer will automatically grow to make room for such additions and often has more characters pre-allocated than are actually needed, to allow room for growth.

Few important point related to StringBuffer class

  • StringBuffer is an Object like String.
  • StringBuffer class is also final like String class.
  • StringBuffer objects are mutable (can be modified) unlike String objects.

Constructors of StringBuffer Class


Methods of StringBuffer Class



Example:

class SBDemo1

{ public static void main(String args[])

{ StringBuffer sb1 = new StringBuffer();

System.out.println("sb1: length: "+sb1.length() + " capacity: " + sb1.capacity());

StringBuffer sb2 = new StringBuffer(100);

System.out.println("sb2: length: "+sb2.length() + " capacity: " + sb2.capacity());

StringBuffer sb3 = new StringBuffer("Hello");

System.out.println("sb3: length: "+sb3.length() + " capacity: " + sb3.capacity());

sb1.ensureCapacity(200);

System.out.println("sb1: length: "+sb1.length() + " capacity: " + sb1.capacity());

sb3.setLength(10);

System.out.println("sb3: length: "+sb3.length() + " capacity: " + sb3.capacity());

System.out.println("sb3: "+sb3);

sb3.setLength(3);

System.out.println("sb3: length: "+sb3.length() + " capacity: " + sb3.capacity());

System.out.println("sb3: "+sb3);

}

}

Output:

sb1: length: 0 capacity: 16

sb2: length: 0 capacity: 100

sb3: length: 5 capacity: 21

sb1: length: 0 capacity: 200

sb3: length: 10 capacity: 21

sb3: Hello

sb3: length: 3 capacity: 21

sb3: Hel

append() Method

It has overloaded versions for all the built-in types and for Object. These are the few of its form:

public StringBuffer append(char c)

public StringBuffer append(String str)

public StringBuffer append(boolean b)

public StringBuffer append(Object obj)

public StringBuffer append(int num)

public StringBuffer append(double

public StringBuffer append(char[] str)

public StringBuffer append(StringBuffer sb)

String.valueOf() method is called for each parameter to obtain its String representation. The result is appended to the current StringBuffer object. The buffer itself is returned by each version of append(). This allows subsequent calls to be chained together.

Note: If null string is appended then “null” gets appended.

insert() Method

The insert() method inserts one string into another. It is overloaded to accept values of all the simple types, plus Strings and Objects. Like append() method, it calls String.valueOf() method to obtain the string representation of the argument passed to it. This string is then inserted into the invoking StringBuffer object. These are the few of its form:

public StringBuffer insert(int offset, char c)

public StringBuffer insert(int offset, int c)

public StringBuffer insert(int offset, long l)

public StringBuffer insert(int offset, char[] str)

public StringBuffer insert(int offset, double d)

public StringBuffer insert(int offset, float f)

public StringBuffer insert(int offset, String str)

public StringBuffer insert(int offset, Object obj)

Example: The following example illustrates some of the methods discussed above.

class SBDemo2

{ public static void main(String args[])

{ String s; int a=42;

StringBuffer sb=new StringBuffer(40);

s=sb.append("a= ").append(a).append("!").toString();

System.out.println(s);

StringBuffer sb1=new StringBuffer("I Java!");

sb1.insert(2, "like ");

System.out.println(sb1);

System.out.println("Reverse of "+sb1+" is: "+sb1.reverse());

}

}

Output:

a= 42!

I like Java!

Reverse of I like Java! is: !avaJ ekil I

Monday, 15 June 2015

Java String important methods

Character Extraction Methods

The String class provides a number of ways in which characters can be extracted from a String object. Although the characters that comprise string within a String object cannot be indexed as if they were a character array, many of the String methods employ an index (or offset) into the string for their operation. Like arrays, the string indexes begin at zero.


Example: The following example illustrates the use of character extraction methods discussed above:

class ExtractionDemo

{ public static void main(String args[])

{ String s = "This is a Demo of character extraction methods";

char c = s.charAt(10);

System.out.println("Character at position 10: " + c);

char carray[] = s.toCharArray();

System.out.print("Character Array: ");

for(int i=0; i<carray.length; i++)

System.out.print(carray[i]);

System.out.println();

byte b[] = s.getBytes();

System.out.print("Byte Array: ");

for(int i=0; i<b.length; i++)

System.out.print((char) b[i]);

System.out.println();

int start = 10; int end = 14;

char buf[] - new char[end-start];

s.getChars(start, end, buf, 0);

System.out.println(buf);

}

}

Output:


Character at position 10: D

Character Array: This is a Demo of character extraction methods

Byte Array: This is a Demo of character extraction methods

Demo

String Comparison Methods



The regionMatches() method compares a specific region inside a styring with another specific region in another string. Thre is an overloaded form that allows you to ignore case in such comparisions.

For both versions, startIndex specifies the index at which the region begins within the invoking string object. The string being compared is specified by str2. The index at which the comparison will starts within the str2 is specified by str2StartIndex. The length of the substring being compared is passed in len.

Example: The following example illustrates the use of regionMatches() method.

class Region

{ public static void main(String args[])

{ String s="Yahoo!";

String s2="yahoo.com";

System.out.println(s.regionMatches(0,s2,0,5));

System.out.println(s.regionMatches(true,0,s2,0,5));//ignore case

System.out.println(s.resionMatches(-1,s2,-1,5));

}

}

Output:

false

true

false

Example: The following example illustrates the use of compareTo() method.

class CompareToDemo

{ public static void main(String args[])

{ String s="yahoo!";

String s2="Yahoo!";

String s3="yahoo";

System.out.println(s.compareTo(s2));

System.out.println(s.compareToIgnoreCase(s2));//ignore case

System.out.println(s.compareTo(s3));

}

}

Output:

32

0

1

startsWith( ) and endsWith( )


Example: The following example illustrates the use of startsWith() and endsWith() methods.

class ComparisonDemo

{ public static void main(String args[])

{ String name="Rahul Jain Januthariya";

System.out.println(name.startsWith("Rahul"));

System.out.println(name.startsWith("rahul"));

System.out.println(name.endsWith("Januthariya"));

System.out.println(name.startsWith("Jain",7));

}

}

Output:

true

false

true

true

The equals( ) v/s = =

The equals() method compares the characters inside a String object. The == compares two object references to see whether they refer to the same instance.

String Search Methods

String class provides methods that allow you to search a string for a specified character or substring. In all cases, methods return the index at which the character or substring is found or –1 on failure.


Methods for String Modification

Because String objects are immutable, whenever you want to modify a string, you must either copy it into a StringBuffer or use one of the following string methods, which will construct a new copy of the string with your modifications.





Note: The substring() methods throw IndexOutOfBoundsException if the beginIndex is negative, or endIndex is larger than the length of this String object, or beginIndex is larger than endIndex.




Java Special String operations

1. String Literals

For each String literal in your program java automatically constructs String object. Thus, you can use a string literal to initialize a String object.

String s = “abc”;

Because a String object is created for every string literal, you can use a string literal at any place you can use a String object.

For example, you can call methods directly on a quoted string as it uses an object reference.

System.out.println(“abc”.length());

2. String Concatenation


In general, Java does not allow operators to be applied to String objects. The one exception to this rule is + operator, which concatenates two strings producing a String object as a result.

Example: The reference of the concatenated string “Rahul Jain Januthariya” will be stored in the reference variable name.

String name = “Rahul” + “ ”  +  “Jain”  +  “ ” + “Januthariya”

String Concatenation with other data types

If a string is concatenated with any data of type other than the string, the compiler converts the other operand (non-string) to its string equivalent.

Example:

String s = “four: “+ 2 + 2 ; System.out.println(s);

Output: four:22

String Conversion and toString( )

When Java converts data into its String representation during concatenation, it does so by calling one of the overloaded versions of the String conversion method valueOf() defined by String class. The valueOf() is a static method overloaded for all simple types and for type Object.

For the simple types, valueOf() returns string that contains the human-readable equivalent of the value with which it is called. For objects, valueOf() calls the toString() method on the object.

Every class inherits toString(), because it is defined by the Object class. However, the default implementation of the toString() is seldom sufficient. It displays name of the class followed by symbol “@” and then object-id (e.g. Box@ab1232), which is normally of no use. For most important classes that you create, you will want to override toString() and provide your own string representations.

You can do so by overriding the toString( ) method:

String toString()

Example:

class Box

{ double w, h, d;

Box( double w, double h, double d)

{ this.w=w; this.h=h; this.d=d;

}

public String toString()

{ return "Dimensions are "+w+" by "+h+" by "+d+".";

}

class ToStringDemo1

{ public static void main(String args[])

{ Box b=new Box(10,12,14);

String s="Box b: "+b; //concates box object

System.out.println(b);

System.out.println(s);

}

}

Output:

Dimensions are 10.0 by 12.0 by 14.0.

Box b: Dimensions are 10.0 by 12.0 by 14.0

Note: If toString() is not overridden, the output of this program will be something like:

Box@b8df17

Box b: Box@b8df17

Java String Constructors

The class String supports many constructors to create String objects. The simplest way to

construct a string is to assign a literal value to a String type variable:

String str = "This is a string";

The above statement will create a string object with the specified contents.

Some of the commonly used constructors are described below:

String()


Initializes a newly created String object so that it represents an empty character sequence:

String str = new String();

String (String str)

Initializes a newly created String object so that it represents the same sequence of characters as the argument; in other words, the newly created string is a copy of the argument string.

Examples:

String str = new String("This is a string");

String str1 = new String(str);

The string str1 is a copy of string str. Although contents are same but str and str1 point to different string objects.

String(char[] value)

Allocates a new String so that it represents the sequence of characters currently contained in the character array argument.

Example: String str in the following example will hold “abc”.

char cr[] = { ‘a’,’b’,’c’};

            String str = new String (cr);

String(char value[], int offset, int count)

Allocates a new String that contains characters from a sub-array of the character array argument.

Example: String str in the following example will hold “cde”.

char cr[] = { ‘a’,’b’,’c’,’d’,’e’,’f’ };

            String s = new String (cr,2,3);

String(byte b[])

Constructs a new String by decoding the specified array of bytes using the platform's default charset.

String(byte[]  b, int offset, int length)

Constructs a new String by decoding the specified subarray of bytes using the platform's default charset.

Even though Java's char type uses 16 bits to represent the Unicode character set, the typical format for strings on the Internet uses arrays of 8-bit bytes constructed from the ASCII character set. Because 8-bit ASCII strings are common, the String class provides constructors that initialize a string when given a byte array. In each of the above constructors the byte to character
conversion is done by using the default character encoding of the platform.

Example: The following example illustrates the use of the constructors, which convert byte array into string.

class SubStringCons

{ public static void main(String args[])

{ byte ascii[] = { 65,66,67,68,69,70 };

String s = new String (ascii);

System.out.println(s);

String s1 = new String (ascii, 2, 3);

System.out.println(s1);

}

}

Output:

ABCDEF

CDE

Java String introduction

The classes String and StringBuffer are part of the java.lang package.

(i) String in Java is an Object

String is a sequence of characters. But, unlike many other languages that implement strings as character arrays, Java implements strings as objects of type String.

Implementing strings as built in objects allows java to provide a full complement of features that make string handling convenient. Also string objects can be constructed a number of ways, making it easy to obtain a string when needed.

(ii) Strings are Immutable

Strings are immutable i.e. you cannot change the string after creation. However, a variable declared as a String reference can be changed to point at some other String object at any time.

You can still perform all types of string operations. Each time you need an altered version of an existing string, a new string object is created that contains the modifications. The original string is left unchanged. This approach is used because fixed, immutable strings can be implemented more efficiently than changeable ones. For those cases in which a modifiable string is desired, there is a companion class called StringBuffer, whose objects contain strings that can be
modified after they are created.

(iii) String class is final

Both String and StringBuffer classes are final. This allows certain optimizations that increase performance of common string operations as discussed in the previous chapter on modifiers.

Java modifiers for class members

  • static
  • final
  • abstract
  • synchronized
  • native
  • transient
  • volatile
1. static modifier

The static members belong to the class in which they are declared, and are not part of any instance of the class. Depending on the accessibility modifiers of the static members in a class, client can access these by using the class name or through object references of the class.

static variables (also called class variables)

These variables only exist in the class they are defined in. When the class is loaded, static variables are initialized to their default values, if no explicit initialization expression in specified.

The static member variables are often used when tracking global information about the instances of a class.

static methods

These are also known as class methods. A static method in a class can directly access other static members in the class. It cannot access instance (i.e. non-static) members of the class, as there is no notion of an object associated with a static method.

However, note that a static method in a class can always use a reference of the class’s type to access its members regardless of whether these members are static or not.

A typical static method might perform some task on behalf of the whole class and/or objects of the class.

An instance in a subclass cannot override a static method in the superclass. The compiler will flag this with an error (means a static method in super class cannot be overridden by non static methods in subclass). A static method is class specific and not part of any object, while overriding, methods are invoked on the behalf of objects of the subclass. However, a static

method in a subclass can hide a static method in the superclass.

Methods declared as static have several restrictions:

  • They can only call other static methods.
  • They can only access static data members
  • They cannot refer to this or super in anyway

static initialization block

A java class can have one or more static initialization block. The syntax of the static initialization block is as follows:

static

{

code

}

A static initialization block can be thought of as a static method, which is invoked implicitly/automatically as soon as the class is loaded.

The static block can be useful in the following situations:

  • Dynamic initialization of static variables.
  • For performing one time activity at the time of loading class. For example, loading jdbc driver class.
  • Loading small database/configuration files in Hashtable, HashMap, Properties etc.

2. final modifier

The modifier final can be used with
  • local variables
  • instance variables/data members
  • static variables/data members
  • instance methods

2.1 final variables

A final variable is normally initialized at the time of declaration and its value cannot be modified after assigning once. Here are few important points related to final variables:
 
  • A final variable is a constant, despite being called a variable. Its value cannot be changed once it has been initialized. This applies to instance, static and local variables, including parameters that are declared final.

  • The final is the only modifier applicable to local variables or formal parameters.
  • A final variable of a primitive data type cannot change its value once it has been initialized.
  • A final variable of a reference type cannot change its reference value once it has been initialized, but the state of the object it denotes can still be changed.
  • Normally a final variable is initialized at the time of declaration but it is not must. Such a final variable is also called blank final variable, and must be initialized once before it is being used.
  • The final static variables are commonly used to define named constants, for example Integer.MAX_VALUE, which is the maximum int value.

2.2 local final variables

Example: The following example illustrates that local final variable can be left blank as discussed above but must be initialized before first use. The variable x is initialized just before displaying its value on the monitor.

class FinalTest //makes use of blank final

{ public static void main(String args[])

{ final int x;//initialization at declaration time not must

x = 50;

System.out.println(x);

}

}

Output:

50

The following program will not compile as final variable is initialized after first use.

class FinalTest

{ public static void main(String args[])

{ final int x; //blank final

System.out.println(x);

x = 50;

}

}

The following program will not compile as final variable is initialized twice.

class FinalTest

{ public static void main(String args[])

{ final int x;

x = 50;

System.out.println(x);

x = 60;

}

}

2.3 instance final variables

An instance final variable can be left blank but must be initialized before obtaining a reference of an object of the class containing final variable. So if we do not initialize at the time of declaration then the other places at which final variables can be initialized are:

  • Constructor

  • Initialization block

Example: The following program will not compile, as final variable is not initialized. The concept of initialization by default value is not applicable to final variables as they cannot be modified after initialization.

class FinalTest

{ final int x;//No default initialization for final instance variables

}

class MyClass

{

public static void main(String args[])

{ FinalTest f=new FinalTest();

}

}

Output: (Compile time error): variable x might not have been initialized

Example: The following program will also not compile, as final variable is initialized after obtaining a reference.

class FinalTest

{ final int x;

}

class MyClass

{ public static void main(String args[])

{ FinalTest f=new FinalTest();

System.out.println(f.x);

f.x = 10;

System.out.println(f.x);

}

}

Example: The following example illustrates that a blank final instance variable can be initialized in the constructor.

class FinalTest

{ final int x;

public static void main(String args[])

{ FinalTest f = new FinalTest();

}

FinalTest()

{ x = 10;

}

}

Output: 10

System.out.println(f.x);

Example: The following program illustrates that a blank final variable can be initialized with a dynamic value and can be referred with this keyword. So different objects of the same class can have different values of the final variable.


class FinalTest

{ final int x;

public static void main(String args[])

{ FinalTest f = new FinalTest(20);

}

FinalTest(int x)

{ this.x = x;

}

}

Output: 20

System.out.println(f.x);

Example: The following program illustrates that a final instance variable can be initialized in a initialization block.

class FinalTest

{ final int x;

public static void main(String args[])

{ FinalTest f = new FinalTest();

}

{

}

}

Output: 30

Initialization block

A java class can have one or more initialization blocks. The syntax of the initialization block is as follows:

{

code

}

An initialization block can be thought of as a constructor, which is invoked
implicitly/automatically as soon as the object is created. In fact if a class contains initialization

System.out.println(f.x);

x = 30;

blocks then they are executed in the order of definition from top to bottom before any constructor.

The initialization block can be useful in the following situations:

  • Dynamic initialization of instance variables.

  • For defining code which is common to all constructors. This will increase the code reusability and reduce maintenance.

2.4 static final variables

A static final variable can be left blank but must be initialized before class is available to the program. So if we do not initialize at the time of declaration then the only place at which static final variable can be initialized is:

  • static Initialization block
Example: The following example illustrates that the blank static final variable can be initialized in the static block.

class FinalTest

{ static final int x;

public static void main(String args[])

{

}

static

{

}

}

Output:

40

System.out.println(FinalTest.x);

x = 40;

2.7.2.5 final methods

  • A final method in a class is complete (i.e. has an implementation) and can not be overridden in any subclass. Subclasses are thus restricted in changing the behavior of the method.
  • The compiler is able to perform certain code optimizations for final methods, because certain assumptions can be made about such members. When a non-final method is invoked, the run time system determines the actual class of the object, binds the method invocation to the correct implementation of the method for that type, and then invokes the implementation. In case of a final method we are sure that sub-class can not override the method so the binding is done at the compile time as in case of private and static methods, which would definitely improve the performance.

  • In case of a final method the compiler may replace an invocation with the actual body of the method like Macro. This mechanism is known as ‘inlining’. In C++, we have the option of declaring a function as inline (although final decision is taken by the compiler) but in Java, the compiler takes the decision.

3. abstract modifier

The abstract modifier can be used only with instance methods. An abstract method does not have an implementation, that is, no method body is defined for an abstract method, only the method prototype is provided in the class definition. Its class is also abstract (i.e., incomplete) and must be explicitly declared as abstract. Subclasses of an abstract class must then provide the method implementation; otherwise, they are also abstract.

Here are some important points related to abstract methods:

  • An abstract method cannot be declared private. This is obvious as we can not override a private method, while in case of an abstract method body is always provided in the sub-class by over-riding the abstract method.

  • Only a non-static/instance method can be declared abstract since static methods cannot be overridden, declaring an abstract static method would make no sense and will result in compilation error.

  • Only an instance method can be declared abstract since static methods cannot be overridden, declaring an abstract static method would make no sense and will result in compilation error.

  • A final method cannot be abstract and vice-versa.

  • The keyword abstract cannot be combined with any non-accessibility modifiers for methods.

  • Methods specified in an interface are implicitly abstract, as only the method prototypes are defined in an interface.

4. synchronized modifier

The synchronized keyword can be used with methods and code blocks.

Several threads can execute simultaneously in a program. They might try to execute several methods on the same object simultaneously. If it is desired that only one thread at a time can execute a method in the object, the methods can be declared synchronized. Their execution is then mutually exclusive among all threads. At any given time, at most one thread can be executing a synchronized method on an object. This discussion also applies to static synchronized methods of a class. The detailed discussion is available in the chapter on multi-threading.

Example:

Suppose you have two threads that are responsible for updating a bank balance, called threads A and B. Suppose also that the account has $100 in it. Now simultaneously, thread A tries to deposit $50 in the account, while thread B tries to deposit $75. Both threads proceed to query the account balance. They both find it to be $100. Each of them independently, adds its deposit to the old sum and sets the new balance accordingly. If thread A finishes last, the account contains

$150. If thread B finishes last, the account balance is $175. Of course, neither of these new figures is correct. The account should have $225 in it (100+50+75). The problem is that both threads tried to execute the same code (querying and changing the balance) at the same time.

This is exactly the scenario that the synchronized keyword can prevent.

The synchronized modifier does not apply to classes or member variables.

5. native modifier

The native modifier can refer only to methods. Like the abstract keyword, native indicates that the body of a method is to be found elsewhere. The body of a native method is entirely outside the JVM, in a library.

Native code is written in a non-java language, typically C or C++, and compiled for a single target machine type. Thus Java’s platform independence is violated.

People who port Java to new platforms implement extensive native code to support GUI components, network communication, and a broad range of other platform-specific functionality.

However, it is rare for the application and applet programmers to need to write native code.

6. transient modifier

Objects can be stored using serialization. Serialization transforms objects into an output format that is conducive for storing objects. Objects can later be retrieved in the same state as when they were serialized, meaning that all fields included in the serialization will have the same values as at the time of serialization. Such objects are said to be persistent. A field can be specified as
transient in the class declaration, indicating that its value should not be saved when objects of the class are written to persistent storage.

Example:

class Experiment implements Serializable

{ transient int currentTemperature; //transient

double mass; //persistent value

}

Specifying the transient modifier for static variables is redundant and therefore, discouraged. The static variables are not part of the persistent state of a serialized object.

7. volatile modifier

During execution, compiled code might cache the values of fields for efficiency reasons. Since multiple threads can access the same field, it is vital that caching is not allowed to cause inconsistencies when reading and writing the value in the field.

The volatile modifier can be used to inform the compiler that it should not attempt to perform optimization on the field, which could cause unpredictable results when the field is accessed by multiple threads.

Monday, 8 June 2015

Java Other modifiers for interface members

Other modifiers for data members

Besides the visibility modifier public, we can also use modifiers static and final. Although we can use these modifiers but it is redundant as all data members are implicitly public, static and final.

Other modifiers for methods

Besides the visibility modifier public, we can also use modifier abstract. Although we can use abstract modifier but it is redundant as all methods are implicitly public, and abstract.

Java Other modifiers for top-level interfaces

(a) abstract

This is the only modifier other than visibility modifiers, which can be used with interface.

Interfaces just specify the method prototypes and not any implementation: they are, by their nature, implicitly abstract (i.e. they cannot be instantiated). We can declare an interface as abstract but it is redundant as interface is always abstract.

Java Other modifiers for top-level classes

Besides visibility modifiers, we can also use following modifiers before a top-class:

(a) abstract, and (b) final

(a) abstract

A class can be specified with the keyword abstract to indicate that it cannot be instantiated. A class containing abstract method must be declared as abstract otherwise it won’t compile. A class not containing any abstract method can also be declared abstract. Such a class can serve as a base class for a number of sub-classes.

(b) final

A class can be declared final to indicate that it cannot be extended. The final class marks the lower boundary of its implementation inheritance hierarchy. Only a class whose definition is complete can be declared final. A class cannot be both final and abstract at the same time.

Here are few important characteristics of the final class.

  • All the methods of a final class are also final i.e. they have the concrete implementation and cannot be over-ridden.
  • Some type checks become faster with final classes. In fact, many type checks become compile time checks and errors can be caught earlier. If the compiler encounters a reference to a final class, it knows that the object referred to is exactly of that type.

  • The compiler is able to perform certain code optimizations for final methods, because certain assumptions can be made about such members. When a non-final method is invoked, the run time system determines the actual class of the object, binds the method invocation to the correct implementation of the method for that type, and then invokes the implementation. In case of a final method we are sure that sub-class cannot override the method so the binding is done at the compile time as in case of private and static methods, which would definitely improve the performance.

  • In case of a final method the compiler may replace an invocation with the actual body of the method like Macro. This mechanism is known as ‘inlining’. In C++, we have the option of declaring a function as inline (although final decision is taken by the compiler) but in Java, the compiler takes the decision.

Java Member accessibility/visibility modifiers for interfaces

The only member accessibility/visibility modifier that can be used with data members and methods of an interface is public

The public is also the implicit accessibility/visibility modifier for interface members i.e. the members are always implicitly assumed to be public even if we do not use the modifier public.

Java Member accessibility/visibility modifiers for classes

By specifying member accessibility modifiers a class can control what information is accessible to clients (i.e. other classes). These modifiers help a class to define a contract so that clients know exactly what services are offered by the class.

Accessibility/visibility of members can be one of the following:

  • public
  • protected
  • default (also called package accessibility)
  • private

Note: Member accessibility modifier only has meaning if the class (or one of its subclasses) is accessible to the client. Also note that only one accessibility modifier can be specified for a member. The discussion applies to both instance and static members of classes.

Java Accessibility modifiers for Top-level classes and interfaces

  • public
  • default (package) accessibility

Sunday, 7 June 2015

Java Modifiers

Introduction

Modifiers are Java keywords that give the compiler information about the nature of code, data, classes or interfaces. For example, we have been using visibility modifiers public, private, protected, package etc. to specify the visibility of class members.  Beside visibility we have also used the modifiers static and abstract.

Classification

  • For the purpose of clear understanding, modifiers can be categorized as:
  • Accessibility modifiers for top-level classes and interfaces.
  • Member accessibility/visibility modifiers for classes.
  • Member accessibility/visibility modifiers for interfaces.
  • Other modifiers for top-level classes.
  • Other modifiers for top-level interfaces.
  • Other modifiers for interface members.
  • Other modifiers for class members.

Java Creating user-defined Exception/Error sub-classes

This is quite easy to do, just define a sub class of Exception/Error class. Your sub-classes do not need to actually implement anything. It is their existence in the type system that allows you to use them as exceptions/errors. The Exception/Error class does not define any methods of its own.

It does, of course, inherit methods provided by Thorwable class.

Extending RunTimeException or any of its sub-classes will create a user-defined unchecked-exception and extending Exception and any other sub-class of exception will create a user-defined checked-exception.  

Example: The following example demonstrates the use of a user-defined checked-exception.

class InvalidMarksException extends Exception

{ InvalidMarksException(String msg)

{ super(msg);

}

}

class MyExceptionDemo

{ static void dispGrade(int marks) throws InvalidMarksException

{ if(marks < 0 || marks > 100)

throw new InvalidMarksException

if(marks >= 75) System.out.println("S");

else if(marks >= 60) System.out.println("A");

else if(marks >= 50) System.out.println("B");

else if(marks >= 33) System.out.println("C");

else System.out.println("F");

("Marks should be in the range 0 to 100");

}

public static void main(String args[])

{ try

{ int marks = Integer.parseInt(args[0]);

dispGrade(marks);

}

catch(InvalidMarksException e)

{ System.out.println(e);

}

}

}


Example: The following example is rewritten here so as to display the marks entered as command line argument along with the error message.

class InvalidMarksException extends Exception

{ int marks;

InvalidMarksException(int marks, String msg)

{ super(msg);

}

public String toString()

{

}

}

class MyExceptionDemo1

{ static void dispGrade(int marks) throws InvalidMarksException

{ if(marks < 0 || marks > 100)

this.marks = marks;

return("InvalidMarksException["+marks+"]:"+getMessage());

throw new InvalidMarksException

if(marks >= 75) System.out.println("S");

else if(marks >= 60) System.out.println("A");

else if(marks >= 50) System.out.println("B");

else if(marks >= 33) System.out.println("C");

else System.out.println("F");

(marks, "Marks should be in the range 0 to 100");

}

public static void main(String args[])

{ try

{ int marks = Integer.parseInt(args[0]);

dispGrade(marks);

}

catch(InvalidMarksException e)

{ System.out.println(e);

}

}

}

Chained Exceptions

The chained exception feature allows you to associate another exception with an exception. This second exception describes the cause of the first exception. For example, imagine a situation in which a method throws an ArithmeticException because of an attempt to divide by zero.

However, the actual cause of the problem was that an I/O error occurred, which caused the divisor to be set improperly.

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.

To allow chained exceptions, Java 2, version 1.4 added two constructors and two methods to Throwable class. The constructors are shown here:

Throwable(Throwable causeExc)

Throwable(String msg, Throwable causeExc)

In the first form, causeExc is the exception that causes the current exception. That is, causeExc is the underlying reason that an exception occurred. The second form allows you to specify a description at the same time that you specify a cause exception. These two constructors have also been added to the Error, Exception, and RuntimeException classes.

The chained exception methods added to Throwable class are getCause() and init Cause():

Throwable getCause()

Throwable initCause(Throwable causeExc)

The getCause() method return the exception that underlies the current exception. If there is no underlying exception, null is returned. The initCause() method associates causeExc with the invoking exception and returns a reference to the exception. Thus, you can associate a cause with an exception after the exception has been created. However, the cause exception can be set only once. Thus, you can call initCause() only once for each exception object. Furthermore, if the
cause exception was set by a constructor, then you cannot set it again using initCause() method.

In general, initCause() is used to set a cause for legacy exception classes which do not support the two additional constructors described earlier. Most of Java's built-in exceptions do not define the additional constructors. Thus, you will use initCause() if you need to add an exception chain to these exceptions.

Chained exceptions are not something that every program will need. However, in chases in which knowledge of an underlying cause is useful, they offer an elegant solution.

Example:

class ChainExecDemo

{

static void demoproc()

{

NullPointerException e = new NullPointerException("top layer");

e.initCause(new ArithmeticException("Cause"));

throw e;

}

public static void main(String agrs[])

{

char a = 'a';

try

{

demoproc();

}

catch(NullPointerException e)

{

System.out.println(a);

System.out.println(e);

System.out.println("Original Cause : " +e.getCause());

}

}

}

Output:


Note: The NullPointerException constructor is not overloaded to receive cause so the only way to associate cause with it is to make use of initCause() method.

Java finally clause

finally creates a block of code that will be executed after a try/catch block has completed and before the code following the try/catch block.

The finally block will execute whether or not exception is thrown. If an exception is thrown, the finally block will execute even if no catch statement matches the exception.

Any time a method is about to return to the caller from inside a try/catch block, via an uncaught exception or an explicit return statement, the finally clause is also executed just before the method returns. This can be useful for closing file handlers and freeing up any other resources that might have been allocated at the beginning of a method with the intent of disposing of them before returning.

The finally clause is optional. However, each try statement requires at least one catch or a finally clause.

Example:

class FinallyDemo

{ static void procA()

{ try

{ System.out.println("inside procA()");

throw new RuntimeException("Demo");

}

finally

{ System.out.println("procA()'s finally"); }

}

static int procB()

{ try

{ System.out.println("inside procB()");

return(5);

}

finally

{ System.out.println("procB()'s finally"); return(10);

}

}

static void procC()

{ try

{ System.out.println("inside procC()"); }

finally

{ System.out.println("procC()'s finally"); }

}

public static void main(String args[])

{ try

{ procA(); }

catch(Exception e)

{ System.out.println("! Exception caught:"+e); }

int x = procB();

System.out.println("x= "+x);

procC();

}

}

Output:

inside procA()

procA()'s finally

! Exception caught:java.lang.RuntimeException: Demo

inside procB()

procB()'s finally

x= 10

inside procC()
procC()'s finally

Java throw statement

Example: Normally built-in exceptions are thrown by the JVM but user can also create and throw any exception although this is normally not done. The throw statement is needed for throwing user-defined exceptions, which is discussed in a later section.

The following program creates and throws an exception

class ThrowDemo {

static void demoproc() {

try {

int c = 0, a = 0;

if (a == 0)

int b = c / a;

} catch (ArithmeticException e) {

System.out.println("Caught inside demporoc.");

throw e;

}

throw new ArithmeticException("Division by zero");

}

public static void main(String args[]) {

try {

demoproc();

} catch (ArithmeticException e) {

System.out.println("Recaught: " + e);

}

}

}

Output:

Caught inside demporoc.

Recaught: java.lang.ArithmeticException: Division by zero

Example: The following example demonstrates that if a checked-exception is thrown using throw statement then it must either be caught or declared in the throws clause.

import java.io.*;

class ThrowsDemo {

static void throwOne() throws IOException {

System.out.println("inside throwOne");

throw new IOException("Demo");

}

public static void main(String args[]) {

}

}

Output: above program will not compile and result in following compile time error.

throwOne();


Example: The above example is re-written such that the method throwOne() is called in a try block.

import java.io.*;

class ThrowsDemo

{ static void throwOne() throws IOException

{ System.out.println("inside throwOne");

}

public static void main(String args[])

{ try

throw new IOException("Demo");

{ throwOne();

}

catch(IOException e)

{ e.printStackTrace();

}

}

}

Output: results in an exception at run-time.


Friday, 5 June 2015

Java Handling Checked Exceptions

Example: This program also handles the Checked Exceptions. The following program takes names of two files as input and copies the file specified by the first argument to the file specified by the second argument. The number of bytes copied are displayed in the finally block. So number of bytes copied will be displayed even if some abnormal condition terminates the program. The files are also closed in the finally block so that they will always be closed.

It has three handlers to handle the abnormal conditions:

  • One handler will print the usage of the program when the user does not provide both input and output file names.
  • The next handler will notify the user when the input file does not exist.
  • Another handler will print an error message when other I/O exceptions occur.
import java.io.*;

class MyCopy

{ public static void main(String args[])

{ int byte_count = 0;

byte buffer[] = new byte[512];

String input_file = null;

String output_file = null;

FileInputStream fin = null;

FileOutputStream fout = null;

try

{ input_file  = args[0];

output_file = args[1];

fin  = new FileInputStream(input_file);

fout = new FileOutputStream(output_file);

int bytes_in_one_read;

while((bytes_in_one_read = fin.read(buffer)) != -1)

{ fout.write(buffer,0,bytes_in_one_read);

}

}

catch(ArrayIndexOutOfBoundsException e)

{ System.out.println("Use:java MyCopy source target");

}

catch(FileNotFoundException e)//Checked Exception

{ System.out.println("Can't open input file:"+input_file);

}

byte_count = byte_count + bytes_in_one_read;

catch(IOException e) //Checked Exception

{ System.out.println("I/O Exception occurs");

}

finally

{ if(byte_count > 0)

if(fin != null)

if(fout != null)

}

System.out.println(byte_count + " bytes written");

fin.close();

fout.close();

} // end main

} // end class

Note:

1. FileNotFoundException and IOException are checked exceptions and must be handled.

2. It is possible that we handle only IOException as this will also indirectly handle the FileNotFoundException, which is its sub-class.

3. If both IOException and FileNotFoundException are handled then FileNotFoundException must be caught before IOException as it is sub-class of IOException.

Example: The previous example is rewritten to use method:

int copyFile(String input-file, String output-file)

We want that caller of this method should handle the abnormal conditions by itself. Method will not have any error handler for I/O Exception. A throws clause is added to the method declaration to indicate that method can throw exception and caller has to handle this exception. The caller can also throw the exception if it does not want to handle itself.

import java.io.*;

class MyCopy1

{ static FileInputStream fin = null;

static FileOutputStream fout = null;

public static int CopyFile(String input_file, String output_file)

{ int byte_count = 0;

throws IOException, FileNotFoundException

 fout = new FileOutputStream(output_file);

int bytes_in_one_read;

byte buffer[] = new byte[512];

fin  = new FileInputStream(input_file);

while((bytes_in_one_read = fin.read(buffer)) != -1)

{ fout.write(buffer,0,bytes_in_one_read);

byte_count = byte_count + bytes_in_one_read;

import java.io.*;

class MyCopy1

{ static FileInputStream fin = null;

static FileOutputStream fout = null;

public static int CopyFile(String input_file, String output_file)

{ int byte_count = 0;

throws IOException, FileNotFoundException

 fout = new FileOutputStream(output_file);

int bytes_in_one_read;

byte buffer[] = new byte[512];

fin  = new FileInputStream(input_file);

while((bytes_in_one_read = fin.read(buffer)) != -1)

{ fout.write(buffer,0,bytes_in_one_read);

byte_count = byte_count + bytes_in_one_read;

{ int a = args.length;

int b = 42/a;

System.out.println("a = " + a);

try

{ if(a == 1)

a = a/(a-a);

if(a == 2)

{

int c[] = {1};

c[42] = 99;

}

}

catch(ArrayIndexOutOfBoundsException e)

{ System.out.println("Array index out-of-bounds:"+e);

}

System.out.println("Outer Try");

}

catch(ArithmeticException e)

{ System.out.println(e);

}

System.out.println("After Outer Try");

}

}

Note: Nesting of try statement can occur in less obvious ways when method calls are involved.

For example, you can enclose a call to a method within a try block. Inside that method is another try statement. In this case, the try within the method is still nested inside the outer try block, which calls the method.

Example: Previous program is re-written so that the nested try block is moved inside the method nesttry().

class NestTry1

{ static void nesttry(int a)

{ try

{ if(a == 1)

if(a == 2)

{ int c[] = {1};

}

}

catch(ArrayIndexOutOfBoundsException e)

{

System.out.println("Array index out-of-bounds:" + e);

}

a = a/(a-a);

c[42] = 99;

}

public static void main(String args[])

{ try

{ int a = args.length;

int b = 42/a;

System.out.println("a = " + a);

nesttry(a);

}

catch(ArithmeticException e)

{

System.out.println(e);

}

}

}


Java Exception Handling Example

Example: This example demonstrates the action taken by the default error/exception handler when an exception/error occurs and is not handled.

class Exc0

{ public static void main(String args[])

{ int d = 0;

int a = 42/d;

System.out.println("This will not be printed");

}

}

When the Java run-time system detects the attempt to divide by zero, it constructs a new exception object and then throws this exception. This causes the execution of Exc0 class to stop,

because once an exception has been thrown, it must be caught by an exception handler and dealt with immediately.

In this example, we have not supplied any exception handlers of our own, so the default handler provided by the Java run-time system catches the exception. The default handler displays a string describing the exception, prints a stack trace from the point at which the exception occurred, and terminates the program.

Here is the output generated when this example is executed:

Exception in thread "main" java.lang.ArithmeticException: / by zero at Exc0.main(Exc0.java:4)

Example: This example demonstrates the action taken by the default error/exception handler when an exception/error occurs in a method other then main() and is not handled.

class Exc1

{ public static void subroutine()

{ int d = 0;

int a = 42/d;

}

public static void main(String args[])

{ Exc1.subroutine();

}

Output:

Exception in thread "main" java.lang.ArithmeticException: / by zero at Exc1.subroutine(Exc1.java:4) at Exc1.main(Exc1.java:7)

The resulting stack trace from the default exception handler shows how the entire call stack is displayed

System.out.println("This will not be printed");

Using try and catch

Although the default exception handler provided by the Java run-time system is useful for debugging, you will usually want to handle an exception yourself. Doing so provides two

benefits:

  • First, it allows you to fix the error
  • It prevents the program from automatically terminating

Example:

class Exc2

{ public static void main(String args[])

{ int d,a;

try

{ d = 0;

a = 42/d;

System.out.println("This will not be printed");

}

catch(ArithmeticException e)

{ //e.printStackTrace();

//System.out.println(e);

System.out.println(e.getMessage());

}

System.out.println("After catch statement");

}

}

Output

/ by zero
After catch statement

Note: The scope of the catch clause is restricted to those statements specified by the immediately preceding try statement. A catch statement can not catch an exception thrown by another try statement (except in the case of nested try statements). The statements that are protected by try must be surrounded by curly braces.

Example: This example demonstrates that we can continue execution after handling the exception and can execute the code of same try block again if it is part of a loop.

Recovery.java

import java.util.Random;

class HandleError

{

public static void main(String args[])

{

int a=0, b=0, c=0;

Random r = new Random();

for(int i=0; i < 5; i++)

{

try

{

b = r.nextInt();

c = r.nextInt();

System.out.println(b);

System.out.println(c);

a = 12345/ (b/c);

}catch(AirthmeticException e)

{ System.out.println(e.getMessage());

}

System.out.println("a : " + a);

}

a = 0;

}

}

Example:  The following example demonstrates the use of multiple catch clauses.

class MultiCatch

{ public static void main(String args[])

{ try

{ int a=args.length;

System.out.println("a = " + a);

int b = 42/a;

int c[] = {1};

c[42] = 99;

}

catch(ArithmeticException e)

{ System.out.println("Divide by 0: " + e);

}

catch(ArrayIndexOutOfBoundsException e)

{ System.out.println("Array Index Out Of Bound: " + e);

}

System.out.println("After try/catch blocks.");

}

}

Example: The following example throws four types of Runtime Exceptions:

  • ArithmeticException: integer division by zero.
  • NullPointerException: for accessing a field or invoking a method of a ‘null’ object.
  • ArrayIndexOutOfBoundsException: for accessing an array element by providing an index value less than zero or greater than or equal to array size.
  • StringIndexOutOfBoundsException: for accessing a character of a String or StringBuffer with index less than zero or greater than or equal to length of String.

class ExceptionTest

{ public static void main(String args[])

{ for(int i=0; i<4; i++)

{ int k = 0;

try

{ switch(i)

{ case 0: int zero = 0;

case 1: int b[] = null;

case 2: int[] c = new int[2];

case 3: char ch = "abc".charAt(3);

}

k = 911/zero;

break;

k = b[0];

break;

k = c[9];

break;

break;

}

catch (Exception e)

{ System.out.println(e);

}

}

}

}

Output:

java.lang.ArithmeticException: / by zero
java.lang.NullPointerException
java.lang.ArrayIndexOutOfBoundsException: 9
java.lang.StringIndexOutOfBoundsException: String index out of range: 3

Note: In the above example all the exceptions are handled using only one catch block. This is possible because all the exceptions are sub-classes of the Exception class.

Example: The previous example is slightly modified so that all the exceptions are handled separately. This approach allows us to take separate actions for each exception.

class ExceptionTest1

{ public static void main(String args[])

{ for(int i=0; i<4; i++)

{ int k = 0;

try

{ switch(i)

{ case 0: int zero = 0;

case 1: int b[] = null;

case 2: int[] c = new int[2];

case 3: char ch = "abc".charAt(3);

}

k = 911/zero;

break;

k = b[0];

break;

k = c[9];

break;

break;

}catch (ArithmeticException e)

{ System.out.println(e); }

catch (NullPointerException e)

{ System.out.println(e); }

catch (ArrayIndexOutOfBoundsException e)

{ System.out.println(e); }

catch (StringIndexOutOfBoundsException e)

{ System.out.println(e); }

}

}

}

Output:

java.lang.ArithmeticException: / by zero
java.lang.NullPointerException
java.lang.ArrayIndexOutOfBoundsException: 9
java.lang.StringIndexOutOfBoundsException: String index out of range: 3

Example: In case of multiple catches, exception subclasses must come before any of their super classes. This is because a catch statement that uses a super class will catch exceptions of that type plus any of its sub classes. Thus, a sub class would never be reached if it comes after its super class. Further, in java unreachable code is an error.

class ExceptionTest2

{ public static void main(String args[])

{ for(int i=0; i<4; i++)

{ int k = 0;

try

{ switch(i)

{ case 0: int zero = 0;

case 1: int b[] = null;

case 2: int[] c = new int[2];

case 3: char ch = "abc".charAt(3);

}

k = 911/zero;

break;

k = b[0];

break;

k = c[9];

break;

break;

}

catch (Exception e) //Will not compile

{ System.out.println(e);

}

catch (ArithmeticException e)

{ System.out.println(e);

}

}

}

}

Output:

ExceptionTest2.java:23: exception java.lang.ArithmeticException has already been caught

catch (ArithmeticException e)


Java Exception - throw Statement

It is possible for your program to throw an exception/error explicitly, using the throw statement.

The general form of throw is shown here:

throw ThrowableInstance;

Here, ThrowableInstance must be an object of type Throwable or a sub-class of Throwable.

Simple types, such as int or char as well as non-Throwable classes, such as String and Object, cannot be used as exceptions.

There are two ways you can obtain a Throwable object:
  • Using a parameter into a catch clause.
  • Creating one with the new operator.

Java Exception - throws clause

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.

A throws clause lists the types of exception that a method might throw.

This is necessary for all exceptions, except those of type Error or RuntimeException, or any of their subclasses. All other exceptions that a method can throw must be declared in the throws clause. If they are not, a compile-time error will result.

General form of method declaration that includes a throws clause is:

modifiers return-type method-name(parameter-list) throws Exception-list

{

//body of method

}

Here exception-list is a comma-separated list of exceptions that a method can throw.

Java Methods available in Throwable class


Java types of Exception

Exceptions can be categorized in two types:

  • Unchecked Exception
  • Checked Exception

Checked Exception

If it is must to check an exception then it is called a checked exception. The program will not compile if there is a possibility of occurring checked exception in a try block and it is not handled.

The compiler ensures that if a method can throw a checked exception, directly or indirectly, then the method must explicitly deal with it. The method must either catch the exception and take the appropriate action, or pass the exception on to its caller.

Note:
Exception and all of its sub-classes (Excluding RuntimeException and its sub-classes) are checked exceptions and must be caught.

Unchecked Exception

If it is not must to check an exception then it is called an unchecked exception. The program will compile even if the unchecked exception is not handled.

If any unchecked exception occurs in a program which is not handled then the program execution will terminate at that point. But if exception is handled then program will not terminate because of exception.

Note:
  • Error and all of its subclasses are unchecked exceptions and need not be caught.
  • RunTimeException and all of its sub-classes are unchecked exceptions and need not be caught.

Java Exception Handling Construct

Java exception/error handling is managed via five keywords: try, catch, throw, throws, and finally.

The general form of an exception-handling block is:

try

{

//block of code to be monitored for errors.

}

catch(ExceptionType1 exOb1)

{

//exception handler for ExceptionType1

}

catch(ExceptionType2 exOb2)

{

//exception handler for ExceptionType1

}

.

.

.

finally

{

//block of code to be executed before try block ends

}

The code, which is to be monitored for run-time errors, is put inside a try block. The try block must be enclosed between braces even if there is only one statement in it. There can be zero or more catch statements and zero or one finally statement. Both catch and finally blocks are optional but either one catch block or one finally block is must.

The code in the try block is executed like any other Java code. If the code inside the try block executes successfully then the control goes to finally block if it is present and then the execution continues from the statement just after the end of finally block (i.e. after the end of try statement). If the finally block is not present then the execution continues from the statement just after the last catch block (i.e. after the end of try statement).

If some run-time error occurs while executing the code in try block then JVM throws an Exception/Error. This means an object of type Exception/Error or one of its sub-classes is created depending on the type of the run-time error. This is then compared with the Exception/Error types of the catch blocks in top to bottom order. If a matching catch block is found then the exception/error is handled i.e. program will not terminate. The execution continues with the first statement in the catch block. On completion of the catch block, excution continues with the statement just after the end of try statement. At the most one catch block is executed irrespective of the number of catch blocks. On completion of the catch block, excution continues with the statement just after the end of try statement. At the most one catch block is executed irrespective of the number of catch blocks.

If exception/error does not match with exception/error type of any of the catch blocks, then we say that it is not handled. The execution will immediately return from try block. The code in the finally block will be executed even if the exception/error is not handled. The exception/error will then be handled by outer try block if there is one otherwise it must be handled in the method which called the current method. The exception/error percolates up the hierarchy till it is handled or it is passed to JVM unhandled if not handled even in the main() method which is the first method from which the execution starts. The JVM then simply terminates the program and displays the exception/error details on the monitor/console.



Java Hierarchy of Exception Classes

  • Exceptions/Errors are also objects in Java.
  • Root class of all exception/error classes is the Throwable class, which is an immediate sub-class of the Object class.
  • Methods are defined in Throwable class to retrieve error message associated with the error/exception and to print the stack trace showing where the error/exception occurs.
  • There are two immediate sub classes of class Throwable:
            o Error
            o Exception
  • Sub classes of Exception have the suffix Exception.
  • Sub classes of Error have the suffix Error (normally).

Error

The sub classes of Error class are basically used for signaling abnormal system conditions like:
  • OutOfMemoryError signals that the Java VM has run out of memory and that the garbage collector is unable to claim any free memory.
  • StackOverflowError signals a stack overflow in the interpreter.

The errors are, in general, unrecoverable and should not be handled.

Exception

The sub classes of Exception class are, in general recoverable. For example, EOFException signals that a file you have opened has no more data for reading. FileNotFoundException signals that a file you want to open does not exist in the file system.

Hierarchy of common Exceptions