一個普通的類,為重寫toString函數之前,直接輸出該類的對象,結果如下:
package blogTest;
class Test{
public int age;
public double acount;
public String string;
public void setAge(int age) {
this.age = age;
}
public void setAcount(double acount) {
this.acount = acount;
}
public void setString(String string) {
this.string = string;
}
public int getAge() {
return age;
}
public double getAcount() {
return acount;
}
public String getString() {
return string;
}
}
public class ToString {
public static void main(String[] args) {
// TODO Auto-generated method stub
Test test=new Test();
test.setAge(10);
test.setAcount(20.0);
test.setString("hello wolrd!");
System.out.println("test:\t\t\t"+test);//blogTest.Test@2a139a55
System.out.println("test.toString():\t"+test.toString());//未重寫toString:blogTest.Test@2a139a55
}
}
/*
結果如下:
test: blogTest.Test@2a139a55
test.toString(): blogTest.Test@2a139a55
*/
注:
當你要輸出一個對象的時候。默認調取該對象的toString方法。 每個類默認繼承Object對象,它里面的toString方法源碼如下:
public String toString() {
return getClass().getName() + "@" + Integer.toHexString(hashCode());
}
getClass().getName()為反射獲取類名稱 hashCode()為本地方法,返回對象的地址值。
因此輸出結果如上圖所示。
重寫該類的toStirng方法之后
package blogTest;
class Test{
public int age;
public double acount;
public String string;
public void setAge(int age) {
this.age = age;
}
public void setAcount(double acount) {
this.acount = acount;
}
public void setString(String string) {
this.string = string;
}
public int getAge() {
return age;
}
public double getAcount() {
return acount;
}
public String getString() {
return string;
}
@Override
public String toString() {
// TODO Auto-generated method stub
return "年齡:"+age+"\t余額:"+acount+"\t名字:"+string;
}
}
public class ToString {
public static void main(String[] args) {
// TODO Auto-generated method stub
Test test=new Test();
test.setAge(10);
test.setAcount(20.0);
test.setString("hello wolrd!");
System.out.println("test:\t\t\t"+test);//blogTest.Test@2a139a55
System.out.println("test.toString():\t"+test.toString());//為重寫toString:blogTest.Test@2a139a55
}
}
/*
結果如下:
test: 年齡:10 余額:20.0 名字:hello wolrd!
test.toString(): 年齡:10 余額:20.0 名字:hello wolrd!
*/
此外我們可以用不同的方法來書寫toString()方法,上面已經給了一種直接返回字符串的形式,下面給出另外兩種。
--------------方法一----------
用StringBuffer類
package blogTest;
class Test{
public int age;
public double acount;
public String string;
public void setAge(int age) {
this.age = age;
}
public void setAcount(double acount) {
this.acount = acount;
}
public void setString(String string) {
this.string = string;
}
public int getAge() {
return age;
}
public double getAcount() {
return acount;
}
public String getString() {
return string;
}
@Override
public String toString() {
// TODO Auto-generated method stub
// return "年齡:"+age+"\t余額:"+acount+"\t名字:"+string;
StringBuffer stringBuffer=new StringBuffer();
stringBuffer.append("年齡:"+age);
stringBuffer.append("\t余額:"+acount);
stringBuffer.append("\t名字:"+string);
return stringBuffer.toString();
}
}
public class ToString {
public static void main(String[] args) {
// TODO Auto-generated method stub
Test test=new Test();
test.setAge(10);
test.setAcount(20.0);
test.setString("hello wolrd!");
System.out.println("test:\t\t\t"+test);//blogTest.Test@2a139a55
System.out.println("test.toString():\t"+test.toString());//為重寫toString:blogTest.Test@2a139a55
}
}
/*
結果如下:
test: 年齡:10 余額:20.0 名字:hello wolrd!
test.toString(): 年齡:10 余額:20.0 名字:hello wolrd!
*/
------------方法二---------
利用反射重寫toString方法。
package blogTest;
import java.lang.reflect.Field;
class Test{
public int age;
public double acount;
public String string;
public void setAge(int age) {
this.age = age;
}
public void setAcount(double acount) {
this.acount = acount;
}
public void setString(String string) {
this.string = string;
}
public int getAge() {
return age;
}
public double getAcount() {
return acount;
}
public String getString() {
return string;
}
public void test() {
Class clazz=this.getClass(); // 獲取該類的class對象
Field[] fields=clazz.getDeclaredFields(); //獲取該類的所有成員變量
System.out.println("輸出該類的成員變量:");
for (Field field : fields) {
// System.out.println(field);
/*
* public int blogTest.Test.age
public double blogTest.Test.acount
public java.lang.String blogTest.Test.string
/
try {
System.out.println(field.getName()+":"+field.get(this));
} catch (IllegalArgumentException | IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
/age
acount
string*/
}
}
@Override
public String toString() {
Class clazz=this.getClass(); // 獲取該類的class對象
StringBuffer stringBuffer=new StringBuffer();
Field[] fields=clazz.getDeclaredFields(); //獲取該類的所有成員變量
for (Field field : fields) {
try {
stringBuffer.append(field.getName()+":"+field.get(this)+"\t");
} catch (IllegalArgumentException | IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}//for
return stringBuffer.toString();
}//toString
}//別忘了這個?。。?br> /*
- The method main cannot be declared static; static methods can only be declared in a static or top level type
*/
public class ToString {
public static void main(String[] args) {
// TODO Auto-generated method stub
Test test=new Test();
test.setAge(10);
test.setAcount(20.0);
test.setString("hello wolrd!");
System.out.println("test:\t\t\t"+test);//blogTest.Test@2a139a55
System.out.println("test.toString():\t"+test.toString());//為重寫toString:blogTest.Test@2a139a55
// test.test();
}
}
/*
輸出結果:
test: age:10 acount:20.0 string:hello wolrd!
test.toString(): age:10 acount:20.0 string:hello wolrd!
*/
注:里面的test方法之前忘記了怎么用反射獲取成員變量名和成員變量值,用來嘗試用的,可以不用管它。
總結:
在這里我們可以看出,使用反射重寫toString方法最為麻煩,但是如果添加了新的成員變量不需要重新修改。
不過好像別人說用反射來獲取成員變量或者成員方法不好,違背了類的封閉性。╮(╯_╰)╭
下面解釋一下:這個簡單有注釋的。
Class clazz=this.getClass(); // 獲取該類的class對象
StringBuffer stringBuffer=new StringBuffer();
Field[] fields=clazz.getDeclaredFields(); //獲取該類的所有成員變量
這個主要是遍歷成員變量
field.getName()可以獲取成員變量的名稱; field.get(this)可以獲取在這里成員變量值
這里我們用前面用到的StringBuffer類把它串在一起就可以了。
注意拋出異常。
for (Field field : fields) {
try {
stringBuffer.append(field.getName()+":"+field.get(this)+"\t");
} catch (IllegalArgumentException | IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}//for
注:
哎,這里寫的時候犯了一個很愚蠢的錯誤,main()函數這里報了個錯:
The method main cannot be declared static; static methods can only be declared in a static or top level type
百思不得其解。
最后發現居然是修改的時候不小心把上邊class類的{}右邊的大括號給注釋掉了,原來是少了個大括號。