Showing posts with label core java concept. Show all posts
Showing posts with label core java concept. Show all posts

Tricky Overloading in Core java | Method overloading concept in java

Choosing the Most Specific Method - Tricky Method Overloading

Let's start with looking at a code-segment and try to think of the output/error, it would produce when compiled/executed and subsequently we'll discuss the behavior of code.


public class NullTest {

   public static void method(Object obj){
     System.out.println("method with param type - Object");
   }
 
   public static void method(String obj){
     System.out.println("method with param type - String");
   }
 
   public static void main(String [] args){
     method(null);
   }
}

So, what do you expect as the output here? Before thinking about the output, do you really expect the code to compile successfully? Well... yeah, the code will compile and run fine as opposed to anyone who might have sensed an ambiguity here - we'll see the reason soon.

Since the methods are overloaded, the resolution will be done at compile-time only. Which method do you see being bind here - the one with parameter type 'Object' or the one with parameter type 'String' and why? Of course, the compiler can't bind two methods with one call, so on what basis would it pick the most suitable? Which method would be picked, is evident from the output given below:-


method with param type - String

Any guesses for why a special treatment is being given to 'String' here? Well... it's not actually for 'String' class specifically, but any sub-class would get a preference over the super class in such a situation. But, why? Because JLS (Section: 15.12.2.5) allows this. It clearly says:

"If more than one member method is both accessible and applicable to a method invocation, it is necessary to choose one to provide the descriptor for the run-time method dispatch. The Java programming language uses the rule that the most specific method is chosen."

As you easily deduce that the compiler should be able to pick 'the most specific', failing which it will throw a compile-time error. Let's understand it with the below code-segment which doesn't compile because the compiler can't pick 'the most specific' here.


public class NullTest {

   public static void method(Object obj){
     System.out.println("method with param type - Object");
   }
 
   public static void method(String str){
     System.out.println("method with param type - String");
   }
 
   public static void method(StringBuffer strBuf){
     System.out.println("method with param type - StringBuffer");
   }
 
   public static void main(String [] args){
     method(null); //... compile-time error!
   }
}

Why is the compiler not able to pick 'the most specific' here - because both String and StringBuffer are are sub-classes of the Object class, but without being in the same inheritance hierarchy. For finding 'the most specific' method, the compiler needs to find a method having the parameter type, which is a sub-class of the parameter types of all other overloaded methods.

This holds true for overloaded methods having more than one parameters as well. The compiler would pick 'the most specific' by looking which method is having at least one of its parameter types as a clear sub-class of the corresponding parameter type and other parameter types being either the same or clear sub-classes, in all other overloaded methods. If it can find one, good, otherwise it will throw a compile-time error. For example:


public class NullTest {

 public static void method(Object obj, Object obj1){
   System.out.println("method with param types - Object, Object");
 }

 public static void method(String str, Object obj){
   System.out.println("method with param types - String, Object");
 }

 public static void main(String [] args){
   method(null, null);
 }
}

Output

method with param types - String, Object

In this case the compiler can easily pick 'the most specific' as the method having parameter types (String, Object) as the other overloaded method is having its parameter types as (Object, Object) - clearly 'String' is a subclass of 'Object' and the other parameter is of same type, so the method with parameter types (String, Object) can be picked with ease. But, the below code would throw a compile-time error as none of the methods satisfy the condition for being picked as 'the most specific' method.


public class NullTest {

 public static void method(Object obj, String obj1){
   System.out.println("method with param types - Object, String");
 }

 public static void method(String str, Object str1){
   System.out.println("method with param types - String, Object");
 }

 public static void main(String [] args){
   method(null, null); //... compile-time error!
 }
}


HashMap working concept in Java | how hashMap internally working

How HashMap works in Java or sometime how get method work in HashMap is common interview questions now days. Almost everybody who worked in Java knows what hashMap is, where to use hashMap or difference between hashtable and HashMap then why this interview question becomes so special? Because of the breadth and depth this question offers. It has become very popular java interview question in almost any senior or mid-senior level java interviews.

Questions start with simple statement

"Have you used HashMap before" or "What is HashMap? Why do we use it “

Almost everybody answers this with yes and then interviewee keep talking about common facts about hashMap like hashMap accpt null while hashtable doesn't, HashMap is not synchronized, hashMap is fast and so on along with basics like its stores key and value pairs etc.
This shows that person has used hashMap and quite familiar with the functionality HashMap offers but interview takes a sharp turn from here and next set of follow up questions gets more detailed about fundamentals involved in hashmap. Interview here you and come back with questions like

"Do you Know how hashMap works in Java” or
"How does get () method of HashMap works in Java"

And then you get answers like I don't bother its standard Java API, you better look code on java; I can find it out in Google at any time etc.
But some interviewee definitely answer this and will say "HashMap works on principle of hashing, we have put () and get () method for storing and retrieving data from hashMap. When we pass an object to put () method to store it on hashMap, hashMap implementation calls
hashcode() method hashMap key object and by applying that hashcode on its own hashing funtion it identifies a bucket location for storing value object , important part here is HashMap stores both key+value in bucket which is essential to understand the retrieving logic. if people fails to recognize this and say it only stores Value in the bucket they will fail to explain the retrieving logic of any object stored in HashMap . This answer is very much acceptable and does make sense that interviewee has fair bit of knowledge how hashing works and how HashMap works in Java.
But this is just start of story and going forward when depth increases a little bit and when you put interviewee on scenarios every java developers faced day by day basis. So next question would be more likely about collision detection and collision resolution in Java HashMap e.g

"What will happen if two different objects have same hashcode?”

Now from here confusion starts some time interviewer will say that since Hashcode is equal objects are equal and HashMap will throw exception or not store it again etc. then you might want to remind them about equals and hashCode() contract that two unequal object in Java very much can have equal hashcode. Some will give up at this point and some will move ahead and say "Since hashcode () is same, bucket location would be same and collision occurs in hashMap, Since HashMap use a linked list to store in bucket, value object will be stored in next node of linked list." great this answer make sense to me though there could be some other collision resolution methods available this is simplest and HashMap does follow this.
But story does not end here and final questions interviewer ask like

"How will you retreive if two different objects have same hashcode?”
 Hmmmmmmmmmmmmm
Interviewee will say we will call get() method and then HashMap uses keys hashcode to find out bucket location and retrieves object but then you need to remind him that there are two objects are stored in same bucket , so they will say about traversal in linked list until we find the value object , then you ask how do you identify value object because you don't value object to compare ,So until they know that HashMap stores both Key and Value in linked list node they won't be able to resolve this issue and will try and fail.

But those bunch of people who remember this key information will say that after finding bucket location , we will call keys.equals() method to identify correct node in linked list and return associated value object for that key in Java HashMap. Perfect this is the correct answer.

In many cases interviewee fails at this stage because they get confused between hashcode () and equals () and keys and values object in hashMap which is pretty obvious because they are dealing with the hashcode () in all previous questions and equals () come in picture only in case of retrieving value object from HashMap.
Some good developer point out here that using immutable, final object with proper equals () and hashcode () implementation would act as perfect Java HashMap keys and improve performance of Java hashMap by reducing collision. Immutability also allows caching there hashcode of different keys which makes overall retrieval process very fast and suggest that String and various wrapper classes e.g Integer provided by Java Collection API are very good HashMap keys.

Now if you clear all this java hashmap interview question you will be surprised by this very interesting question "What happens On HashMap in Java if the size of the Hashmap exceeds a given threshold defined by load factor ?". Until you know how hashmap works exactly you won't be able to answer this question.
if the size of the map exceeds a given threshold defined by load-factor e.g. if load factor is .75 it will act to re-size the map once it filled 75%. Java Hashmap does that by creating another new bucket array of size twice of previous size of hashmap, and then start putting every old element into that new bucket array and this process is called rehashing because it also applies hash function to find new bucket location.

If you manage to answer this question on hashmap in java you will be greeted by "do you see any problem with resizing of hashmap in Java" , you might not be able to pick the context and then he will try to give you hint about multiple thread accessing the java hashmap and potentially looking for race condition on HashMap in Java.

So the answer is Yes there is potential race condition exists while resizing hashmap in Java, if two thread at the same time found that now Java Hashmap needs resizing and they both try to resizing. on the process of resizing of hashmap in Java , the element in bucket which is stored in linked list get reversed in order during there migration to new bucket because java hashmap doesn't append the new element at tail instead it append new element at head to avoid tail traversing. if race condition happens then you will end up with an infinite loop. though this point you can potentially argue that what the hell makes you think to use HashMap in multi-threaded environment to interviewer :)

I like this question because of its depth and number of concept it touches indirectly, if you look at questions asked during interview this HashMap questions has verified
Concept of hashing
Collision resolution in HashMap
Use of equals () and hashCode () method and there importance?
Benefit of immutable object?
race condition on hashmap in Java
Resizing of Java HashMap

Just to summarize here are the answers which does makes sense for above questions

How HashMAp works in Java
HashMap works on principle of hashing, we have put () and get () method for storing and retrieving object form hashMap.When we pass an both key and value to put() method to store on HashMap, it uses key object hashcode() method to calculate hashcode and they by applying hashing on that hashcode it identifies bucket location for storing value object.
While retrieving it uses key object equals method to find out correct key value pair and return value object associated with that key. HashMap uses linked list in case of collision and object will be stored in next node of linked list.
Also hashMap stores both key+value tuple in every node of linked list.

What will happen if two different HashMap key objects have same hashcode?
They will be stored in same bucket but no next node of linked list. And keys equals () method will be used to identify correct key value pair in HashMap.

In terms of usage HashMap is very versatile and I have mostly used hashMap as cache in electronic trading application I have worked . Since finance domain used Java heavily and due to performance reason we need caching a lot HashMap comes as very handy there.






Multiple Scenario of try , catch and finally in exception handling in java

Following Below multiple scenario question related to try, catch and finally block in exception handling in java
Scenario #1: try throwing an exception; catch and finally both having return statements


public class TestFinally {

/**
* @param args
*/
public static void main(String[] args) {

System.out.println("Inside main method!");
int iReturned = new TestFinally().testMethod();
System.out.println("Returned value of i = " + iReturned);

}

public int testMethod(){

int i = 0;
try{
 System.out.println("Inside try block of testMethod!");
 i = 100/0;
 return i;
}catch(Exception e){
 System.out.println("Inside catch block of testMethod!");
 i = 200;
 return i;
}
finally{
 System.out.println("Inside finally block of testMethod!");
 i = 300;
 return i;
}
}
}


Output: a return (or any control transfer for that matter) in finally always rules!



Inside main method!
Inside try block of testMethod!
Inside catch block of testMethod!
Inside finally block of testMethod!
Returned value of i = 300


Scenarios #2: try having exception-free code and a return; catch and finally both have return




...
try{
System.out.println("Inside try block of testMethod!");
i = 100;
return i;
}catch(Exception e){
System.out.println("Inside catch block of testMethod!");
i = 200;
return i;
}
finally{
System.out.println("Inside finally block of testMethod!");
i = 300;
return i;
}
...


Output: did you get the first one right? This is a cakewalk then. With the same logic that any control transfer in finally always rules we can easily predict the output to be similar to that of Scenario #1 with the only difference that in this case the catch block won't be executed as no exception thrown... all right? Here is the output:



Inside main method!
Inside try block of testMethod!
Inside finally block of testMethod!
Returned value of i = 300


Scenario #3: try having exception; finally doesn't have a return



...
try{
System.out.println("Inside try block of testMethod!");
i = 100/0;
return i;
}catch(Exception e){
System.out.println("Inside catch block of testMethod!");
i = 200;
return i;
}
finally{
System.out.println("Inside finally block of testMethod!");
i = 300;
//return i;
}
...


Output: no return in finally means whatever executable return encountered on the way to finally will be executed once finally completes its execution, so the output would be:



Inside main method!
Inside try block of testMethod!
Inside catch block of testMethod!
Inside finally block of testMethod!
Returned value of i = 200


Scenario #4: try and catch both having exception; finally having a return



...
try{
System.out.println("Inside try block of testMethod!");
i = 100/0;
return i;
}catch(Exception e){
System.out.println("Inside catch block of testMethod!");
i = 200/0;
return i;
}
finally{
System.out.println("Inside finally block of testMethod!");
i = 300;
return i;
}
...


Output: control transfer in finally overrules the exceptions thrown in try/catch, hence the output would be:



Inside main method!
Inside try block of testMethod!
Inside catch block of testMethod!
Inside finally block of testMethod!
Returned value of i = 300


Scenario #5: try and catch both having exception; finally NOT having any return



...
try{
System.out.println("Inside try block of testMethod!");
i = 100/0;
return i;
}catch(Exception e){
System.out.println("Inside catch block of testMethod!");
i = 200/0;
return i;
}
finally{
System.out.println("Inside finally block of testMethod!");
i = 300;
//return i;
}
...


Output: since no return in finally, hence after the execution of the finally block the sheer need to have an executable return statement (which doesn't exist in this case as catch also has an exception) would throw the exception encountered right before the finally execution started, which would be the exception in catch block in our case...right? So, the output would be:



Exception in thread "main" java.lang.ArithmeticException: / by zero
 at TestFinally.testMethod(TestFinally.java:24)
 at TestFinally.main(TestFinally.java:10)
Inside main method!
Inside try block of testMethod!
Inside catch block of testMethod!
Inside finally block of testMethod!


Scenario #6: try, catch, and finally all three having exceptions



...
try{
System.out.println("Inside try block of testMethod!");
i = 100/0;
return i;
}catch(Exception e){
System.out.println("Inside catch block of testMethod!");
i = 200/0;
return i;
}
finally{
System.out.println("Inside finally block of testMethod!");
i = 300;
return i/0;
}
...


Output: evidently the exception would be thrown, but which one? The one which was encountered last i.e., the one encountered in the finally block. Output would be:



Inside main method!
Inside try block of testMethod!
Inside catch block of testMethod!
Inside finally block of testMethod!
Exception in thread "main" java.lang.ArithmeticException: / by zero
 at TestFinally.testMethod(TestFinally.java:30)
 at TestFinally.main(TestFinally.java:10)


Scenario #7: try and catch both fine; finally doesn't have any return



...
try{
System.out.println("Inside try block of testMethod!");
i = 100;
return i;
}catch(Exception e){
System.out.println("Inside catch block of testMethod!");
i = 200;
return i;
}
finally{
System.out.println("Inside finally block of testMethod!");
i = 300;
//return i;
}
...


Output: well... first thing first. If try is fine, do we need to even think about catch? A BIG No... right? Okay, so we have try and finally blocks to focus on. Let me first show you the output and then we would discuss if you have any doubts. Here is it:



Inside main method!
Inside try block of testMethod!
Inside finally block of testMethod!
Returned value of i = 100

Why String has been made immutable in Java | use of Immutable in java

 Below listed reason behind String to make immutable

 Performance is a reason (assuming you are already aware of the internal String pool maintained for making sure that the same String object is used more than once without having to create/re-claim it those many times), but the main reason why String has been made immutable in Java is 'Security'. Surprised? Let's understand why.
Suppose you need to open a secure file which requires the users to authenticate themselves. Let's say there are two users named 'user1' and 'user2' and they have their own password files 'password1' and 'password2', respectively. Obviously 'user2' should not have access to 'password1' file.

As we know the filenames in Java are specified by using Strings. Even if you create a 'File' object, you pass the name of the file as a String only and that String is maintained inside the File object as one of its members.

Had String been mutable, 'user1' could have logged into using his credentials and then somehow could have managed to change the name of his password filename (a String object) from 'password1' to 'password2' before JVM actually places the native OS system call to open the file. This would have allowed 'user1' to open user2's password file. Understandably it would have resulted into a big security flaw in Java. I understand there are so many 'could have's here, but you would certainly agree that it would have opened a door to allow developers messing up the security of many resources either intentionally or un-intentionally.

With Strings being immutable, JVM can be sure that the filename instance member of the corresponding File object would keep pointing to same unchanged "filename" String object. The 'filename' instance member being a 'final' in the File class can anyway not be modified to point to any other String object specifying any other file than the intended one (i.e., the one which was used to create the File object).

Liked the article? Subscribe to this blog for regular updates. Wanna follow it to tell the world that you enjoy GeekExplains? Please find the 'Followers' widget in the rightmost sidebar.