zoukankan      html  css  js  c++  java
  • 如何为已有的类没有生成toString的方法增强生成toString方法

    1:只要提到增强,我的第一思路就是代理,动态代理。但是仅仅是一个toString其实没必要使用代理模式了,有点大材小用了(动态代理其实也是最后通过反射生成toString的方法)。

    2:简单粗暴,可以自己写一个ToStringUtils工具类,使用反射获取所有字段然后拼接生成toString,有了这个思路其实实现很容易了。但是每次新项目频繁导入自己的工具类对项目而言还是相对不便利,最好还是利用现有的轮子,那就是apache  commons lang3 工具包了,方法为:org.apache.commons.lang3.builder.ReflectionToStringBuilder#toString(java.lang.Object), 翻阅源码就可以知道底层就是使用的反射实现,部分源码:

    org.apache.commons.lang3.builder.ReflectionToStringBuilder#toString()

     public String toString() {
            if (this.getObject() == null) {
                return this.getStyle().getNullText();
            }
            Class<?> clazz = this.getObject().getClass();
            this.appendFieldsIn(clazz); // 重点关注
            while (clazz.getSuperclass() != null && clazz != this.getUpToClass()) {
                clazz = clazz.getSuperclass();
                this.appendFieldsIn(clazz);
            }
            return super.toString();
        }
    

      

    重点关注方法:

        protected void appendFieldsIn(final Class<?> clazz) {
            if (clazz.isArray()) {
                this.reflectionAppendArray(this.getObject());
                return;
            }
            final Field[] fields = clazz.getDeclaredFields();
            AccessibleObject.setAccessible(fields, true);
            for (final Field field : fields) {
                final String fieldName = field.getName();
                if (this.accept(field)) {
                    try {
                        // Warning: Field.get(Object) creates wrappers objects
                        // for primitive types.
                        final Object fieldValue = this.getValue(field);
                        if (!excludeNullValues || fieldValue != null) {
                            this.append(fieldName, fieldValue);
                        }
                    } catch (final IllegalAccessException ex) {
                        //this can't happen. Would get a Security exception
                        // instead
                        //throw a runtime exception in case the impossible
                        // happens.
                        throw new InternalError("Unexpected IllegalAccessException: " + ex.getMessage());
                    }
                }
            }
        }
    

      

    该工具还支持生成toString字符串的样式:

       String toString = ReflectionToStringBuilder.toString(new User("daxin", 18), ToStringStyle.JSON_STYLE);
       System.out.println(toString);
    

      输出:

      String toString = ReflectionToStringBuilder.toString(new User("daxin", 18), ToStringStyle.NO_CLASS_NAME_STYLE);
      System.out.println(toString);
    

     

     翻阅了一下源码,其实没有太多高深的东西,更多东西还是需要自己的探索的。

  • 相关阅读:
    μc/osⅡ简化版任务机制浅析
    用pygame学习初级python(一) 15.4.19
    openfire+asmack搭建的安卓即时通讯(六) 15.4.16
    openfire+asmack搭建的安卓即时通讯(五) 15.4.12
    openfire+asmack搭建的安卓即时通讯(四) 15.4.10
    openfire+asmack搭建的安卓即时通讯(三) 15.4.9
    openfire+asmack搭建的安卓即时通讯(二) 15.4.9
    openfire+asmack搭建的安卓即时通讯(一) 15.4.7
    无界非阻塞队列ConcurrentLinkedQueue核心源码浅析
    StampedLock主要API实现浅析
  • 原文地址:https://www.cnblogs.com/leodaxin/p/9087043.html
Copyright © 2011-2022 走看看