重写toString()函数

2017-03-18  本文已影响0人  hao小子

一个普通的类,为重写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

}//别忘了这个!!!
/*

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类的{}右边的大括号给注释掉了,原来是少了个大括号。

上一篇下一篇

猜你喜欢

热点阅读