《Effective Java》阅读笔记10始终要覆盖toString

·  阅读 218

1.为什么要覆盖toString方法?

public class Person {
		protected String name;
		protected int age;
 
 
		public String getName() {
			return name;
		}
		public void setName(String name) {
			this.name = name;
		}
		public int getAge() {
			return age;
		}
		public void setAge(int age) {
			this.age = age;
		}
		public Person(String name, int age) {
			super();
			this.name = name;
			this.age = age;
		}
		/*@Override
		public String toString() {
			return "Person [name=" + name + ", age=" + age + "]";
		}*/
		public static void main(String[] args) {
			Person s = new Person("liming", 6);
			System.out.println(s);
		}
	}
复制代码

如果不覆盖打印:

demo6.Person@1636731
复制代码

覆盖打印:

@Override
public String toString() {
    return "\nname: " + name + "\nage: " + age;}
复制代码
Person [name=liming, age=6]
复制代码

虽然java.lang.Object提供了toString方法的一个实现,但它返回的字符串通常并不是类的用户所期望看到的。

尽管有人认为“Person@1636731”算得上简洁和易于阅读,但是与“Person [name=liming, age=12]”比较起来,它还算不上信息丰富的。它包含类的名称,以及一个“@”符号,接着是散列码的无符号十六进制表示法,例如“Person@1636731”。

toString的约定进一步指出,建议所有的类都覆盖这个方法。

2、无论你是否指定格式,都要在文档中明确

  • 是否指定格式,都为toString 返回值中包含的信息,提供了一种编程式的访问路径
  • 无论与否,都请在文档中表明你的意图

toString()方法的通用约定是:返回当前对象“简洁,但信息丰富,并且易于阅读的表达形式”。

 指定toString返回值的格式有不足之处:如果这个类已经被广泛使用,一旦指定格式,就必须始终如一地坚持这种格式。无论是否决定指定格式,都应该在文档中明确地表明意图。

3 Guava关于toString的

Guava通过 Objects.toStringHelper为我们提供了方便创建toString的方法。看下面的样例:

/ Returns "ClassName{x=1}"
   Objects.toStringHelper(this)
       .add("x", 1)
       .toString();

   // Returns "MyObject{x=1}"
   Objects.toStringHelper("MyObject")
       .add("x", 1)
       .toString();
复制代码

==Guava关于toString的文档连接==: code.google.com/p/guava-lib…

// 重写PhoneNumber的toString方法 - Effective Java中文第二版第44页

package org.effectivejava.examples.chapter03.item10;
import java.util.HashMap;
import java.util.Map;

import com.google.common.base.Objects;

public final class PhoneNumber {
        private final short areaCode;
        private final short prefix;
        private final short lineNumber;

        public PhoneNumber(int areaCode, int prefix, int lineNumber) {
                rangeCheck(areaCode, 999, "area code");
                rangeCheck(prefix, 999, "prefix");
                rangeCheck(lineNumber, 9999, "line number");
                this.areaCode = (short) areaCode;
                this.prefix = (short) prefix;
                this.lineNumber = (short) lineNumber;
        }

        private static void rangeCheck(int arg, int max, String name) {
                if (arg < 0 || arg > max)
                        throw new IllegalArgumentException(name + ": " + arg);
        }

        @Override
        public boolean equals(Object o) {
                if (o == this)
                        return true;
                if (!(o instanceof PhoneNumber))
                        return false;
                PhoneNumber pn = (PhoneNumber) o;
                return pn.lineNumber == lineNumber && pn.prefix == prefix
                                && pn.areaCode == areaCode;
        }

        @Override
        public int hashCode() {
                int result = 17;
                result = 31 * result + areaCode;
                result = 31 * result + prefix;
                result = 31 * result + lineNumber;
                return result;
        }

    //Effective Java原有的toString方法
        /*
         * @Override public String toString() { return
         * String.format("(%03d) %03d-%04d", areaCode, prefix, lineNumber); }
         */

        /**
         * 采用Guava实现的toString
         *
         */
        @Override
        public String toString() {
                return Objects.toStringHelper(this)
                                .addValue(String.format("(%03d) %03d-%04d", areaCode, prefix,lineNumber))
                                .add("areaCode", areaCode)
                                .add("prefix", prefix)
                                .add("lineNumber", lineNumber)
                                .toString();
        }

        public static void main(String[] args) {
                Map<PhoneNumber, String> m = new HashMap<PhoneNumber, String>();
                m.put(new PhoneNumber(707, 867, 5309), "Jenny");

                System.out.println(m);
        }
}
复制代码

输出对比

//原输出
{(707)
867-5309=Jenny}

//Guava实现输出 
{PhoneNumber{(707) 
867-5309, areaCode=707, prefix=867, lineNumber=5309}=Jenny}
复制代码

4.结论

覆盖toString就是为了调试或者打印的时候可以更直观的看到对象的有用的信息,所以建议写新写类的时候要覆盖toString方法。

5.参考文献

www.jianshu.com/p/05bf27bb2… www.javatt.com/p/6191

关注公众号“程序员面试之道”

回复“面试”获取面试一整套大礼包!!!

本公众号分享自己从程序员小白到经历春招秋招斩获10几个offer的面试笔试经验,其中包括【Java】、【操作系统】、【计算机网络】、【设计模式】、【数据结构与算法】、【大厂面经】、【数据库】期待你加入!!!

1.计算机网络----三次握手四次挥手

2.梦想成真-----项目自我介绍

3.你们要的设计模式来了

4.震惊!来看《这份程序员面试手册》!!!

5.一字一句教你面试“个人简介”

6.接近30场面试分享

分类:
后端
标签: