Friday, 12 July 2013

Memory management & Garbage collection

Q1. How does Java allocate stack and heap memory?
Ans. Each time an object is created in Java it goes into the area of memory known as heap. The primitive variables like int and double are allocated in the stack (i.e. Last In First Out queue), if they are local variables and in the heap if they are member variables (i.e. fields of a class). In Java methods and local variables are pushed into stack when a method is invoked and stack pointer is decremented when a method call is completed. In a multi-threaded application each thread will have its own stack but will share the same heap. This is why care should be taken in your code to avoid any concurrent access issues in the heap space. The stack is thread-safe because each thread will have its own stack.

Q2. Is there any possible memory leak in Java?
Ans. Memory leak is unused but referenced part of the memory. Though GC takes care of cleaning up your memory/heap, but if you have used some native objects and forgot to reclaim the memory explicitly because that's anyway not going to be taken care by the GC (which takes care of heap memory management only).

Similarly, using 'static' also can be one of the potential reasons for memory leaks in Java. 'static' can't straightway be blamed for causing memory leaks; but if programmer has not taken care of the setting the references to 'null' explicitly after using the static objects then they can definitely cause memory leaks. Since 'static' members will by default live for the entire life of an app unless they are explicitly set to 'null'. So, always make it a point to nullify the references as soon as you reach at a point in your code where the use of the static member is over.

Ex: Suppose you have created a 'Statement' object from a DB Connection and the connection is a pooled one. Now as you know calling close() method on a pooled connection will not actually close the connection instead it will return the Connection object to the pool to be re-used. So, in such a case unless you explicitly close the 'Statement' object, it would keep consuming precious memory space for no real use. Now if you have declared the 'Statement' object as a static member, it'll be maintained in the memory for the entire life time of the app even when the control is out of the scope. Now that if your Statement object is non-static, it will eligible for garbage collection, once it is out-of-scope. However, there is still wastage of memory after using the Statement last and before reaching the end of the local scope.

Therefore, in summary we can say that one should/must :-

  • Always think if you really need to make this variable/member a 'static'.
  • Always try to confine the scope of an object to restrict its usage only to the section it's actually needed.
  • Always make a conscious effort to explicitly nullify objects once you finish using them (especially the large objects) 

Q3. Explain memory management in java.
Ans. In java, memory is managed via garbage collector. Few techniques for memory management are:
1. Reference Counting: A count of references to each object is maintained. When garbage collector runs, it deletes objects with zero reference count. 
Drawback: Circular references are maintained in memory.

2. Tracing collectors/Copy Collector/Stop and copy collector: Start from a root object and keep a track of all references which have direct/indirect reference to the root object. Then all the live objects are moved to another heap, taking care of references properly.
Drawback: At each point of time, you will have 2 heaps thus consuming twice the memory.

3. Mark sweep collectors/Stop and work collector: Similar to tracing collector except that instead of copying the references to the new heap, they are swept out of memory, after a list of live and dead objects is known.

Mark and sweep is a stop-the-world garbage collection technique; that is all application threads stop until garbage collection completes or until a higher-priority thread interrupts the garbage collector. If the garbage collector is interrupted it must restart which can lead to application thrashing with little apparent result.


Q4. Does Java have destructors?
Ans. Garbage collector does the job working in the background. Java does not have destructors; but it has finalizer that does a similar job. Syntax is 
      public void finalize() { } 

If an object has a finalizer, the method is invoked before the system garbage collects the object.

Q5. Does the finalize method in subclass invoke finalize method in super class?
Ans. Finalize is not implicitly chained. A finalize method in sub-class should call finalize in super class explicitly as its last action for proper functioning. Compilers don’t enforce this check.

Q6. Can finalize method be overloaded?
Ans. Yes but only the following version is called by garbage collector:
           protected void finalize() throws Throwable { };

Q7. Should I override finalize method?
Ans. Unlike C++ destructors, the finalize() method in Java is unpredictable, often dangerous and generally unnecessary. Use try and finally blocks while implementing finalize method. The finalize() method should only be used in rare instances as a safety net or to terminate non-critical native resources. If you do happen to call the finalize() method in some rare instances then remember to call the super.finalize() as shown below:


protected void finalize() throws Throwable {
      try {

            //finalize subclass state
      }

      finally {
            super.finalize();

      }
}

Q8. An object is resurrected by making other object refer to the dying object in finalize method. Will this object be ever garbage collected?
Ans. Resurrection can happen in finalize method which will prevent GC to reclaim the object memory. However this could be done only once. Next time GC will not invoke finalize method before garbage collection.

Well, the problem is that an object which overrides finalize() must now be determined to be garbage in at least two separate garbage collection cycles in order to be collected. When the first cycle determines that it is garbage, it becomes eligible for finalization. Because of the (slim, but unfortunately real) possibility that the object was "resurrected" during finalization, the garbage collector has to run again before the object can actually be removed. And because finalization might not have happened in a timely fashion, an arbitrary number of garbage collection cycles might have happened while the object was waiting for finalization. This can mean serious delays in actually cleaning up garbage objects, and is why you can get OutOfMemoryErrors even when most of the heap is garbage.

Q9. Explain types of references in Java? java.lang.ref package can be used to declare soft, weak and phantom references.
Ans. There are actually four different degrees of reference strength: strong, soft, weak, and phantom, in order from strongest to weakest:

Strong Reference: By default.

Weak references: A weak reference is a reference that isn't strong enough to force an object to remain in memory. Weak references allow you to leverage the garbage collector's ability to determine reachability for you, so you don't have to do it yourself. You create a weak reference like this:

WeakReference<Widget> weakWidget = new WeakReference<Widget>(widget);
weakWidget.get() // get the actual Widget

Of course the weak reference isn't strong enough to prevent garbage collection, so you may find (if there are no strong references to the widget) that weakWidget.get() suddenly starts returning null.

Soft references: A soft reference is exactly like a weak reference, except that it is less eager to throw away the object to which it refers. An object which is only weakly reachable (the strongest references to it are WeakReferences) will be discarded at the next garbage collection cycle, but an object which is softly reachable will generally stick around for a while. Soft References aren't required to behave any differently than WeakReferences, but in practice softly reachable objects are generally retained as long as memory is in plentiful supply. This makes them an excellent foundation for a cache, since you can let the garbage collector worry about both how reachable the objects are and how badly it needs the memory they are consuming.

Phantom references
A phantom reference is quite different than either SoftReference or WeakReference. Its grip on its object is so tenuous that you can't even retrieve the object -- its get() method always returns null. The only use for such a reference is keeping track of when it gets enqueued into a ReferenceQueue, as at that point you know the object to which it pointed is dead. How is that different from WeakReference, though?

The difference is in exactly when the enqueuing happens. WeakReferences are enqueued as soon as the object to which they point becomes weakly reachable. This is before finalization or garbage collection has actually happened. In case of Weak Reference, object could even be "resurrected" by an finalize() method, but the WeakReference would remain dead. PhantomReferences are enqueued only when the object is physically removed from memory, and the get() method always returns null specifically to prevent you from being able to "resurrect" an almost-dead object.

Use of Phantom Reference:
1. They allow you to determine exactly when an object was removed from memory. They are in fact the only way to determine that. This isn't generally that useful, but might come in handy in certain very specific circumstances like manipulating large images: if you know for sure that an image should be garbage collected, you can wait until it actually is before attempting to load the next image, and therefore make the dreaded OutOfMemoryError less likely.

2. PhantomReferences avoid a fundamental problem with finalization – resurrection. With PhantomReference, resurrection is impossible. When a PhantomReference is enqueued, there is absolutely no way to get a pointer to the now-dead object.Arguably, the finalize() method should never have been provided in the first place. PhantomReferences are definitely safer and more efficient to use, and eliminating finalize() would have made parts of the VM considerably simpler. But, they're also more work to implement, so I confess to still using finalize() most of the time. The good news is that at least you have a choice.

Q10. Talk about garbage collector for various references.
Ans. If an element is determined to be eligible for processing, GC must determine if it is eligible for collection. The first criterion here is simple. Is the referent marked? If it is marked, the reference object is not eligible for collection and GC moves onto the next element of the list. However, if the referent is not marked and is eligible for collection, the process differs for each reference type. 

Soft references are collected if their referent has not been marked for the previous 32 garbage collection cycles. You adjust the frequency of collection with the -Xsoftrefthreshold option. If there is a shortage of available storage, all soft references are cleared. All soft references are guaranteed to have been cleared before the OutOfMemoryError is thrown.


Weak and phantom references are always collected if their referent is not marked. 

Soft vs Weak vs Phantom References




Type
Purpose
Use
When GCed
Implementing Class
Strong Reference
An ordinary reference. Keeps objects alive as long as they are referenced.
normal reference.
Any object not pointed to can be reclaimed.
default
Soft Reference
Keeps objects alive provided there’s enough memory.
to keep objects alive even after clients have removed their references (memory-sensitive caches), in case clients start asking for them again by key.
After a first gc pass, the JVM decides it still needs to reclaim more space.
java.lang.ref.SoftReference
Weak Reference
Keeps objects alive only while they’re in use (reachable) by clients.
Containers that automatically delete objects no longer in use.
After gc determines the object is only weakly reachable
java.lang.ref.WeakReference 
java.util.WeakHashMap
Phantom Reference
Lets you clean up after finalization but before the space is reclaimed (replaces or augments the use of finalize())
Special clean up processing
After finalization.
java.lang.ref.PhantomReference

Q11. Explain garbage collection on Remote Objects or Distributed Garbage collection. 
Ans. In a distributed system, just as in the local system, it is desirable to automatically delete those remote objects that are no longer referenced by any client. This frees the programmer from needing to keep track of the remote objects' clients so that it can terminate appropriately. RMI uses a reference-counting garbage collection algorithm for the same. 

To accomplish reference-counting garbage collection, the RMI runtime keeps track of all live references within each Java virtual machine. When a live reference enters a Java virtual machine for first time, it sends a "referenced" message to the server for the object. Going forward, whenever a live reference enters JVM, its reference count is incremented and is decremented as soon as it leaves the JVM. When the last reference has been discarded, an unreferenced message is sent to the server. Many subtleties exist in the protocol; most of these are related to maintaining the ordering of referenced and unreferenced messages in order to ensure that the object is not prematurely collected. 

When a remote object is not referenced by any client, the RMI runtime refers to it using a weak reference. The weak reference allows the Java virtual machine's garbage collector to discard the object if no other local references to the object exist. As long as a local reference to a remote object exists, it cannot be garbage-collected and it can be passed in remote calls or returned to clients. Remote objects are only collected when no more references, either local or remote, still exist. The distributed garbage collection algorithm interacts with the local Java virtual machine's garbage collector in the usual ways by holding normal or weak references to objects. 

In addition to the reference counting mechanism, a live client reference has a lease with a specified time. When the client is done with the reference and allows the remote stub to go out of scope, or when the lease on the object expires, the reference layer on the host automatically deletes the record of the remote reference and notifies the client's reference layer that this remote reference has expired. The lease time is controlled by the system property java.rmi.dgc.leaseValue. The value is in milliseconds and defaults to 10 minutes. The concept of expirable leases, as opposed to strict on/off references, is used to deal with situations where a client-side failure or a network failure keeps the client from notifying the server that it is done with its reference to an object.

A remote object needing unreferenced notification must implement the java.rmi.server.Unreferenced interface. When those references no longer exist, the unreferenced method will be invoked.

Q12. Does OutOfMemoryError and StackOverFlowError cause JVM crash?
Ans. Any problem in PURE Java code throws a Java exception or error. Java exceptions or errors will NOT cause a core dump (on UNIX systems) or a Dr.Watson error (on WIN32systems). Any serious Java problem will result in an OutOfMemoryError thrown by the JVM with the stack trace and consequently JVM will exit. An OutOfMemoryError (not jvm crash) can be thrown due to one of the following 4 reasons:

1. JVM may have a memory leak due to a bug in its internal heap management implementation. But this is highly unlikely because JVMs are well tested for this.

2. The application may not have enough heap memory allocated for its running. You can allocate more JVM heap size (with –Xmx parameter to the JVM) or decrease the amount of memory your application takes to overcome this. You can increase heap size as below:
          java -Xms1024M -Xmx1024M

Care should be taken not to make the –Xmx value too large because it can slow down your application.

3. Another not so prevalent cause is the running out of a memory area called the “perm” which sits next to the heap. All the binary code of currently running classes is archived in the “perm” area. The ‘perm’ area is important if your application or any of the third party jar files you use dynamically generate classes.
For example: “perm” space is consumed when XSLT templates are dynamically compiled into classes, J2EE application servers, JasperReports, JAXB etc use Java reflection to dynamically generate classes and/or large amount of classes in your application. To increase perm space:
     java -XX:PermSize=256M -XX:MaxPermSize=256M

4. The fourth and the most common reason is that you may have a memory leak in your application.

Q13. Different OutOfMemory errors.
Ans. Let’s have a look at the Sun HotSpot JVM and its concrete implementation of OutOfMemoryError errors.

1.    In the heap we get an OutOfMemoryError, if the garbage collector cannot reclaim enough memory for a new object. In such situation the Sun HotSpot JVM shows this error message:
               java.lang.OutOfMemoryError: Java heap space

2.    An alternative for this is as below, it occurs when application tries to create an array on the heap that is bigger than the total heap size.
             java.lang.OutOfMemoryError: Requested array size exceeds VM limit

3.    If there is not enough memory in the method area for creating a new class, the Sun HotSpot implementation gets an error in the permanent generation:
             java.lang.OutOfMemoryError: PermGen space

4.    OutOfMemory errors in thread exclusive memory areas occur less frequently and are identified by the following error messages in the Sun HotSpot JVM:
              java.lang.OutOfMemoryError: unable to create new native thread

This occurs if there are too many threads in the JVM and there is not enough memory left to create a new thread. I’ve seen this because the memory limits of a process have been reached (especially in 32bit operating systems, e.g. on Windows 32bit it is 2GB) or the maximum number of file handles for the user that executes the java process has been reached.

5.    It indicates that a memory allocation error on a native stack (JNI method call) has occured.
               java.lang.OutOfMemoryError: <reason> <stacktrace> (Native method)

6.    It is also interesting that a memory allocation error on the JVM stack (too many frames on the stack) does not throw an Java OutOfMemory error but as the JVM specification mandates.
                java.lang.StackOverflowError

7.    The last variant of the OutOfMemoryError is out of swap space. This error is thrown if there is not enough memory left on the operating system level – which is normally true if other processes are using all of the available memory or the swap space is configured too small.
                 java.lang.OutOfMemoryError: request <size> bytes for <reason>. 

Q14. Why does the JVM crash with a core dump or a Dr.Watson error?
Ans. Both the core dump on UNIX operating system and Dr.Watson error on WIN32 systems mean the same thing. If you define a crash as an unhandled problem (i.e. no Java Exception or Error); then this cannot be done from within Java. The JVM is a process like any other and when a process crashes a core dump is created. A core dump is a memory map of a running process. This can happen due to one of the following reasons:

1. Using JNI (Java Native Interface) code containing a fatal bug in it. Typical crashes in native code happen by dereferencing pointers to wrong memory areas (like Nullpointer) or illegal opcodes.
For ex: using Oracle OCI drivers, which are written partially in native code or JDBC-ODBC bridge drivers, which are written in non Java code. Using 100% pure Java drivers (communicates directly with the database instead of through client software utilizing the JNI) instead of native drivers can solve this problem.

2. The OS on which your JVM is running might require a patch or service pack.

3. The JVM implementation may have a bug in translating system resources like threads, file handles, sockets etc from the platform neutral Java byte code into platform specific operations. If this JVM’s translated native code performs an illegal operation then the operating system will instantly kill the process and mostly will generate a core dump file.

The core dump files are generated by the operating system in response to certain signals. The JVM can also intercept certain signals like SIGQUIT which is kill -3 <pid> from the operating system and it responds to this signal by printing out a Java stack trace and then continue to run. On the other hand signals like SIGSTOP (kill -23 <pid>) and SIGKILL (kill -9 <pid>) will cause the JVM process to stop or die. The JVM argument "java –Xsqnopause" will indicate JVM not to pause on SIGQUIT signal from OS.

4. On Linux/Unix, it is easy to crash JVM crash by sending it a Signal to the running process.

Note: You should not use "SIGSEGV" for this, since JVM catches this signal and re-throws it as a NullPointerException in most places. So it is better to send a SIGBUS.

Sunday, 7 July 2013

Nested and Inner classes

Q1. What is static class? Why would you need a static class?
Ans. First of all, a top level class can't be static. The compiler will detect and report this error. Thus only an inner class can be declared static, which is known as nested class.

Nested top-level classes are typically used as a convenient way to group related classes without creating a new package. If your main class has a few smaller helper classes that can be used outside the class and make sense only with your main class, it's a good idea to make them nested (top-level) classes.


NOTE: A static class can have non-static members and methods.


Q2. What is the difference b/w a nested class and inner class.
Ans. Static inner classes are known as nested classes and non-static inner classes are known as inner class.

Nested class:
As with class methods and variables, a static nested class is associated with its outer class. Nested class cannot refer directly to instance variables or methods defined in its enclosing class — it can use them only through an object reference. Static nested classes are accessed using the enclosing class name, i.e. OuterClass.StaticNestedClass


For example, to create an object for the static nested class, use following:
    OuterClass.StaticNestedClass nestedObject = new OuterClass.StaticNestedClass();


Inner class:

As with instance methods and variables, an inner class is associated with an instance of its enclosing class and has direct access to that object's methods and fields. Also, because an inner class is associated with an instance, it cannot define any static members itself.

Objects that are instances of an inner class exist within an instance of the outer class. Consider the following classes:class OuterClass {
     ...
     class InnerClass {          ...

     }
}
To instantiate an inner class, you must first instantiate the outer class. Then, create the inner object within the outer object with this syntax:
     OuterClass.InnerClass innerObject = outerObject.new InnerClass()


Q3. How do you get a reference to outer class in inner class and declare an object of inner class.
Ans. Using .this and .new.

Inside inner class, this would refer to inner class itself, so you access the outer class as “OuterClassName.this”

And to create an object of inner use .new i.e “o.new Iclass”
     where o is object of outer class Oclass and Iclass is inner class of outer class Oclass.

Q4. What are various types of inner classes?
Ans.
1. Anonymous: Anonymous classes are declared and instantiated within the same statement. They do not have names, and they can be instantiated only once. Since an anonymous class doesn't have a normal class declaration where it's possible to use static, it cannot be declared static.

2. Local: Local classes are the same as local variables, in the sense that they're created and used inside a block. Once you declare a class within a block, it can be instantiated as many times as you wish within that block. Like local variables, local classes aren't allowed to be declared public, protected, private, or static.

3. Member: Member classes are defined within the body of a class. You can use member classes anywhere within the body of the containing class. You declare member classes when you want to use variables and methods of the containing class without explicit delegation.

The member class is the only class that you can declare static (which when declared static is known as nested class). 

4. Nested top-level: A nested top-level class is a member classes with a static modifier. 

Q5. How is local inner class different from anonymous class and which one you should chose?
Ans. Local inner class has a name associated (inside a method only), whereas anonymous class doesn't. Since the name of the local inner class is not accessible outside the method, the only justification for using a local inner class instead of an anonymous inner class is if you need a named constructor and/or an overloaded constructor, since an anonymous inner class can only use instance initialization.

Another reason to make a local inner class rather than an anonymous inner class is if you need to make more than one object of that class. 


NOTE: Arguments passed to a method are accessible to local inner or anonymous class only if argument is being passed as final.


Q6. Anonymous inner class, 
            as return new Contents { ......};
Ans. What this strange syntax means is "Create an object of an anonymous class that’s inherited from Contents." The reference returned by the new expression is automatically upcast to a Contents reference.

Q7. Can inner classes be overridden?
Ans. There isn’t any extra inner-class magic going on when you inherit from the outer class. The two inner classes are completely separate entities, each in its own namespace. So, it’s still possible to explicitly inherit from the inner class.

Q8. Can you define constructors for inner classes?
Ans. Yes, but only when inner class has a name. Since anonymous classes don’t have a name, it is not possible to have a constructor. In such cases, instance initializer acts as constructor ( i.e code inside curly braces in class body). The only drawback in this case is that you can't have overloaded constructors, which is possible in case of named inner classes.

Q9. Can inner class have static members?
Ans. No

Q10. Where should you use inner classes?
Ans. Code without inner classes is more maintainable and readable. When you access private data members of the outer class, the JDK compiler creates package-access member functions in the outer class for the inner class to access the private members. This leaves a security hole. In general we should avoid using inner classes. Use inner class only when an inner class is only relevant in the context of the outer class and/or inner class can be made private so that only outer class can access it. Inner classes are used primarily to implement helper classes like Iterators, Comparators etc which are used in the context of an outer class.

Q11. Why do we need inner classes?
Ans.In case of multiple inheritance, you can inherit from only one implementation (class) and rest has to be interface.

Inner classes solve this issue, when Outer class O extends an implementation (class A) and inner class I extends other one (class B). Each inner class can independently inherit from an implementation. Thus, the inner class is not limited by whether the outer class is already inheriting from an implementation.


Interfaces solve part of the problem of multiple inheritance, but inner classes effectively allow "multiple implementation inheritance." That is, inner classes effectively allow you to inherit from more than one non-interface. Also, inner classes help us to have closure and callback functionality. 


A closure is a callable object that retains information from the scope in which it was created. An inner class is an object-oriented closure, because it doesn’t just contain each piece of information from the outer-class object ("the scope in which it was created"), but it automatically holds a reference back to the whole outer-class object, where it has permission to manipulate all the members, even private ones.


With a callback, some other object is given a piece of information that allows it to call back into the originating object at some later point. One of the most compelling arguments made to include some kind of pointer mechanism in Java was to allow callbacks.


Wednesday, 3 July 2013

Exceptions

Q1. Tell us the exception class hierarchy.
Ans.



Q2. Difference between checked exceptions and unchecked exceptions?

Ans. There are 3 kinds of exceptions:
1. The first kind of exception is the checked exception. These are exceptional conditions that a well-written application should anticipate and recover from. All exceptions are checked exceptions, except for those indicated by Error, RuntimeException, and their subclasses. Ex. FileNotFoundException

2. The second kind of exception is the error. These are exceptional conditions that are external to the application, and that the application usually cannot anticipate or recover from. Ex: Suppose that an application successfully opens a file for input, but is unable to read the file because of a hardware or system malfunction.

3. These are exceptional conditions that are internal to the application. These usually indicate programming bugs, such as logic errors or improper use of an API. The cost of checking for the runtime exception often outweighs the benefit of catching it. Ex: Null PointerException is a RunTime Exception.

Consider the application described previously that passes a file name to the constructor for FileReader. If a logic error causes a null to be passed to the constructor, the constructor will throw NullPointerException. The application can catch this exception, but it probably makes more sense to eliminate the bug that caused the exception to occur.


Q3. What is an Error in java and how is it different from Exception?
Ans.
1. Exceptions are those which can be handled at the run time with try-catch-finally blocks where as errors cannot be handled. 
  Ex: Array out of bonds, attempt to divide by zero etc.

2. You can anticipate RunTime Exceptions but not errors. Error may be due to I/O, logical error, etc. This causes your program to halt and you can't continue after that.

Errors are exceptional conditions that are external to the application, and that the application usually cannot anticipate or recover from.

For example, suppose that an application successfully opens a file for input, but is unable to read the file because of a hardware or system malfunction. The unsuccessful read will throw java.io.IOError. An application might choose to catch this exception, in order to notify the user of the problem — but it also might make sense for the program to print a stack trace and exit.

An Error is a subclass of Throwable that indicates serious problems that a reasonable application should not try to catch. Most such errors are abnormal conditions. The ThreadDeath error, though a "normal" condition, is also a subclass of Error because most applications should not try to catch it.

A method is not required to declare in its throws clause any subclasses of Error that might be thrown during the execution of the method but not caught, since these errors are abnormal conditions that should never occur.

Q4. What is exception specification and do we need to specify RunTimeException in that?
Ans. Telling what type of exceptions a method can throw is exception specification.
ex: method throws type1, type2, type3

You need not specify RunTimeException in exception specification. RuntimeException (or anything inherited from it) is a special case, since the compiler doesn’t require an exception specification for these types. The output is reported to System.err.

If a RuntimeException gets all the way out to main() without being caught, printStackTrace() is called for that exception as the program exits.

Keep in mind that only exceptions of type RuntimeException (and subclasses) can be ignored in your coding, since the compiler carefully enforces the handling of all checked exceptions. The reasoning is that a RuntimeException represents a programming error.


Q5. Can you declare to throw an exception but still not throw it?
Ans. You can claim to throw an exception that you really don’t. The compiler takes your word for it, and forces the users of your method to treat it as if it really does throw that exception. This has the beneficial effect of being a placeholder for that exception, so you can actually start throwing the exception later without requiring changes to existing code. It’s also important for creating abstract base classes and interfaces whose derived classes or implementations may need to throw exceptions.

Q6. Can I use throws Error or throws Throwable clause. If yes, what are the advantages of same?
Ans. Yes, I can use throws Error and throws Throwable clause. However, there is no use/advantage of same. One should try to catch exceptions as specific as possible.

You should catch errors, only if you can handle them. Normally errors are due to I/O errors or external to application, thus they should be allowed to go to main program and shouldn't be caught. Similarly saying throws Throwable will force to catch all kinds of exceptions and errors.


Q7. Exception Restriction
Ans.When you override a method, you can throw only the exceptions that have been specified in the base-class version of the method. Although exception specifications are enforced by the compiler during inheritance, the exception specifications are not part of the type of a method, which comprises only the method name and argument types. Therefore, you cannot overload methods based on exception specifications. In addition, just because an exception specification exists in a base-class version of a method doesn’t mean that it must exist in the derived-class version of the method. This is quite different from inheritance rules, where a method in the base class must also exist in the derived class. Put another way, the "exception specification interface" for a particular method may narrow during inheritance and overriding, but it may not widen—this is precisely the opposite of the rule for the class interface during inheritance.


Points:
1. Interface CANNOT add exceptions to existing methods from the base class. i.e if a method is defined in a class and an interface, another class is extending and implementing, method signature will be taken from class and not interface.

2. Overridden methods can throw inherited exceptions. Thus, when you put the reference in derived class object itself, handle inherited Exception. However, if put the object reference in base class object; you should catch base class Exception as per the exception specification in base class method.

3. The restriction on exceptions does not apply to constructors. Derived class constructor can throw anything it wants, regardless of what the base-class constructor throws. However, since a base-class constructor must always be called one way or another, the derived-class constructor must declare any base-class constructor exceptions in its exception specification.

4. A derived-class constructor cannot catch exceptions thrown by its base-class constructor.


Q8. Exception arguments

Ans. There are two constructors in all standard exceptions: The first is the default constructor, and the second takes a string argument (i.e a message) so that you can place pertinent information in the exception:
      throw new NullPointerException("t = null");

Q9. Talk about try-catch-finally block.
Ans. try-block would of course be started first and executed till any exception or a control transfer statement is encountered. If it's an exception, the control would go to catch and subsequently to finally to complete the execution. If it's a control transfer (like a return, break, continue, etc.), then the control transfer statement is evaluated and kept in a pending state. Once the finally is executed, then the runtime sees if finally-block has any valid control transfer statement or not and if found then the pending control transfer statement is forgotten and the one present in finally is actually executed. In case finally-block doesn't have any control transfer statement then the pending one i.e. from try or catch block whichever is latest, is executed and mind you it's not re-evaluated. 

Ex: In a normal case if we have a statement like 'return i*i', since this is a complex statement involving an expression hence the expression would first be evaluated and once evaluation is complete then the value would replace the placeholder originally occupied by the expression. For example: if i = 10, then 'return i*i' would become 'return 100' and now this statement doesn't have any reference to 'i' to have any other value change in future. The pending control transfer statement would always be in a ready-to-run shape and it would not have any reference to any variable and hence any change to 'i' in the finally block would not affect the value associated with the pending 'return' statement.


Q10. Can a catch block have multiple arguments.
Ans. No. Each catch clause (exception handler) is like a little method that takes one and only one argument of a particular type. Though we can have multiple catch blocks for multiple exceptions.

Q11. Describe guarded region and exception handler.
Ans. Guarded region is a section of code that might produce exceptions and is followed by the code to handle those exceptions. Exception handler, in other words, is catch block.

Q12. Exception Handler block.
Ans. This is catch block.

catch( Type1 id1) {

     .......
}

catch (Type2 id2) {     ........
}


The identifier (id1, id2, and so on) can be used inside the handler, just like a method argument. Sometimes you never use the identifier because the type of the exception gives you enough information to deal with the exception, but the identifier must still be there.


Q13. Is it possible to not execute the finally block?
Ans. If the JVM exits while the try or catch code is being executed, then the finally block may not execute. Likewise, if the thread executing the try or catch code is interrupted or killed, the finally block may not execute even though the application as a whole continues. The only time finally won't be called is if you call System.exit() or if the JVM crashes first.

Q14. Exception Chaining
Ans. Often you want to catch one exception and throw another, but still keep the information about the originating exception — this is called exception chaining

Prior to JDK 1.4, programmers had to write their own code to preserve the original exception information. Only Throwable subclasses that provide the cause argument in the constructor are the three fundamental exception classes:

Error (used by the JVM to report system errors), Exception, and RuntimeException.If you want to chain any other exception types, you do it through the initCause() method rather than the constructor.

// Using initcause to set an exception as causeDynamicFieldsException dfe = new DynamicFieldsException();
dfe.initCause(new NullPointerException());
throw dfe;

// using constructor to set an exception as causecatch(NoSuchFieldException e) {
     throw new RuntimeException(e); 

          // This was not possible before JDK 1.4, as that is user defined exception.
}

However, now all Throwable subclasses have the option to take a cause object in their constructor. The cause is intended to be the originating exception, and by passing it in you maintain the stack trace back to its origin, even though you’re creating and throwing a new exception


Q15. StackTrace. ie. printStackTrace()
Ans. Information provided by printStackTrace( ) can also be accessed directly using getStackTrace( ). This method returns an array of stack trace elements, each representing one stack frame. Element zero is the top of the stack, and is the last method invocation in the sequence (the point this Throwable was created and thrown). The last element of the array and the bottom of the stack is the first method invocation in the sequence.

for(StackTraceElement ste : e.getStackTrace())

     System.out.println(ste.getMethodName());

Q16. Describe default printStackTrace behaviour.
Ans. By default, the information is sent to System.err. Default version is e.printStackTrace();and others are:
void printStackTrace(PrintStream)
void printStackTrace(java.io.PrintWriter)

Ex:
MyException: Originated in g()
at FullConstructors.g(FullConstructors.java:15)
at FullConstructors.main(FullConstructors.java:24)

where MyException -> Exception Name
Originated in g() -> Message while exception was created
And rest is stacktrace.

Q17. fillInStackTrace
Ans. The line where fillInStackTrace( ) is called becomes the new point of origin of the exception.

If you simply rethrow the current exception, the information that you print about that exception in printStackTrace( ) will pertain to the exception’s origin, not the place where you rethrow it. If you want to install new stack trace information, you can do so by calling fillInStackTrace( ), which returns a Throwable object that it creates by stuffing the current stack information into the old exception object. Here’s what it looks like:
     throw (Exception)e.fillInStackTrace();


Q18. How can I find caller method/object of a calling method?
Ans. 
1. Using getStackTrace on current thread (since Java 1.5) – 
        StackTraceElement[] stackTraceElements = Thread.currentThread().getStackTrace()
2. Calling getStackTrace on a Throwable instance (since Java 1.4) - Creating an instance of Throwable and then calling getStackTrace()method on it. 
      StackTraceElement[] ste = new Throwable().getStackTrace();
3. Using native method (like getCallerClass method) of some JVM implementation specific classes. We should avoid such a practice as we may otherwise sacrifice the portability of the code.

Potential Problem with #1 and #2: In certain situations, few JVM implementations may either omit one or more stack frames from the stack trace or they might not have any stack frame info at all related to this Throwable instance as a JVM implementation is allowed to return a zero-length array by Java language specs.

Another possible issue is that compile-time inlining may show skewed results. Say if a method A internally calls another method B and B calls C. Let's suppose the method B has no other executable statement. Obviously this will be a good candidate for compile time inlining as the compiler might replace the call to method B inside method A definition with a call to method C. In such cases, the above two approaches will return the caller method of method C as method A and not as method B what the source code might suggest. Please note that this will require you to turn on the optimization of the compiler. Results may vary across compilers as different compilers may have different criteria for inlining - some might never do.


Threading, Synchronization

Q1. Explain transient modifier.
Ans. When an instance variable is declared as transient, then its value need not persist when an object is stored. For example: file handle, a database connection, a system thread etc.
class T {
     transient int a; // will not persist
     int b; // will persist}


Such objects are only meaningful locally. So they should be marked as transient in a serializable class.

Q2. Can a method be static and synchronized?
Ans. A static method can be synchronized. If you do so, the JVM will obtain a lock on the java.lang.Class instance associated with the object. It is similar to saying:
               synchronized(XYZ.class) { ....}

Q3. How to make thread safe singleton.
Ans.
1. Synchronize the getInstance() method.

2. Second approach to thread safety declares a constant Singleton attribute on the Singleton class itself:public class Singleton {
      public final static Singleton instance = new Singleton();
      private Singleton() {};

      public static void main( String [] args ) {
            Singleton instance = Singleton.instance;            // ...
      }
}
Variable “instance” will be initialized when the class loads. 

3. Third approach is to use synchronized block
public class ExampleSingleton {
      private static ExampleSingleton instance;

      public static ExampleSingleton getInstance() {

            // non-synchronized to prevent locking in case instance has already been created
            if ( instance == null ) {
                  synchronized( ExampleSingleton.class ) {

                        // Synchronized to prevent pre-emption and checking for is-nullable again
                        // to ensure that object is not created and not in stage of creation)
                        if ( instance == null ) { 
                             instance = new ExampleSingleton();
                        }
                  }//sync ends
            }
            return instance;
      }
}