美文网首页
Java实体类如何快速重写toString()

Java实体类如何快速重写toString()

作者: 靳兆鲁 | 来源:发表于2019-03-16 15:50 被阅读0次

当我们写一个实体类的时候,我们有时需要重写toString方法以方便我们查看类中字段的值,如果在重写toString()时,纯手写各个字段的话(如下方代码),字段少了还好,字段多的话就....emmm!

static class Model extends Object {

        String name;

        int age;

        String birthday;

        public String getName() {
            return name;
        }

        public Model setName(String name) {
            this.name = name;
            return this;
        }

        public int getAge() {
            return age;
        }

        public Model setAge(int age) {
            this.age = age;
            return this;
        }

        public String getBirthday() {
            return birthday;
        }

        public Model setBirthday(String birthday) {
            this.birthday = birthday;
            return this;
        }

        @NonNull
        @Override
        public String toString() {
            return "[name=" + name
                    + ",age=" + age
                    + ",birthday=" + birthday+"]";
        }
    }

所以有必要寻求一种快速的方法,其实很简单:


static class Model extends Object {

        String name;

        int age;

        String birthday;

        public String getName() {
            return name;
        }

        public Model setName(String name) {
            this.name = name;
            return this;
        }

        public int getAge() {
            return age;
        }

        public Model setAge(int age) {
            this.age = age;
            return this;
        }

        public String getBirthday() {
            return birthday;
        }

        public Model setBirthday(String birthday) {
            this.birthday = birthday;
            return this;
        }

        @NonNull
        @Override
        public String toString() {

            StringBuilder result = new StringBuilder("[");

            for (Field declaredField : Model.class.getDeclaredFields()) {
                try {
                    result
                            .append(declaredField.getName())
                            .append("=")
                            .append(declaredField.get(Model.this))
                            .append(",");
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }
            }

            return result.substring(0, result.length() - 1) + "]";

//            return "[name=" + name
//                    + ",age=" + age
//                    + ",birthday=" + birthday + "]";
        }
    }

其实就是简单用到了Class中的几个方法。
那我们不能每新建一个实体类重写toString()时都写这些代码吧,虽然不多,但是我懒啊,那怎么办呢?很好办,把逻辑抽出来,新建一个静态方法,用的时候直接调用就好了。


 static class Model extends Object {

        String name;

        int age;

        String birthday;

        public String getName() {
            return name;
        }

        public Model setName(String name) {
            this.name = name;
            return this;
        }

        public int getAge() {
            return age;
        }

        public Model setAge(int age) {
            this.age = age;
            return this;
        }

        public String getBirthday() {
            return birthday;
        }

        public Model setBirthday(String birthday) {
            this.birthday = birthday;
            return this;
        }

        @NonNull
        @Override
        public String toString() {
            return modelToString(this);

//            StringBuilder result = new StringBuilder("[");
//
//            for (Field declaredField : getClass().getDeclaredFields()) {
//                try {
//                    result
//                            .append(declaredField.getName())
//                            .append("=")
//                            .append(declaredField.get(Model.this))
//                            .append(",");
//                } catch (IllegalAccessException e) {
//                    e.printStackTrace();
//                }
//            }
//
//            return result.substring(0, result.length() - 1) + "]";

//            return "[name=" + name
//                    + ",age=" + age
//                    + ",birthday=" + birthday + "]";
        }
    }

    public static <T> String modelToString(T t) {
        StringBuilder result = new StringBuilder("[");

        for (Field declaredField : t.getClass().getDeclaredFields()) {
            try {
                result
                        .append(declaredField.getName())
                        .append("=")
                        .append(declaredField.get(t))
                        .append(",");
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
        }

        return result.substring(0, result.length() - 1) + "]";
    }

这样就简单多了,说了那么多我们简单测试一下。


    public static void main(String[] args) throws Exception {
        long start = System.currentTimeMillis();
        System.out.println(new Model()
                .setBirthday("2018-02-02")
                .setName("娃娃")
                .setAge(2)
                .toString());

        long sum = System.currentTimeMillis() - start;
        System.out.println(String.valueOf(sum / 1000) + " 秒\n" + sum + " 毫秒");
    }
 

输出如下:

[name=娃娃,age=2,birthday=2018-02-02]
0 秒
3 毫秒

Process finished with exit code 

那种样是不是就完工了呢?其实不是,如果你访问的是没有访问权限的字段它会报错,就是这段

     try {
                result
                        .append(declaredField.getName())
                        .append("=")
                        .append(declaredField.get(t))
                        .append(",");
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }

,假如你访问的是另一个类的private字段,会有
java.lang.IllegalAccessException:的异常,我们来解决这个问题:

public static <T> String modelToString(T t) {
        StringBuilder result = new StringBuilder("[");

        for (Field declaredField : t.getClass().getDeclaredFields()) {
            try {
                result
                        .append(declaredField.getName())
                        .append("=")
                        .append(declaredField.get(t))
                        .append(",");
            } catch (IllegalAccessException e) {
                declaredField.setAccessible(true);
                try {
                    result
                            .append(declaredField.get(t))
                            .append(",");
                } catch (IllegalAccessException e1) {
                    e1.printStackTrace();
                }
                declaredField.setAccessible(false);
            }
        }

        return result.substring(0, result.length() - 1) + "]";
    }

如果我访问的是私有字段,我们先调用setAccessible(true)使其有被访问权限,最后调用
declaredField.setAccessible(false);关闭访问权限。

相信很多玩过Java反射的同学,都会想到这种方法!

其实不重写toString()也是可行的,调用modelToString(T t)时直接传对象,但不推荐这样做,麻烦,不省心!

相关文章

网友评论

      本文标题:Java实体类如何快速重写toString()

      本文链接:https://www.haomeiwen.com/subject/aglsmqtx.html