String pool and Heap visualisation

Sunday, 30 November 2014
Friday, 28 November 2014
Different ways to create objects in Java
Different ways to create objects in Java
There are four different ways (I really don’t know is there a fifth way to do this) to create objects in java:
1. Using new keyword
This is the most common way to create an object in java. I read somewhere that almost 99% of objects are created in this way.
MyObject object = new MyObject();
2. Using Class.forName()If we know the name of the class & if it has a public default constructor we can create an object in this way.
MyObject object = (MyObject) Class.forName("subin.rnd.MyObject").newInstance();
3. Using clone()The clone() can be used to create a copy of an existing object.
MyObject anotherObject = new MyObject();
MyObject object = anotherObject.clone();
4. Using object deserializationObject deserialization is nothing but creating an object from its serialized form.
ObjectInputStream inStream = new ObjectInputStream(anInputStream );
MyObject object = (MyObject) inStream.readObject();
There are various ways:
- Through
Class.newInstance. - Through
Constructor.newInstance. - Through deserialisation (uses the no-args constructor of the most derived non-serialisable base class).
- Through
Object.clone(does not call a constructor). - Through JNI (should call a constructor).
- Through any other method that calls a
newfor you. - I guess you could describe class loading as creating new objects (such as interned
Strings). - A literal array as part of the initialisation in a declaration (no constructor for arrays).
- The array in a "varargs" (
...) method call (no constructor for arrays). - Non-compile time constant string concatenation (happens to produce at least four objects, on a typical implementation).
- Causing an exception to be created and thrown by the runtime. For instance
throw null;or"".toCharArray()[0]. - Oh, and boxing of primitives (unless cached), of course.
- JDK8 should have lambdas (essentially concise anonymous inner classes), which are implicitly converted to objects.
- For completeness (and PaĆlo Ebermann), there's some syntax with the
newkeyword as well
Auto-Widening Vs Auto-Boxing Vs Auto-UpCasting In Java
Auto-Widening Vs Auto-Boxing Vs Auto-UpCasting In Java
Just go through the following example,
public class WrapperClasses
{
static void overloadedMethod(Integer I)
{
System.out.println("Integer Wrapper Class Type");
}
static void overloadedMethod(long l)
{
System.out.println("long primitive type");
}
public static void main(String[] args)
{
int i = 21;
overloadedMethod(i);
}
}
In the above example, ‘overloadedMethod’ is overloaded. One method takes Integer wrapper class type as an argument and another method takes primitive long type as an argument. In the main method, we are calling this ‘overloadedMethod’ by passing primitive int type as an argument. When you run this program, you will get “long primitive type” as output. That means, auto-widening is happening not auto-boxing.
Now, make little modification to the above example. Change the argument of second method from primitive long type to Long wrapper class type.
public class WrapperClasses
{
static void overloadedMethod(Integer I)
{
System.out.println("Integer Wrapper Class Type");
}
static void overloadedMethod(Long L)
{
System.out.println("Long Wrapper Class Type");
}
public static void main(String[] args)
{
int i = 21;
overloadedMethod(i);
}
}
Now run this program. you will get “Integer Wrapper Class Type” as output. That means auto-boxing is happening.
Now, make one more modification to the above program. Change the argument of first method from Integer Wrapper Class Type to Double Wrapper Class Type.
public class WrapperClasses
{
static void overloadedMethod(Double D)
{
System.out.println("Double Wrapper Class Type");
}
static void overloadedMethod(Long L)
{
System.out.println("Long Wrapper Class Type");
}
public static void main(String[] args)
{
int i = 21;
overloadedMethod(i); //compile time error
}
}
Above example gives compile time error. Because, there is no method definition which takes int type as an argument. Primitive int type can be auto-widened to big sized primitive types or can be auto-boxed to Integer wrapper class type but can not be converted into Double or Long wrapper class type.
Now, add one more overloadedMethod which takes Number Class type as an argument to the above class.
public class WrapperClasses
{
static void overloadedMethod(Number N)
{
System.out.println("Number Class Type");
}
static void overloadedMethod(Double D)
{
System.out.println("Double Wrapper Class Type");
}
static void overloadedMethod(Long L)
{
System.out.println("Long Wrapper Class Type");
}
public static void main(String[] args)
{
int i = 21;
overloadedMethod(i);
}
}
Now run this program, you will get “Number Class Type” as output. What happened here is, internally primitive int type is auto-boxed to Integer type and Integer type is auto-UpCasted to Number type as Integer wrapper class is a sub class of Number class.
Above examples can be summarized like below,
If you are passing primitive data type as an argument to the method call, compiler first checks for a method definition which takes same data type as an argument.
If such method does not exist, then it checks for the method definition which takes big sized primitive data type than passed data type. i.e It tries to perform auto-widening conversion of passed data type.
If auto-widening conversion is not possible, then it checks for method definition which takes corresponding wrapper class type as an argument. i.e It tries to perform auto-boxing conversion.
If such method does not exist, then it checks for the method which takes super class type (Number or Object type) as an argument.
If such method also does not exist, then compiler gives compile time error.

Just go through the following example,
public class WrapperClasses
{
static void overloadedMethod(Integer I)
{
System.out.println("Integer Wrapper Class Type");
}
static void overloadedMethod(long l)
{
System.out.println("long primitive type");
}
public static void main(String[] args)
{
int i = 21;
overloadedMethod(i);
}
}
In the above example, ‘overloadedMethod’ is overloaded. One method takes Integer wrapper class type as an argument and another method takes primitive long type as an argument. In the main method, we are calling this ‘overloadedMethod’ by passing primitive int type as an argument. When you run this program, you will get “long primitive type” as output. That means, auto-widening is happening not auto-boxing.
Now, make little modification to the above example. Change the argument of second method from primitive long type to Long wrapper class type.
public class WrapperClasses
{
static void overloadedMethod(Integer I)
{
System.out.println("Integer Wrapper Class Type");
}
static void overloadedMethod(Long L)
{
System.out.println("Long Wrapper Class Type");
}
public static void main(String[] args)
{
int i = 21;
overloadedMethod(i);
}
}
Now run this program. you will get “Integer Wrapper Class Type” as output. That means auto-boxing is happening.
Now, make one more modification to the above program. Change the argument of first method from Integer Wrapper Class Type to Double Wrapper Class Type.
public class WrapperClasses
{
static void overloadedMethod(Double D)
{
System.out.println("Double Wrapper Class Type");
}
static void overloadedMethod(Long L)
{
System.out.println("Long Wrapper Class Type");
}
public static void main(String[] args)
{
int i = 21;
overloadedMethod(i); //compile time error
}
}
Above example gives compile time error. Because, there is no method definition which takes int type as an argument. Primitive int type can be auto-widened to big sized primitive types or can be auto-boxed to Integer wrapper class type but can not be converted into Double or Long wrapper class type.
Now, add one more overloadedMethod which takes Number Class type as an argument to the above class.
public class WrapperClasses
{
static void overloadedMethod(Number N)
{
System.out.println("Number Class Type");
}
static void overloadedMethod(Double D)
{
System.out.println("Double Wrapper Class Type");
}
static void overloadedMethod(Long L)
{
System.out.println("Long Wrapper Class Type");
}
public static void main(String[] args)
{
int i = 21;
overloadedMethod(i);
}
}
Now run this program, you will get “Number Class Type” as output. What happened here is, internally primitive int type is auto-boxed to Integer type and Integer type is auto-UpCasted to Number type as Integer wrapper class is a sub class of Number class.
Above examples can be summarized like below,
If you are passing primitive data type as an argument to the method call, compiler first checks for a method definition which takes same data type as an argument.
If such method does not exist, then it checks for the method definition which takes big sized primitive data type than passed data type. i.e It tries to perform auto-widening conversion of passed data type.
If auto-widening conversion is not possible, then it checks for method definition which takes corresponding wrapper class type as an argument. i.e It tries to perform auto-boxing conversion.
If such method does not exist, then it checks for the method which takes super class type (Number or Object type) as an argument.
If such method also does not exist, then compiler gives compile time error.
Just go through the following example,
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
| public class WrapperClasses{ static void overloadedMethod(Integer I) { System.out.println("Integer Wrapper Class Type"); } static void overloadedMethod(long l) { System.out.println("long primitive type"); } public static void main(String[] args) { int i = 21; overloadedMethod(i); }} |
In the above example,
‘overloadedMethod’ is overloaded. One method takes Integer wrapper class
type as an argument and another method takes primitive long type as an
argument. In the main method, we are calling this ‘overloadedMethod’ by
passing primitive int type as an argument. When you run this program,
you will get “long primitive type” as output. That means, auto-widening
is happening not auto-boxing.
Now, make little
modification to the above example. Change the argument of second method
from primitive long type to Long wrapper class type.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
| public class WrapperClasses{ static void overloadedMethod(Integer I) { System.out.println("Integer Wrapper Class Type"); } static void overloadedMethod(Long L) { System.out.println("Long Wrapper Class Type"); } public static void main(String[] args) { int i = 21; overloadedMethod(i); }} |
Now run this program. you will get “Integer Wrapper Class Type” as output. That means auto-boxing is happening.
Now, make one more
modification to the above program. Change the argument of first method
from Integer Wrapper Class Type to Double Wrapper Class Type.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
| public class WrapperClasses{ static void overloadedMethod(Double D) { System.out.println("Double Wrapper Class Type"); } static void overloadedMethod(Long L) { System.out.println("Long Wrapper Class Type"); } public static void main(String[] args) { int i = 21; overloadedMethod(i); //compile time error }} |
Above example gives
compile time error. Because, there is no method definition which takes
int type as an argument. Primitive int type can be auto-widened to big
sized primitive types or can be auto-boxed to Integer wrapper class type
but can not be converted into Double or Long wrapper class type.
Now, add one more overloadedMethod which takes Number Class type as an argument to the above class.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
| public class WrapperClasses{ static void overloadedMethod(Number N) { System.out.println("Number Class Type"); } static void overloadedMethod(Double D) { System.out.println("Double Wrapper Class Type"); } static void overloadedMethod(Long L) { System.out.println("Long Wrapper Class Type"); } public static void main(String[] args) { int i = 21; overloadedMethod(i); }} |
Now run this program,
you will get “Number Class Type” as output. What happened here is,
internally primitive int type is auto-boxed to Integer type and Integer
type is auto-UpCasted to Number type as Integer wrapper class is a sub
class of Number class.
Above examples can be summarized like below,
- If you are passing primitive data type as an argument to the method call, compiler first checks for a method definition which takes same data type as an argument.
- If such method does not exist, then it checks for the method definition which takes big sized primitive data type than passed data type. i.e It tries to perform auto-widening conversion of passed data type.
- If auto-widening conversion is not possible, then it checks for method definition which takes corresponding wrapper class type as an argument. i.e It tries to perform auto-boxing conversion.
- If such method does not exist, then it checks for the method which takes super class type (Number or Object type) as an argument.
- If such method also does not exist, then compiler gives compile time error.
It can be diagrammatically represented as,
- See more at: http://javaconceptoftheday.com/auto-widening-auto-boxing-auto-upcasting-java/#sthash.aOVMAFlS.dpuf
Internals of HashMap :-
HashMap use 2 data structure:
First find the slot by hash value, then loop each element in the slot until found or end,
Add value:
First find the slot by hash value,
then try find the value:
* if found, then replace the value,
* if not found, then add a new one to begining of the slot,
capacity
Capacity is slot size, as element count increase, capacity is larger but liner to element count, and finally equals to size (Integer.MAX_VALUE),
linked list length:
As element count increase, length is liner to a small constant value, and finally equals to 1,
speed:
put / get, has O(1) speed, because slot is access via index, and linked list length is very small,
space:
The slot size increase as element count increase,
but it's empty element are null, so not much space is taking,
resize:
When resize capacity, it also need to do rehash, this might take.
The bucket is the linked list effectively . Its not a LinkedList as in a java.util.LinkedList - It's a separate (simpler) implementation just for the map .
So we traverse through linked list , comparing keys in each entries using keys.equals() until it return true. Then the corresponding entry object Value is returned .
A hashmap works like this (this is a little bit simplified, but it illustrates the basic mechanism):
It has a number of "buckets" which it uses to store key-value pairs in. Each bucket has a unique number - that's what identifies the bucket. When you put a key-value pair into the map, the hashmap will look at the hash code of the key, and store the pair in the bucket of which the identifier is the hash code of the key. For example: The hash code of the key is 235 -> the pair is stored in bucket number 235. (Note that one bucket can store more then one key-value pair).
When you lookup a value in the hashmap, by giving it a key, it will first look at the hash code of the key that you gave. The hashmap will then look into the corresponding bucket, and then it will compare the key that you gave with the keys of all pairs in the bucket, by comparing them with
Now you can see how this is very efficient for looking up key-value pairs in a map: by the hash code of the key the hashmap immediately knows in which bucket to look, so that it only has to test against what's in that bucket.
Looking at the above mechanism, you can also see what requirements are necessary on the
It has a number of "buckets" which it uses to store key-value pairs in. Each bucket has a unique number - that's what identifies the bucket. When you put a key-value pair into the map, the hashmap will look at the hash code of the key, and store the pair in the bucket of which the identifier is the hash code of the key. For example: The hash code of the key is 235 -> the pair is stored in bucket number 235. (Note that one bucket can store more then one key-value pair).
When you lookup a value in the hashmap, by giving it a key, it will first look at the hash code of the key that you gave. The hashmap will then look into the corresponding bucket, and then it will compare the key that you gave with the keys of all pairs in the bucket, by comparing them with
equals().Now you can see how this is very efficient for looking up key-value pairs in a map: by the hash code of the key the hashmap immediately knows in which bucket to look, so that it only has to test against what's in that bucket.
Looking at the above mechanism, you can also see what requirements are necessary on the
hashCode() and equals() methods of keys:- If two keys are the same (
equals()returnstruewhen you compare them), theirhashCode()method must return the same number. If keys violate this, then keys that are equal might be stored in different buckets, and the hashmap would not be able to find key-value pairs (because it's going to look in the same bucket). - If two keys are different, then it doesn't matter if their hash
codes are the same or not. They will be stored in the same bucket if
their hash codes are the same, and in this case, the hashmap will use
equals()to tell them apart.
HashMap use 2 data structure:
- Hash
Use hash value to group elements into slots, control by hash() method of HashMap, - linked list (singly)
Each slot is a singly linked list, their key has the same hash value,
the slot index is control by indexFor() method of HashMap,
First find the slot by hash value, then loop each element in the slot until found or end,
Add value:
First find the slot by hash value,
then try find the value:
* if found, then replace the value,
* if not found, then add a new one to begining of the slot,
capacity
Capacity is slot size, as element count increase, capacity is larger but liner to element count, and finally equals to size (Integer.MAX_VALUE),
linked list length:
As element count increase, length is liner to a small constant value, and finally equals to 1,
speed:
put / get, has O(1) speed, because slot is access via index, and linked list length is very small,
space:
The slot size increase as element count increase,
but it's empty element are null, so not much space is taking,
resize:
When resize capacity, it also need to do rehash, this might take.
The bucket is the linked list effectively . Its not a LinkedList as in a java.util.LinkedList - It's a separate (simpler) implementation just for the map .
So we traverse through linked list , comparing keys in each entries using keys.equals() until it return true. Then the corresponding entry object Value is returned .
Subscribe to:
Comments (Atom)
