J2SE


String constant pool
http://www.javaranch.com/journal/200409/Journal200409.jsp#a1
http://theopentutorials.com/tutorials/java/strings/string-literal-pool/



Java SE 7 Documentation http://www.indiabix.com/online-test/java-programming-test/

How to get no of days in a Month from a given date?

Ex:
Date date = new Date();
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
int noOfDaysInMonth = calendar.getActualMaximum(Calendar.DAY_OF_MONTH));


How is exception handling implemented in JVMs?

Exceptions are expensive and should be used exceptionally. In order top understand some of the issues involved; let us look at the mechanism used by the Java Virtual Machine (JVM) to handle the exceptions.

The JVM maintains a method invocation stack containing all the methods that have been invoked by the current thread in the reverse order of invocation. In other words, the first method invoked by the thread is at the bottom of the stack and the current method is at the top. Actually it is not the actual method that is present in the stack. Instead a stack frame representing the method is added to the stack. The stack frame contains the method’s parameters, return value, local variables and JVM specific information. When the exception is thrown in a method at the top of the stack, code execution stops and the JVM takes over.

The JVM searches the current method for a catch clause for the exception thrown or one of the parent classes of the thrown exception. If one is not found, then the JVM pops the current stack frame and inspects the calling method (the next method in the stack), for the catch clause for the exception or its parents. The process continues until the bottom of the stack is reached. In summary, it requires a lot of time and effort on the part of JVM.


Can we override static method in Java?
Many people have heard that you can't override a static method. This is true - you can't. However it is possible to write code like this:

class Foo {
    public static void method() {
        System.out.println("in Foo");
    }
}

class Bar extends Foo {
    public static void method() {
        System.out.println("in Bar");
    }
}
This compiles and runs just fine. Isn't it an example of a static method overriding another static method? The answer is no - it's an example of a static method hiding another static method. If you try to override a static method, the compiler doesn't actually stop you - it just doesn't do what you think it does.

So what's the difference?

Briefly, when you override a method, you still get the benefits of run-time polymorphism, and when you hide, you don't. So what does that mean? Take a look at this code:
class Foo {
    public static void classMethod() {
        System.out.println("classMethod() in Foo");
    }

    public void instanceMethod() {
        System.out.println("instanceMethod() in Foo");
    }
}

class Bar extends Foo {
    public static void classMethod() {
        System.out.println("classMethod() in Bar");
    }

    public void instanceMethod() {
        System.out.println("instanceMethod() in Bar");
    }
}
 
class Test {
    public static void main(String[] args) {
        Foo foo = new Bar();
        foo.instanceMethod();
        foo.classMethod();
    }
}
If you run the above program, the output is









Why do we get instanceMethod from Bar, but classMethod() from Foo?

Aren't we using the same instance foo to access both of these? Yes we are - but since one is overriding and the other is hiding, we see different behavior.

Since instanceMethod() is an instance method, in which Bar overrides the method from Foo, at run time the JVM uses the actual class of the instance foo to determine which method to run. Although foo was declared as a Foo, the actual instance we created was a new Bar(). So at runtime, the JVM finds that foo is a Bar instance, and so it calls instanceMethod() in Bar rather than the one in Foo. That's how Java normally works for instance methods.

With classMethod() though. since it's a class method, the compiler and JVM don't expect to need an actual instance to invoke the method. And even if you provide one (which we did: the instance referred to by foo) the JVM will never look at it. The compiler will only look at the declared type of the reference, and use that declared type to determine, at compile time, which method to call. Since foo is declared as type Foo, the compiler looks at foo.classMethod() and decides it means Foo.classMethod. It doesn't matter that the instance reffered to by foo is actually a Bar - for static methods, the compiler only uses the declared type of the reference. That's what we mean when we say a static method does not have run-time polymorphism.

Because instance methods and class methods have this important difference in behavior, we use different terms - "overriding" for instance methods and "hiding" for class methods - to distinguish between the two cases. And when we say you can't override a static method, what that means is that even if you write code that looks like it's overriding a static method (like the first Foo and Bar at the top of this page) - it won't behave like an overridden method.

So what about accessing a static method using an instance?

It's possible in Java to write something like:

foo.classMethod();

where foo is an instance of some class, and classMethod() is a class method (i.e. a static method) of that class. This is legal, but it's a bad idea because it creates confusion. The actual instance foo is not really important here. Only the declared type of foo matters. That is, what class is foo declared to be? Since classMethod() is static, the class of foo (as determined by the compiler at compile time) is all we need.

Rather than writing:

foo.classMethod();

It would be better coding style to write either:

Foo.classMethod();

(or)

Bar.classMethod();

That way, it is crystal clear which class method you would like to call. It is also clear that the method you are calling is indeed a class method.

Barring that, you could always come up with this monstrosity:

foo.getClass().getMethod("classMethod", new Class[]).invoke(null, new Object[]);

But all this could be avoided by simply not trying to override your static (class) methods. :-)

Why does the compiler sometimes talk about overriding static methods?

Sometimes you will see error messages from the compiler that talk about overriding static methods. Apparently, whoever writes these particular messages has not read the Java Language Specification and does not know the difference between overriding and hiding. So they use incorrect and misleading terminology. Just ignore it. The Java Language Specification is very clear about the difference between overriding and hiding, even if the compiler messages are not. Just pretend that the compiler said "hide" rather than "override"..


String literal vs. String object

1. Direct Method of creating String object

You've probably heard of the "String Literal Pool." What is the String Literal Pool? Most often, I hear people say that it is a collection of String objects. Although that's close, it's not exactly correct. "Really, it's a collection of references to String objects". Strings, even though they are immutable, are still objects like any other in Java. Objects are created on the heap and Strings are no exception. So, Strings that are part of the "String Literal Pool" still live on the heap, but they have references to them from the String Literal Pool.

Strings are immutable and can be shared without any data corruption. For example, if several reference variables refer to the same String object then it would be bad if any of them changes the String’s value. This is the reason for making String objects as immutable.

Take a look at this example:
public class ImmutableStrings
{
    public static void main(String[] args)
    {
        String one = "java";
        String two = "java";
        
        System.out.println(one.equals(two));
        System.out.println(one == two);
    }
}

//Output

true
true
In such a case, there is really no need to make two instances of an identical String object. If a String object could be changed, as a StringBuffer can be changed, we would be forced to create two separate objects. But, as we know that String objects cannot change, we can safely share a String object among the two String references, one and two. This is done through the String literal pool. Here's how it is accomplished:

When a .java file is compiled into a .class file, any String literals are noted in a special way, just as all constants are. When a class is loaded (note that loading happens prior to initialization), the JVM goes through the code for the class and looks for String literals. When it finds one, it checks to see if an equivalent String is already referenced from the heap. If not, it creates a String instance on the heap and stores a reference to that object in the constant table. Once a reference is made to that String object, any references to that String literal throughout your program are simply replaced with the reference to the object referenced from the String Literal Pool.

So, in the example shown above, there would be only one entry in the String Literal Pool, which would refer to a String object that contained the word "java". Both of the local variables, one and two, would be assigned a reference to that single String object. You can see that this is true by looking at the output of the above program. While the equals() method checks to see if the String objects contain the same data ("java"), the == operator, when used on objects, checks for referential equality - that means that it will return true if and only if the two reference variables refer to the exact same object. In such a case, the references are equal. From the above output, you can see that the local variables, one and two, not only refer to Strings that contain the same data, they refer to the same object.

Graphically, our objects and references would look something like this:



2. Creating String using constructor

Note, however, that this is a special behavior for String Literals. Constructing Strings using the "new" keyword implies a different sort of behavior. Let's look at an example:
Source Code
public class ImmutableStrings
{
    public static void main(String[] args)
    {
        String one = "java";
        String two = new String("java");
        
        System.out.println(one.equals(two));
        System.out.println(one == two);
    }
}

//Output

true
false            
In this case, we actually end up with a slightly different behavior because of the keyword "new." In such a case, references to the two String literals are still put into the constant table (the String Literal Pool), but, when you come to the keyword "new," the JVM is obliged to create a new String object at run-time, rather than using the one from the constant table.

In such a case, although the two String references refer to String objects that contain the same data, "java", they do not refer to the same object. That can be seen from the output of the program. While the equals() method returns true, the == operator, which checks for referential equality, returns false, indicating that the two variables refer to distinct String objects.

Once again, if you'd like to see this graphically, it would look something like this. Note that the String object referenced from the String Literal Pool is created when the class is loaded while the other String object is created at runtime, when the "new String..." line is executed.



If you'd like to get both of these local variables to refer to the same object, you can use the intern() method defined in String. Invoking two.intern() will look for a String object referenced from the String Literal Pool that has the same value as the one you invoked the intern method upon. If one is found, a reference to that String is returned and can be assigned to your local variable. If you did so, you'd have a picture that looks just like the one below, with both local variables, one and two, referring to the same String object, which is also referenced from the String Literal Pool. At that point, the second String object, which was created at run-time, would be eligible for garbage collection.



Strings Garbage Collection

An object is eligible for garbage collection when it is no longer referenced from an active part of the application. Anyone see what is special about garbage collection for String literals? Let's look at an example and see if you can see where this is going.

Source Code
public class ImmutableStrings
{
    public static void main(String[] args)
    {
        String one = "someString";
        String two = new String("someString");
        
        one = two = null;
    }
}           
Just before the main method ends, how many objects are available for garbage collection? 0? 1? 2?

The answer is 1. Unlike most objects, String literals always have a reference to them from the String Literal Pool. That means that they always have a reference to them and are, therefore, not eligible for garbage collection. This is the same example as I used above so you can see what our picture looked liked originally there. Once we assign our variables, one and two, to null, we end up with a picture that looks like this:



As you can see, even though neither of our local variables, one or two, refer to our String object, there is still a reference to it from the String Literal Pool. Therefore, the object is not elgible for garbage collection. The object is always reachable through use of the intern() method, as referred to earlier.

No comments:

Post a Comment