Sunday, 27 February 2011

Classloaders in java

Problems in java.util.Observable

Consider Observable pattern.

The way its implemented in java is full of flaws.

1. Observable is a class, not an interface, and worse, it doesn’t even implement an interface. Unfortunately, the java.util.Observable implementation has a number of problems that limit its usefulness and reuse. That’s not to say it doesn’t provide some utility, but there are some large potholes to watch out for. So from design point of view its bad in 2 ways:

   A) Because Observable is a class, you have to subclass it. That means you can’t add on the Observable behavior to an existing class that already extends another superclass. This limits its reuse potential (and isn’t that why we are using patterns in the first place?).
   B) Because there isn’t an Observable interface, you can’t even create your own implementation that plays well with Java’s built-in Observer API. Nor do you have the option of swapping out the java.util implementation for another (say, a new, multithreaded implementation).

2. Observable may serve your needs if you can extend java.util.Observable. On the other hand, you may need to roll your own implementation as we did at the beginning of the chapter. In either case, you know the Observer Pattern well and you’re in a good position to work with any API that makes use of the pattern.

3. If you look at the Observable API, the setChanged() method is protected. So what? Well, this means you can’t call setChanged() unless you’ve subclassed Observable. This means you can’t even create an instance of the Observable class and compose it with your own objects, you have to subclass. The design violates a second design principle here…favor composition over inheritance.

Java memory model

http://www.cs.umd.edu/users/pugh/java/memoryModel/
This is v.good material to follow java memory model.

Thursday, 24 February 2011

Java Serialization : Introduction

Introduction

Serialization is the process of saving an object in a storage medium (such as a file, or a memory buffer) or to transmit it over a network connection in binary form. The serialized objects are JVM independent and can be re-serialized by any JVM. In this case the "in memory" java objects state are converted into a byte stream. This type of the file can not be understood by the user. It is a special types of object i.e. reused by the JVM (Java Virtual Machine). This process of serializing an object is also called deflating or marshalling an object.

Note : Note that its ‘primary purpose’ is to write an object into a stream, so that it can be transported through a network and that object can be rebuilt again, but sometimes people use java serialization as a replacement for database, which is not our main motive. Just a placeholder where you can persist an object across sessions. This is not the primary purpose of java serialization. Sometimes, when I interview candidates for Java I hear them saying java serialization is used for storing (to preserve the state) an object and retrieving it. They use it synonymously with database. This is a wrong perception for serialization. Other ways you can leverage the feature of serialization is, you can use it to perform a deep copy.

You can see this tutorial for quick tutorial.

Overview

Serialization is the process of saving an object in a storage medium (such as a file, or a memory buffer) or to transmit it over a network connection in binary form. The serialized objects are JVM independent and can be re-serialized by any JVM. In this case the "in memory" java objects state are converted into a byte stream. This type of the file can not be understood by the user. It is a special types of object i.e. reused by the JVM (Java Virtual Machine). This process of serializing an object is also called deflating or marshalling an object. But when deserializing the object, the deserializer must know by some protocol how to deserialize. Here protocol means, understanding between serializing person and de-serializing person.

Implementation

For an object to be serialized, it must be an instance of a class that implements either the Serializable or Externalizable interface in java.io. Serializable is type of marker interface. Both interfaces only permit the saving of data associated with an object's variables. They depend on the class definition being available to the Java Virtual Machine at reconstruction time in order to construct the object.


The Serializable interface relies on the Java runtime default mechanism to save an object's state. Writing an object is done via the writeObject() method in the ObjectOutputStream class (or the ObjectOutput interface). Writing a primitive value may be done through the appropriate write<datatype>() method.

Reading the serialized object is accomplished using the readObject() method of the ObjectInputStream class, and primitives may be read using the various read<datatype>() methods.
What about other objects that may be referred to by the object we are serializing? For instance, what if our object is a Frame containing a set of (AWT) Panel and TextArea instance variables? Using the Serializable interface, these references (and their associated data) also are converted and written to the stream. All state information necessary to reconstruct our Frame object and any objects that it references gets stored together.
If those other objects or their formats weren't stored, our reconstructed Frame would contain null object references, and the content of those Panels and TextAreas would be gone. Plus, any methods that rely on the existence of the Panels or TextAreas would throw exceptions.
The Externalizable interface specifies that the implementing class will handle the serialization on its own, instead of relying on the default runtime mechanism. This includes which fields get written (and read), and in what order. The class must define a writeExternal() method to write out the stream, and a corresponding readExternal() method to read the stream. Inside of these methods the class calls ObjectOutputStream writeObject(), ObjectInputStream readObject(), and any necessary write<datatype>() and read<datatype>() methods, for the desired fields.
 

Hiding Data From Serialization

Sometimes you may wish to prevent certain fields from being stored in the serialized object. The Serializable interface allows the implementing class to specify that some of its fields do not get saved or restored. This is accomplished by placing the keyword transient before the data type in the variable declaration. For example, you may have some data which is confidential and can be re-read from a master file later (as opposed to saving it with the serialized object). Or you decide (wisely) to preserve the privacy of file references by declaring any such variables as transient. Otherwise, all fields automatically get written without any additional effort by the class.
In addition to those fields declared as transient, static fields are not serialized (written out), and so cannot be deserialized (read back in).
Another way to use Serializable, and control which fields get written, is to override the writeObject() method of the Serializable interface. Inside of this method, you are responsible for writing out the appropriate fields. If you take this approach, you will want to override readObject() as well, to control the restoration process. This is similar to using Externalizable, except that interface requires writeExternal() and readExternal().
For the Externalizable interface, since both writeExternal() and readExternal() must be declared public, this increases the risk that a rogue object could use them to determine the format of the serialized object. For this reason, you should be careful when saving object data with this interface.
It is worth considering the amount of security you need for any objects that you serialize. When reading them back in, all of the normal Java security checks (such as the bytecode verifier) are in effect. You can define certain values within the class that should remain intact in serialized objects. Perhaps they should contain a specific value, or a value within a particular range. You can easily check the value of any numeric variable read in from a serialized object, especially if you know that only a portion of the available range for that data type is used by your variable.
You can also encrypt the outgoing data stream. The implementation is up to you, and don't forget to decrypt the object format when reading it back in.

Versioning

Example of serialization:

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;

class SerializationBox implements Serializable {

private byte serializableProp = 10;

public byte getSerializableProp() {
return serializableProp;
}
}

public class SerializationSample {

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

SerializationBox serialB = new SerializationBox();
serialize("serial.out", serialB);
SerializationBox sb = (SerializationBox) deSerialize("serial.out");
System.out.println(sb.getSerializableProp());
}

public static void serialize(String outFile, Object serializableObject)
throws IOException {
FileOutputStream fos = new FileOutputStream(outFile);
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(serializableObject);
}

public static Object deSerialize(String serilizedObject)
throws FileNotFoundException, IOException, ClassNotFoundException {
FileInputStream fis = new FileInputStream(serilizedObject);
ObjectInputStream ois = new ObjectInputStream(fis);
return ois.readObject();
}
}

Format of a Serialized Object 
Conclusion
Adding object persistence to Java applications using serialization is easy. Serialization allows you to save the current state of an object to a container, typically a file. At some later time, you can retrieve the saved data values and create an equivalent object. Depending on which interface you implement, you can choose to have the object and all its referenced objects saved and restored automatically, or you can specify which fields should be saved and restored. Java also provides several ways of protecting sensitive data in a serialized object, so objects loaded from a serialized representation should prove no less secure than those classes loaded at application startup. Versioning provides a measure of the backward compatibility of class versions. The code needed to add serialization to your application is simple and flexible.

Some acronyms in java

JLS - Java Language Specification

Java Native methods

The Java native method is a great way to gain and merge the power of C or C++ programming into Java. To use Java as a scientific and high performance language, when efficient native Java compilers are not fully implemented, use native method can boost the performance to at least the speed of C compiled code.

1. Write the Java Code (Native Methods)

2. Compile the java code

Use the Java compiler to compile the Java class that you created in the previous step. At this time, you should also compile the main Java application that you wrote to test the native method.

3. Create the .h File

4. Create a Stubs File

5. Write the C Function

6: Create a Dynamically Loadable Library (Native Methods)

7. Run your application

 refer java docs for diagram and details.

4. Create a Stubs File

In addition to the .h file that you generated in the previous step, you must also use javah to generate a stub file. The stub file contains C code that provides the glue that holds the Java class and its parallel C structure together. To generate a stub file use javah's -stubs option. Again remember to run javah on the Java class.
By default, javah will place the resulting stub file in the same directory as the .class file. You can use the -d option to force javah to put the generated stub file in a different directory.
Similar to the .h file that javah generates, the name of the stubs file is the class name with .c appended to the end. In the "Hello World!" example that you've been working with throughout this lesson, the stub file is called HelloWorld.c : 

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <StubPreamble.h>

/* Stubs for class HelloWorld */
/* SYMBOL: "HelloWorld/displayHelloWorld()V", Java_HelloWorld_displayHelloWorld_stub */
stack_item *Java_HelloWorld_displayHelloWorld_stub(stack_item *_P_,struct execenv *_EE_) {
extern void HelloWorld_displayHelloWorld(void *);
(void) HelloWorld_displayHelloWorld(_P_[0].p);
return _P_;
}

For the moment, all you really need to know about the stub file is that you will later compile it into the dynamically loadable library that you create in Step 6: Create a Dynamically Loadable Library.

Generating a Stub


UNIX
% javah -stubs HelloWorld
DOS shell (Windows 95/NT)
C:\> javah -stubs HelloWorld

3. Create the .h File

In this step, you use the javah utility program to generate a C header file (a .h file) from the HelloWorld Java class. The header file defines a structure that represents the HelloWorld class on the C side, and provides a C function definition for the implementation of the native method displayHelloWorld() defined in that class.
Run javah now on the HelloWorld class that you created in the previous steps. For example, on UNIX you would issue the following command to your favorite shell tool.
% javah HelloWorld
By default, javah places the new .h file in the same directory as the .class file. You can tell javah to place the header files in a different directory with the -d option. The name of the header file is the Java class name with a .h appended to the end of it. For example, the command shown above will generate a file named HelloWorld.h.
eg. Content of javah file:

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <native.h>
/* Header for class HelloWorld */

#ifndef _Included_HelloWorld
#define _Included_HelloWorld

typedef struct ClassHelloWorld {
char PAD; /* ANSI C requires structures to have a least one member */
} ClassHelloWorld;
HandleTo(HelloWorld);

extern void HelloWorld_displayHelloWorld(struct HHelloWorld *);
#endif

The Class Structure

Look at the header file. Notice that it contains a struct definition for a structure named ClassHelloWorld. The members of this structure parallel the members of the corresponding Java class; that is to say, the fields in the struct correspond to instance variables in the class. But since HelloWorld doesn't have any instance variables, there is just a place holder in the structure. You can use the members of the struct to reference class instance variables from your C functions.

The Function Definition

In addition to the C structure that mimics the Java class, you will also notice a C function signature that looks like this:
extern void HelloWorld_displayHelloWorld(struct HHelloWorld *);
This is the definition for the C function that you will write in Step 5: Write the C Function that provides the implementation for the HelloWorld class's native method displayHelloWorld(). You must use this function signature when you write the implementation for the native method. If HelloWorld contained any other native methods, their function signatures would appear here as well. The name of the C function that implements the native method is derived from the package name, the class name, and the name of the Java native method. Thus, the native method displayHelloWorld() within the HelloWorld class becomes HelloWorld_displayHelloWorld(). In our example, there is no package name because HelloWorld is in the default package.
You will notice that the C function accepts a single parameter even though the native method defined in the Java class accepted none. You can think of the parameter as the "this" variable in C++. Our example ignores the "this" parameter. However, the next lesson, , describes how to access the data in the "this" parameter.

5. Write the C Function

Now, you can finally get down to the business of writing the implementation for the native method in C.
The function that you write must have the same function signature as the one you generated with javah into the HelloWorld.h file in Step 3: Create the .h File. The function signature generated for the HelloWorld class's displayHelloWorld() native method looks like this:
extern void HelloWorld_displayHelloWorld(struct HHelloWorld *);
Here's our implementation for HelloWorld_displayHelloWorld() which can be found in the file named HelloWorldImp.c.
#include &lt;StubPreamble.h&gt;
#include "HelloWorld.h"
#include &lt;stdio.h&gt;

void HelloWorld_displayHelloWorld(struct HHelloWorld *this) {
printf("Hello World!\n");
return;
}
As you can see, the implementation for HelloWorld_displayHelloWorld() is straightforward: the function uses the printf() function to display the string "Hello World!" and then returns. This file includes 3 C header files:
  • StubPreamble.h which provides enough information to the C code to interact with the Java runtime system. When writing native methods, you must always include this file in your C source files.
  • The .h file that you generated in Step 3: Create the .h File. This file contains the C structure that represents the Java class for which we are writing the native method and the function definition for the native method you are writing in this step.
  • The code snippet above also includes stdio.h because it uses the printf() function.

Running javah


UNIX
% javah HelloWorld
DOS shell (Windows 95/NT)
C:\> javah HelloWorld

Compiling Java Code


UNIX
% javac HelloWorld.java
% javac Main.java
DOS shell (Windows 95/NT)
C:\> javac HelloWorld.java
C:\> javac Main.java
Macintosh
[PENDING: Macintosh instructions]

1. Write the Java Code (Native Methods)

The following Java code segment defines a class named HelloWorld that has one method and a static code segment.
class HelloWorld {
public native void displayHelloWorld();

static {
System.loadLibrary("hello");
}
}

Define a Native Method

You can tell that the implementation for the HelloWorld class's displayHelloWorld() method is written in another programming language because of the native keyword that appears as part of its method definition:
public native void displayHelloWorld();
This method definition provides only the method signature for displayHelloWorld() and does not provide any implementation for it. The implementation for displayHelloWorld() is provided in a separate C language source file. The method definition for displayHelloWorld() also indicates that the method is a public instance method, accepts no arguments and returns no value. For more information about arguments to and return values from native methods see .
Like other methods, native methods must be defined within a Java class.

Load the Library

The C code that implements displayHelloWorld must be compiled into a dynamically loadable library (you will do this in Step 6: Create a Dynamically Loadable Library) and loaded into the Java class that requires it. Loading the library into the Java class maps the implementation of the native method to its definition. The following static code block from the HelloWorld class loads the appropriate library, named hello. The runtime system executes a class's static code block when it loads the class.
static {
System.loadLibrary("hello");
}
The loadLibrary() method is part of the System class.

Create the Main Program

In a separate source file, named Main.java, create a Java application that instantiates HelloWorld and calls the displayHelloWorld() native method.
class Main {
public static void main(String args[]) {
new HelloWorld().displayHelloWorld();
}
}
As you can see from the code sample above, you call a native method in the same manner as you call a regular method: just append the name of the method to the end of the object name with a period ('.'). A matched set of parentheses, ( and ), follow the method name and enclose any arguments to pass into the method. The displayHelloWorld() method doesn't take any arguments.

6: Create a Dynamically Loadable Library (Native Methods)

Remember in Step 1: Write the java Class that you use this method call to load a dynamically loadable library named hello into your program at runtime.
System.loadLibrary("hello");
Now you are ready to create the dynamically loadable library. Use the C compiler to compile the C source code created in the previous steps, HelloWorld.c and HelloWorldImp.c, into a dynamically loadable library named hello.

Type of classes

There can be many classification of classes:
1. Final
Base Class,
Derived Class
Value classes

Monday, 21 February 2011

Removing file extension java code

Armstrong Number Java Program

An Armstrong Number is one in which the sum of the individual numbers raised to the power of the number of words in that number is equal to that particular number itself. For example 1 raised to the power 1 is equal to 1, so it is an Armstrong Number. Again 153, implies 1 raised to the power 3, 5 raised to the power 3, and then 3 raised to the power 3 are added, then it gives 153 again, so it is also an Armstrong Number.
The Java Code is given below:-
////////////////////////////////////
package developer;
import java.util.Scanner;
public class ArmstrongNumber {
static double finalValue = 0;
public static void main(String[] args) {
int valueTaker = 0;
System.out.println("Enter a number to be checked for Armstrong Number: ");
Scanner armstScan = new Scanner(System.in);
if(armstScan.hasNextInt())
{
valueTaker = armstScan.nextInt();
}
StringBuffer sb = new StringBuffer().append(valueTaker);
double lengthSBKeeper = sb.length();
for(int lengthKeeper = 0; lengthKeeper < sb.length(); lengthKeeper++)
{
double zxc = Integer.parseInt(sb.substring(lengthKeeper, lengthKeeper+1));
finalValue = Math.pow(zxc, lengthSBKeeper) + finalValue;
}
if(finalValue == valueTaker)
{
System.out.println("The entered number "+valueTaker+" is an Armstrong Number");
}
else
{
System.out.println("The entered number is not an Armstrong Number");
}
}
}
///////////////////////////////////////

SCJP Useful Resources


Sunday, 20 February 2011

How Inner Classes Work in java


The preceding sections have explained the features and behavior of the various types of inner classes. Strictly speaking, that should be all you need to know about inner classes. In practice, however, some programmers find it easier to understand the details of inner classes if they understand how they are implemented.
Inner classes were introduced in Java 1.1. Despite the dramatic changes to the Java language, the introduction of inner classes did not change the Java Virtual Machine or the Java class file format. As far as the Java interpreter is concerned, there is no such thing as an inner class: all classes are normal top-level classes. In order to make an inner class behave as if it is actually defined inside another class, the Java compiler ends up inserting hidden fields, methods, and constructor arguments into the classes it generates. You may want to use the javap disassembler to disassemble some of the class files for inner classes so you can see what tricks the compiler has used to make inner classes work. (See Chapter 8, "Java Development Tools", for information on javap.)

3.13.1. Static Member Class Implementation

Recall our first LinkedStack example (Example 3-8), which defined a static member interface named Linkable. When you compile this LinkedStack class, the compiler actually generates two class files. The first one is LinkedStack.class, as expected. The second class file, however, is calledLinkedStack$Linkable.class. The $ in this name is automatically inserted by the Java compiler. This second class file contains the implementation of the static member interface.
As we discussed earlier, a static member class can access all the static members of its containing class. If a static member class does this, the compiler automatically qualifies the member access expression with the name of the containing class. A static member class is even allowed to access the privatestaticfields of its containing class. Since the static member class is compiled into an ordinary top-level class, however, there is no way it can directly access theprivate members of its container. Therefore, if a static member class uses a private member of its containing class (or vice versa), the compiler automatically generates non-private access methods and converts the expressions that access the private members into expressions that access these specially generated methods. These methods are given the default package access, which is sufficient, as the member class and its containing class are guaranteed to be in the same package.

3.13.2. Member Class Implementation

A member class is implemented much like a static member class. It is compiled into a separate top-level class file, and the compiler performs various code manipulations to make interclass member access work correctly.
The most significant difference between a member class and a static member class is that each instance of a member class is associated with an instance of the enclosing class. The compiler enforces this association by defining a synthetic field named this$0 in each member class. This field is used to hold a reference to the enclosing instance. Every member class constructor is given an extra parameter that initializes this field. Every time a member class constructor is invoked, the compiler automatically passes a reference to the enclosing class for this extra parameter.
As we've seen, a member class, like any member of a class, can be declared publicprotected, or private, or given the default package visibility. However, as I mentioned earlier, there have been no changes to the Java Virtual Machine to support member classes. Member classes are compiled to class files just like top-level classes, but top-level classes can only have public or package access. Therefore, as far as the Java interpreter is concerned, member classes can only have public or package visibility. This means that a member class declared protected is actually treated as a public class, and a member class declaredprivate actually has package visibility. This does not mean you should never declare a member class as protected or private. Although the interpreter cannot enforce these access control modifiers, the modifiers are noted in the class file. This allows any conforming Java compiler to enforce the access modifiers and prevent the member classes from being accessed in unintended ways.

3.13.3. Local and Anonymous Class Implementation

A local class is able to refer to fields and methods in its containing class for exactly the same reason that a member class can; it is passed a hidden reference to the containing class in its constructor and saves that reference away in a private field added by the compiler. Also, like member classes, local classes can useprivate fields and methods of their containing class because the compiler inserts any required accessor methods.
What makes local classes different from member classes is that they have the ability to refer to local variables in the scope that defines them. The crucial restriction on this ability, however, is that local classes can only reference local variables and parameters that are declared final. The reason for this restriction becomes apparent from the implementation. A local class can use local variables because the compiler automatically gives the class a private instance field to hold a copy of each local variable the class uses. The compiler also adds hidden parameters to each local class constructor to initialize these automatically created privatefields. Thus, a local class does not actually access local variables, but merely its own private copies of them. The only way this can work correctly is if the local variables are declared final, so that they are guaranteed not to change. With this guarantee, the local class can be assured that its internal copies of the variables are always in sync with the real local variables.
Since anonymous classes have no names, you may wonder what the class files that represent them are named. This is an implementation detail, but the Java compiler from Sun uses numbers to provide anonymous class names. If you compile the example shown in Example 3-11, you'll find that it produces a file with a name like LinkedStack$1.class. This is the class file for the anonymous class.

Java Development Tools


Local Classes

A local class is declared locally within a block of Java code, rather than as a member of a class.

Typically, a local class is defined within a method, but it can also be defined within a static initializer or instance initializer of a class. Because all blocks of Java code appear within class definitions, all local classes are nested within containing classes. For this reason, local classes share many of the features of member classes. It is usually more appropriate, however, to think of them as an entirely separate kind of inner class.
A local class has approximately the same relationship to a member class as a local variable has to an instance variable of a class.The defining characteristic of a local class is that it is local to a block of code. Like a local variable, a local class is valid only within the scope defined by its enclosing block.

Defining and Using a Local Class
// This method creates and returns an Enumeration object

public java.util.Enumeration enumerate() {
// Here's the definition of Enumerator as a local class
class Enumerator implements java.util.Enumeration {

Linkable current;
public Enumerator() { current = head; }
public boolean hasMoreElements() {
return (current != null);
}

public Object nextElement() {
if (current == null)
throw new java.util.NoSuchElementException();

Object value = current;
current = current.getNext();

return value;

}

}

// Now return an instance of the Enumerator class
//defined directly above
return new Enumerator();
}


Features of Local Classes
Local classes have the following interesting features:

  • Like member classes, local classes are associated with a containing instance, and can access any members, including private members, of the containing class.

  • In addition to accessing fields defined by the containing class, local classes can access any local variables, method parameters, or exception parameters that are in the scope of the local method definition and declared final.

Restrictions on Local Classes
Local classes are subject to the following restrictions:
  • A local class is visible only within the block that defines it; it can never be used outside that block.

  • Local classes cannot be declared public, protected, private, or static. These modifiers are for members of classes; they are not allowed with local variable declarations or local class declarations.

  • Like member classes, and for the same reasons, local classes cannot contain static fields, methods, or classes. The only exception is for constants that are declared both static and final.

  • Interfaces cannot be defined locally.

  • A local class, like a member class, cannot have the same name as any of its enclosing classes.

  • As noted earlier, a local class can use the local variables, method parameters, and even exception parameters that are in its scope, but only if those variables or parameters are declared final. This is because the lifetime of an instance of a local class can be much longer than the execution of the method in which the class is defined. For this reason, a local class must have a private internal copy of all local variables it uses (these copies are automatically generated by the compiler). The only way to ensure that the local variable and the private copy are always the same is to insist that the local variable is final.

New Syntax for Local Classes
In Java 1.0, only fields, methods, and classes can be declared final. The addition of local classes in Java 1.1 has required a liberalization in the use of the final modifier. It can now be applied to local variables, method parameters, and even the exception parameter of a catch statement. The meaning of the final modifier remains the same in these new uses: once the local variable or parameter has been assigned a value, that value cannot be changed.
Instances of local classes, like instances of member classes, have an enclosing instance that is implicitly passed to all constructors of the local class. Local classes can use the same this syntax as member classes, to refer explicitly to members of enclosing classes. Because local classes are never visible outside the blocks that define them, however, there is never a need to use the new and super syntax used by member classes to specify the enclosing instance explicitly.

Scope of a Local Class
In discussing member classes, we saw that a member class can access any members inherited from superclasses and any members defined by its containing classes. The same is true for local classes, but local classes can also access final local variables and parameters. The following code illustrates the many fields and variables that may be accessible to a local class:

class A { protected char a = 'a'; }
class B { protected char b = 'b'; }

public class C extends A {
// Private fields visible to local class
private char c = 'c';
public static char d = 'd';

public void createLocalObject(final char e)
{

final char f = 'f';
// i not final; not usable by local class
int i = 0;

class Local extends B
{

char g = 'g';
public void printVars()
{

// All of these fields and variables are accessible
//to this class

// (this.g) g is a field of this class
System.out.println(g);
// f is a final local variable
System.out.println(f);
// e is a final local parameter
System.out.println(e);
// (C.this.d) d -- field of containing class
System.out.println(d);
// (C.this.c) c -- field of containing class
System.out.println(c);
// b is inherited by this class
System.out.println(b);
// a is inherited by the containing class
System.out.println(a);

}

}

Local l = new Local(); // Create an instance of the local class
l.printVars(); // and call its printVars() method.

}

}


Local Classes and Local Variable Scope
A local variable is defined within a block of code, which defines its scope. A local variable ceases to exist outside of its scope. Java is a lexically scopedlanguage, which means that its concept of scope has to do with the way the source code is written. Any code within the curly braces that define the boundaries of a block can use local variables defined in that block.


Lexical scoping simply defines a segment of source code within which a variable can be used. It is common, however, to think of a scope as a temporal scope--to think of a local variable as existing from the time the Java interpreter begins executing the block until the time the interpreter exits the block. This is usually a reasonable way to think about local variables and their scope.
The introduction of local classes confuses the picture, however, because local classes can use local variables, and instances of a local class can have a lifetime much longer than the time it takes the interpreter to execute the block of code. In other words, if you create an instance of a local class, the instance does not automatically go away when the interpreter finishes executing the block that defines the class, as shown in the following code:
public class Weird {

// A static member interface used below

public static interface IntHolder { public int getValue(); }

public static void main(String[] args) {

// An array to hold 10 objects
IntHolder[] holders = new IntHolder[10];

for(int i = 0; i < 10; i++) { // Loop to fill the array up
final int fi = i; // A final local variable
// A local class
class MyIntHolder implements IntHolder {

public int getValue() { return fi; } // It uses the final variable

}

holders[i] = new MyIntHolder(); // Instantiate the local class

}

// The local class is now out of scope, so we can't use it. But
// we've got ten valid instances of that class in our array. The
//local variable fi is not in our scope here, but it is still
//in scope for the getValue() method of each of those ten objects.
//So call getValue() for each object and print it out.
//This prints the digits 0 to 9.

for(int i = 0; i < 10; i++)
System.out.println(holders[i].getValue());

}

}

The behavior of the previous program is pretty surprising. To make sense of it, remember that the lexical scope of the methods of a local class has nothing to do with when the interpreter enters and exits the block of code that defines the local class. Here's another way to think about it: each instance of a local class has an automatically created private copy of each of the final local variables it uses, so, in effect, it has its own private copy of the scope that existed when it was created.