StringBuffer over String Class

String myStr = “SchoolHoood”;
myStr = myStr.concat(” – Learn to Enjoy”);
myStr = myStr.concat(” – For 5 to 55.”);

Since strings are immutable in java, the above codes makes 2 hanging string objects in heap namely:
1. SchoolHood
2. SchoolHood – Learn to enjoy
Of course the final string “SchoolHoood – Learn to Enjoy – For 5 to 55.” will have a reference var as myStr.

If lot many modifications are required on a string, StrinBuilder/StringBuffer should be preferred over just plain String class. This is to avoid the loosing of strings in the heap-pool and hence saving the memory. For detail read Immutable String in Java.

The above code could be rewritten as:
StringBuffer myStrBuff = nw StringBuffer(“SchoolHoood”);
myStrBuff.append(” – Learn to Enjoy”);
myStrBuff.append(” – For 5 to 55.”);

Since append method is invoked on the StringBuffer object “myStrBuff” itself, hence append happens to be on the same string. Thus StringBuffer/SringBuilder objects can be modified over and over again without leaving behind a discarded String objects.

These two methods are used widely in case of FILE I/O because there you need to treat a large amount of data as a single unit. Say for example , while reading a file line by line — youStrBuilderObj.append(lineContent) — will make you to deal with data easily.

Immutable String in Java

Immutable concept : Once you assign a value to a string, you CANT change. Hence “replace” (or other methods like concat, subString etc) method couldn’t change myStr3.

Thus using string methods to create a new String by altering an existing String will never create a new string.

YOU NEED TO ASSIGN them to a NEW STRING, then only it will take in effect.

Look at step 6. Once everything is set to null. we know still “SchoolHood” & “JavaHood” do exist in Heap. What if we could take them back?

There is JVM plays major role. JVM sets aside a special area of memory called the “String constant pool.”

When the compiler encounters a String literal, it checks the pool to see if an identical String already exists. If a match is found, the reference to the new literal is directed to the existing String, and no new String literal object is created.

Thus if JAVA treats STRINGS as immutable; the thought design would have been to IMPROVE THE PERFORMANCE by having an excellent memory management.

public class StringReferenceDemo {
	public static void main(String[] args) {
		String myStr1 = "SchoolHood";  // 1
		String myStr2 = "SchoolHood";  // 2
		String myStr3 = myStr2; // 3

		System.out.println(myStr1.hashCode()); //1897055952 - Returns a hash code value for the object
		System.out.println(myStr2.hashCode()); // 1897055952
		System.out.println(myStr3.hashCode()); // 1897055952

		myStr3.replace("School", "Java"); // Still at 3
		System.out.println(myStr3); // SchoolHood
		myStr3 = myStr3.replace("School", "Java"); // 4a, 4b
		System.out.println(myStr3); // JavaHood
		System.out.println(myStr3.hashCode()); // -517433730
		String myStr4 = myStr3.replace("Java","School"); //5
		System.out.println(myStr4); // SchoolHood
		System.out.println(myStr4.hashCode());	 // 1897055952
		myStr1 = myStr2 = myStr3 = myStr4 = null; // 6

		String myStr5 = "SchoolHood"; // 7
    System.out.println(myStr5.hashCode()); // 1897055952
	}
}

Steps:

1: myStr1 is a reference variable pointing to the add location (Java converted hashcode value 1897055952)
2. myStr2 is a reference var pointing to the same location : #1897055952
In heap there is a space ALREADY allocated, hence no new location is assigned.
3. myStr3 is a reference var pointing to the same location : #1897055952
Although using a replace wont change the myStr3. Still myStr3 as the same location : #1897055952
Hence printing myStr3 even after replace you are getting the same “SchoolHood”
4a. Replace and assignment dereferences myStr3 from “SchoolHood” and
4b. references newly to the new location as “JavaHood”. Hence myStr3 is now “JavaHood” at #-517433730
5. myStr4 – Again replacing “JavaHood” to “SchoolHood”. Hence pointing back to the same #1897055952
Doesnt create any new location
5. Set all these vars to null.
Still in memory you will find SchoolHood at #1897055952 and JavaHood at #-517433730
7. myStr5 is claiming back the pos of #1897055952 coz of “String constant pool”

 

Still one question remains, what if such string name-values are quite large in the heap? What is the best to avoid it?

Answer is in STRING BUFFER/STRING BUILDER. Keep watching. Shortly it will be posted here.

TCF { Try-Catch-Finally }

This morning I was going through an article try-catch-finally (TCF) in Java.
Suddenly got some weird thoughts.

Plugged myself to Eclipse to dive into the right answers. Here are few bullets:

1. Can try exist all alone ( without catch, without finally) ?
ANS: try block {1} i.e 1 time
catch block * i.e 0 or N times
finally block ? i.e 0 or 1 time

2. Can I put just try block in an “if” condition leaving catch block independent?

if(alive){
  try{
         //dive into pacific ocean once more
      {
} // end of if
catch(Exception e) {
     // Reported dead before entering to pacific
}

ANS: No. You cant associate catch without if.

3. I want to write the below JDBC scenario in below manner:

try block -> Establish a connection to the database & submit a query to the MySQL database for execution
catch block -> If connection failure or query failure happens, will give a message to the end user.
finally block -> close the database connection at any cost

Not a big deal, my code is ready. Here I go………

public class TtryCatchFinallyDemo {

	public static void main(String[] args) {
		Connection con = null;
		Statement stmt = null;
		ResultSet rs = null;
		try {
			Class.forName("com.mysql.jdbc.Driver");
			con = DriverManager.getConnection("jdbc:mysql://localhost:3306/mysql", "root", "password");
			stmt = con.createStatement();
			rs = stmt.executeQuery("Select * FROM user");
			while (rs.next()) {
				System.out.println(rs.getString("User2")); //Mistaken purposely- User2 instead "User" // PlaceHolder_00
			}
			con.close(); // PlaceHolder_01
		}
		catch (Exception e) {
			System.out.println("Exception Occurred :- " + e.getMessage());
			// PlaceHolder_02
		}finally{
                         con.close; // PlaceHolder_03
			}
		}
	}
}

Looks absolutely fine. Right?

No. It has error.
Exception in thread “main” java.lang.Error: Unresolved compilation problem:
Unhandled exception type SQLException

Assume the error happens at PlaceHolder_00, control will move to the exception block and then finally block.

Writing con.close() at PlaceHolder_01 will not close the database connection. Thus I need to close it at finally block at PlaceHolder_03.
But will it serve my purpose?

Thus the correct way of doing it would be

Modify the above code to

finally{
			try{
				System.out.println(con.isClosed());  // false
				con.close();
				System.out.println(con.isClosed()); // true
				con = null;
			}catch(Exception e){// PlaceHolder_03
			     System.out.println("Exception occurred!");
			}
		}

But again re-writing try catch withing finally wont be a good idea.

Hopefully setting the con to null will solve everything.

finally{
   con = null;
}

String to Integer

In JAVA programming it is very frequent demand of converting an int/Integer to String.

Below snapshot shows how this is done. Easy to remember.
Integer to String

public class DataTypeCoversionDemo {
            private static String strVar = "11";
            private static int intVar = 22;
            private static Integer integerVar = 222;
     
      public static void main(String[] args) {      
          convertInt_String();   
      }

      public static void convertInt_String(){
            // ********* Integer to int ********** //
            Integer tInteger = Integer.valueOf(intVar);
            int tSimpleIntValue = tInteger.intValue();

            System.out.println("Simple Int to Integer  :- " + tInteger); //22      
            System.out.println("Integer to Simple int :- " + tSimpleIntValue); //22

            // ********* int to String ********* //
            String tString = String.valueOf(intVar);
            int tInt = Integer.parseInt(strVar);

            System.out.println("Simple Int to String :- " + tString); //22
            System.out.println("String to Simple Int :- " + tInt); //11

            // ******* Integer to String ******* //  
            String tString2 = integerVar.toString();
            Integer tInteger2 = Integer.parseInt(strVar);        

            System.out.println("Integer to String :- " + tString2); //222
            System.out.println("String to Integer :- " + tInteger2); //11
      }
}