·
Hi Java Guys,
Read this article, its worth it.
Writing toString Methods
One of the standard methods defined in java.lang.Object is toString. This method is used to obtain a string representation of an object. You can (and normally should) override this method for classes that you write. This tip examines some of the issues around using toString.
Let's first consider some sample code:
class MyPoint {
private final int x, y;
public MyPoint(int x, int y) {
this.x = x;
this.y = y;
}
}
public class TSDemo1 {
public static void main(String args[]) {
MyPoint mp = new MyPoint(37, 47);
// use default Object.toString( )
System.out.println( mp);
// same as previous, showing the
// function of the default toString()
System.out.println( mp.getClass( ).getName( )
+ "@"
+ Integer.toHexString (mp.hashCode( )));
// implicitly call toString() on object
// as part of string concatenation
String s = mp + " testing";
System.out.println( s);
// same as previous, except object
// reference is null
mp = null;
s = mp + " testing";
System.out.println( s);
}
}
The TSDemo1 program defines a class MyPoint to represent X,Y points. It does not define a toString method for the class. The program creates an instance of the class and then prints it. When you run TSDemo1, you should see a result that looks something like this:
MyPoint@111f71
MyPoint@111f71
MyPoint@111f71 testing
null testing
You might wonder how it's possible to print an arbitrary class object. The library methods such as System.out.println know nothing about the MyPoint class or its objects. So how is it possible to convert such an object to string form and then print it, as the first output statement in TSDemo1 does?
The answer is that println calls the java.io.PrintStream .print(Object) method, which then calls the String.valueOf method. The String.valueOf method is very simple:
public static String valueOf(Object obj) {
return (obj == null) ? "null" : obj.toString( );
}
When println is called with a MyPoint object reference, the String.valueOf method converts the object to a string. String.valueOf first checks to make sure that the reference is not null. It then calls the toString method for the object. Since the MyPoint class has no toString method, the default one in java.lang.Object is used instead.
What does the default toString method actually return as a string value? The format is illustrated in the second print statement above. The name of the class, an "@", and the hex version of the object's hashcode are concatenated into a string and returned. The default hashCode method in Object is typically implemented by converting the memory address of the object into an integer. So your results might vary from those shown above.
The third and fourth parts of the TSDemo1 example illustrate a related idea: when you use "+" to concatenate a string to an object, toString is called to convert the object to a string form. You need to look at the bytecode expansion for TSDemo1 to see that. You can look at the bytecode for TSDemo1 (that is, in a human-readable form) by issuing the javap command as follows:
javap -c . TSDemo1
If you look at the bytecode, you'll notice that part of it involves creating a StringBuffer object, and then using StringBuffer. append(Object) to append the mp object to it. StringBuffer. append(Object) is implemented very simply:
public synchronized StringBuffer append(Object obj) {
return append(String. valueOf(obj) );
}
As mentioned earlier, String.valueOf calls toString on the object to get its string value.
O.K., so much for invoking the default toString method. How do you write your own toString methods? It's really very simple. Here's an example:
class MyPoint {
private final int x, y;
public MyPoint(int x, int y) {
this.x = x;
this.y = y;
}
public String toString() {
return x + " " + y;
}
}
public class TSDemo2 {
public static void main(String args[]) {
MyPoint mp = new MyPoint(37, 47);
// call MyPoint.toString( )
System.out.println( mp);
// call toString() and
// extract the X value from it
String s = mp.toString( );
String t = s.substring( 0, s.indexOf(' '));
int x = Integer.parseInt( t);
System.out.println( t);
}
}
When you run the TSDemo2 program, the output is: 37 47 37
The toString method in this example does indeed work, but there are a couple of problems with it. One is that there is no descriptive text displayed in the toString output. All you see is a cryptic "37 47". The other problem is that the X,Y values in MyPoint objects are private. There is no other way to get at them except by picking apart the string returned from toString. The second part of the TSDemo2 example shows the code required to extract the X value from the string. Doing it this way is error-prone and inefficient.
Here's another approach to writing a toString method, one that clears up the problems in the previous example:
class MyPoint {
private final int x, y;
public MyPoint(int x, int y) {
this.x = x;
this.y = y;
}
public String toString() {
return "X=" + x + " " + "Y=" + y;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
}
public class TSDemo3 {
public static void main(String args[]) {
MyPoint mp = new MyPoint(37, 47);
// call MyPoint.toString( )
System.out.println( mp);
// get X,Y values via accessor methods
int x = mp.getX();
int y = mp.getY();
System.out.println( x);
System.out.println( y);
}
}
The output is:
X=37 Y=47
37
47
This example adds some descriptive text to the output format, and defines a couple of accessor methods to get at the X,Y values. In general, when you write a toString method, the format of the string that is returned should cover all of the object contents. Your toString method should also contain descriptive labels for each field. And there should be a way to get at the object field values without having to pick apart the string. Note that using "+" within toString to build up the return value is not necessarily the most efficient approach. You might want to use StringBuffer instead.
Primitive types in the Java programming language, such as int, also have toString methods, for example Integer.toString( int). What about arrays? How can you convert an array to a string? You can assign an array reference to an Object reference, but arrays are not really classes. However, it is possible to use reflection to implement a toString method for arrays. The code looks like this:
import java.lang.reflect. *;
public class TSDemo4 {
public static String toString(Object arr) {
// if object reference is null or not
// an array, call String.valueOf( )
if (arr == null ||
!arr.getClass( ).isArray( )) {
return String.valueOf( arr);
}
// set up a string buffer and
// get length of array
StringBuffer sb = new StringBuffer( );
int len = Array.getLength( arr);
sb.append('[ ');
// iterate across array elements
for (int i = 0; i < len; i++) {
if (i > 0) {
sb.append(', ');
}
// get the i-th element
Object obj = Array.get(arr, i);
// convert it to a string by
// recursive toString() call
sb.append(toString( obj));
}
sb.append('] ');
return sb.toString( );
}
public static void main(String args[]) {
// example #1
System.out.println( toString( "testing" ));
// example #2
System.out.println( toString( null));
// example #3
int arr3[] = new int[]{
1,
2,
3
};
System.out.println( toString( arr3));
// example #4
long arr4[][] = new long[][]{
{1, 2, 3},
{4, 5, 6},
{7, 8, 9}
};
System.out.println( toString( arr4));
// example #5
double arr5[] = new double[0];
System.out.println( toString( arr5));
// example #6
String arr6[] = new String[]{
"testing",
null,
"123"
};
System.out.println( toString( arr6));
// example #7
Object arr7[] = new Object[]{
new Object[]{null, new Object(), null},
new int[]{1, 2, 3},
null
};
System.out.println( toString( arr7));
}
}
The TSDemo4 program creates a toString method, and then passes the toString method an arbitrary Object reference. If the reference is null or does not refer to an array, the program calls the String.valueOf method. Otherwise, the Object refers to an array. In that case, TSDemo4 uses reflection to access the array elements. Array.getLength and Array.get are the key methods that operate on the array. After an element is retrieved, the program calls toString recursively to obtain the string for the element. Doing it this way ensures that multidimensional arrays are handled properly.
The output of the TSDemo4 program is:
testing
null
[1,2,3]
[[1,2,3],[4, 5,6],[7,8, 9]]
[]
[testing,null, 123]
[[null,java. lang.Object@ 111f71,null] ,[1,2,3], null]
Obviously, if you have a huge array, and you call toString, it will use a lot of memory, and the resulting string might not be particularly useful or readable by a human.
All The Best
Have a Nice Day .
Thanks&Regards
Vamsikrishna Venigalla
9949127050
The Solution for every problem is to begin
Read this article, its worth it.
Writing toString Methods
One of the standard methods defined in java.lang.Object is toString. This method is used to obtain a string representation of an object. You can (and normally should) override this method for classes that you write. This tip examines some of the issues around using toString.
Let's first consider some sample code:
class MyPoint {
private final int x, y;
public MyPoint(int x, int y) {
this.x = x;
this.y = y;
}
}
public class TSDemo1 {
public static void main(String args[]) {
MyPoint mp = new MyPoint(37, 47);
// use default Object.toString( )
System.out.println( mp);
// same as previous, showing the
// function of the default toString()
System.out.println( mp.getClass( ).getName( )
+ "@"
+ Integer.toHexString (mp.hashCode( )));
// implicitly call toString() on object
// as part of string concatenation
String s = mp + " testing";
System.out.println( s);
// same as previous, except object
// reference is null
mp = null;
s = mp + " testing";
System.out.println( s);
}
}
The TSDemo1 program defines a class MyPoint to represent X,Y points. It does not define a toString method for the class. The program creates an instance of the class and then prints it. When you run TSDemo1, you should see a result that looks something like this:
MyPoint@111f71
MyPoint@111f71
MyPoint@111f71 testing
null testing
You might wonder how it's possible to print an arbitrary class object. The library methods such as System.out.println know nothing about the MyPoint class or its objects. So how is it possible to convert such an object to string form and then print it, as the first output statement in TSDemo1 does?
The answer is that println calls the java.io.PrintStream .print(Object) method, which then calls the String.valueOf method. The String.valueOf method is very simple:
public static String valueOf(Object obj) {
return (obj == null) ? "null" : obj.toString( );
}
When println is called with a MyPoint object reference, the String.valueOf method converts the object to a string. String.valueOf first checks to make sure that the reference is not null. It then calls the toString method for the object. Since the MyPoint class has no toString method, the default one in java.lang.Object is used instead.
What does the default toString method actually return as a string value? The format is illustrated in the second print statement above. The name of the class, an "@", and the hex version of the object's hashcode are concatenated into a string and returned. The default hashCode method in Object is typically implemented by converting the memory address of the object into an integer. So your results might vary from those shown above.
The third and fourth parts of the TSDemo1 example illustrate a related idea: when you use "+" to concatenate a string to an object, toString is called to convert the object to a string form. You need to look at the bytecode expansion for TSDemo1 to see that. You can look at the bytecode for TSDemo1 (that is, in a human-readable form) by issuing the javap command as follows:
javap -c . TSDemo1
If you look at the bytecode, you'll notice that part of it involves creating a StringBuffer object, and then using StringBuffer. append(Object) to append the mp object to it. StringBuffer. append(Object) is implemented very simply:
public synchronized StringBuffer append(Object obj) {
return append(String. valueOf(obj) );
}
As mentioned earlier, String.valueOf calls toString on the object to get its string value.
O.K., so much for invoking the default toString method. How do you write your own toString methods? It's really very simple. Here's an example:
class MyPoint {
private final int x, y;
public MyPoint(int x, int y) {
this.x = x;
this.y = y;
}
public String toString() {
return x + " " + y;
}
}
public class TSDemo2 {
public static void main(String args[]) {
MyPoint mp = new MyPoint(37, 47);
// call MyPoint.toString( )
System.out.println( mp);
// call toString() and
// extract the X value from it
String s = mp.toString( );
String t = s.substring( 0, s.indexOf(' '));
int x = Integer.parseInt( t);
System.out.println( t);
}
}
When you run the TSDemo2 program, the output is: 37 47 37
The toString method in this example does indeed work, but there are a couple of problems with it. One is that there is no descriptive text displayed in the toString output. All you see is a cryptic "37 47". The other problem is that the X,Y values in MyPoint objects are private. There is no other way to get at them except by picking apart the string returned from toString. The second part of the TSDemo2 example shows the code required to extract the X value from the string. Doing it this way is error-prone and inefficient.
Here's another approach to writing a toString method, one that clears up the problems in the previous example:
class MyPoint {
private final int x, y;
public MyPoint(int x, int y) {
this.x = x;
this.y = y;
}
public String toString() {
return "X=" + x + " " + "Y=" + y;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
}
public class TSDemo3 {
public static void main(String args[]) {
MyPoint mp = new MyPoint(37, 47);
// call MyPoint.toString( )
System.out.println( mp);
// get X,Y values via accessor methods
int x = mp.getX();
int y = mp.getY();
System.out.println( x);
System.out.println( y);
}
}
The output is:
X=37 Y=47
37
47
This example adds some descriptive text to the output format, and defines a couple of accessor methods to get at the X,Y values. In general, when you write a toString method, the format of the string that is returned should cover all of the object contents. Your toString method should also contain descriptive labels for each field. And there should be a way to get at the object field values without having to pick apart the string. Note that using "+" within toString to build up the return value is not necessarily the most efficient approach. You might want to use StringBuffer instead.
Primitive types in the Java programming language, such as int, also have toString methods, for example Integer.toString( int). What about arrays? How can you convert an array to a string? You can assign an array reference to an Object reference, but arrays are not really classes. However, it is possible to use reflection to implement a toString method for arrays. The code looks like this:
import java.lang.reflect. *;
public class TSDemo4 {
public static String toString(Object arr) {
// if object reference is null or not
// an array, call String.valueOf( )
if (arr == null ||
!arr.getClass( ).isArray( )) {
return String.valueOf( arr);
}
// set up a string buffer and
// get length of array
StringBuffer sb = new StringBuffer( );
int len = Array.getLength( arr);
sb.append('[ ');
// iterate across array elements
for (int i = 0; i < len; i++) {
if (i > 0) {
sb.append(', ');
}
// get the i-th element
Object obj = Array.get(arr, i);
// convert it to a string by
// recursive toString() call
sb.append(toString( obj));
}
sb.append('] ');
return sb.toString( );
}
public static void main(String args[]) {
// example #1
System.out.println( toString( "testing" ));
// example #2
System.out.println( toString( null));
// example #3
int arr3[] = new int[]{
1,
2,
3
};
System.out.println( toString( arr3));
// example #4
long arr4[][] = new long[][]{
{1, 2, 3},
{4, 5, 6},
{7, 8, 9}
};
System.out.println( toString( arr4));
// example #5
double arr5[] = new double[0];
System.out.println( toString( arr5));
// example #6
String arr6[] = new String[]{
"testing",
null,
"123"
};
System.out.println( toString( arr6));
// example #7
Object arr7[] = new Object[]{
new Object[]{null, new Object(), null},
new int[]{1, 2, 3},
null
};
System.out.println( toString( arr7));
}
}
The TSDemo4 program creates a toString method, and then passes the toString method an arbitrary Object reference. If the reference is null or does not refer to an array, the program calls the String.valueOf method. Otherwise, the Object refers to an array. In that case, TSDemo4 uses reflection to access the array elements. Array.getLength and Array.get are the key methods that operate on the array. After an element is retrieved, the program calls toString recursively to obtain the string for the element. Doing it this way ensures that multidimensional arrays are handled properly.
The output of the TSDemo4 program is:
testing
null
[1,2,3]
[[1,2,3],[4, 5,6],[7,8, 9]]
[]
[testing,null, 123]
[[null,java. lang.Object@ 111f71,null] ,[1,2,3], null]
Obviously, if you have a huge array, and you call toString, it will use a lot of memory, and the resulting string might not be particularly useful or readable by a human.
All The Best
Have a Nice Day .
Thanks&Regards
Vamsikrishna Venigalla
9949127050
The Solution for every problem is to begin
No comments:
Post a Comment