Did you cast Object to String anywhere in your second code.
No! You are simply concatenating the result i.next() to the String "The value is ". That's it!
What is simply happening there: i.next() returns the object and because the runtime type of that is String so the overridden version of the toString() will be called from the String class to show you the result.
ClassCastException occurs when there is something runtime incompatible assignment is done.
Object o1 = new Object();
String s1 = (String)o1; //CCE will be thrown
Object o2 = new String();
String s2 = (String)o2; //NO PROBLEM AT RUNTIME, because the runtime type of the o2 will be String so assigning String object to String ref variable is no sin.
