【问题标题】:Eclipse toString() generator with nested indentation具有嵌套缩进的 Eclipse toString() 生成器
【发布时间】:2019-01-03 18:16:55
【问题描述】:

Eclipse 有一个方便的模板,用于为类自动生成toString() 方法。您可以通过点击Alt+Shift+S 并点击“Generate toString()...”来访问它

您可以从那里选择要包含在派生的toString() 中的字段,并设置其他选项以确定应如何生成它。

我想用它为大量类快速生成toString()方法。

举个例子,这里有一个Song类:

public class Song {
    private String title;
    private int lengthInSeconds;
    public Song(String title, int lengthInSeconds) {
        this.title = title;
        this.lengthInSeconds = lengthInSeconds;
    }
    // getters and setters...

}

这是一个Album 类,它包含一个Songs 数组:

public class Album {
    private Song[] songs;
    private int songCount;
    public Album(Song[] songs) {
        this.songs = songs;
        this.songCount = songs.length;
    }
    //getters...

}

我目前使用这个模板来生成我的toString() 方法(使用“StringBuilder/StringBuffer - 链式调用”选项):

class ${object.className} {
    ${member.name}: ${member.value},
    ${otherMembers}
}

我现在可以使用它为Song 生成toString()

@Override
public String toString() {
    StringBuilder builder = new StringBuilder();
    builder.append("class Song {\n    ");
    if (title != null)
        builder.append("title: ").append(title).append(",\n    ");
    builder.append("lengthInSeconds: ").append(lengthInSeconds).append("\n}");
    return builder.toString();
}

对于Album

@Override
public String toString() {
    StringBuilder builder = new StringBuilder();
    builder.append("class Album {\n    ");
    if (songs != null)
        builder.append("songs: ").append(Arrays.toString(songs)).append(",\n    ");
    builder.append("songCount: ").append(songCount).append("\n}");
    return builder.toString();
}

现在,假设我创建了一个相册并想像这样测试它的toString()

@Test
public void testToString() {
    Song[] songs = new Song[] { 
            new Song("We Will Rock You", 200), 
            new Song("Beat it", 150),
            new Song("Piano Man", 400) };
    Album album = new Album(songs);
    System.out.println(album);
}

这是我得到的:

class Album {
    songs: [class Song {
    title: We Will Rock You,
    lengthInSeconds: 200
}, class Song {
    title: Beat it,
    lengthInSeconds: 150
}, class Song {
    title: Piano Man,
    lengthInSeconds: 400
}],
    songCount: 3
}

但我想要的是一个可以嵌套缩进的生成器,像这样:

class Album {
    songs: [class Song {
        title: We Will Rock You,
        lengthInSeconds: 200
    }, class Song {
        title: Beat it,
        lengthInSeconds: 150
    }, class Song {
        title: Piano Man,
        lengthInSeconds: 400
    }],
    songCount: 3
}

并在每个对象内部有更多类的情况下继续这样做,如果这有意义的话。

在调用toString() 之前,我尝试创建一个可以用 4 个空格和一个换行符替换换行符的方法:

private String indentString(java.lang.Object o) {
    if (o == null) {
        return "null";
    }
    return o.toString().replace("\n", "\n    ");
}

想法是它可以将附加中的"\n " 转换为"\n " 等等,但我不确定是否可以在 Eclipse 模板中调用函数。

任何人都知道如何做到这一点?我已经检查了文档,但它非常稀疏。也查看了所有内容,但我没有看到任何类似的问题。

作为参考,我专门使用 Spring Tool Suite 版本 4.0.1RELEASE。

【问题讨论】:

  • toString() 中缩进AlbumArrays.toString(songs).replace("\n", "\n ")(而不是Arrays.toString(songs))。
  • @howlger 但如何在 Eclipse 生成器模板中做到这一点?实际上,我现在有一个解决方案,我将在今晚晚些时候有机会时发布。它需要创建一个自定义 toString() 构建器。我更喜欢单独使用模板,但我不确定目前是否可行。

标签: java eclipse tostring spring-tool-suite


【解决方案1】:

这不是我希望的方式,但我确实有一个解决方案。通过创建custom toString() builder class

,我能够完成我想要的

这是我创建的类:

/*
 * Helper class to generate formatted toString() methods for pojos
 */
public class CustomToStringBuilder {
    private StringBuilder builder;
    private Object o;

    public CustomToStringBuilder(Object o) {
         builder = new StringBuilder();
         this.o = o;
    }

    public CustomToStringBuilder appendItem(String s, Object o) {
        builder.append("    ").append(s).append(": ").append(toIndentedString(o)).append("\n");
        return this;
    }

    public String getString() {
        return "class " + o.getClass().getSimpleName() + "{ \n" + builder.toString() + "}";
    }

    /**
     * Convert the given object to string with each line indented by 4 spaces
     * (except the first line).
     */
    private static String toIndentedString(java.lang.Object o) {
        if (o == null) {
            return "null";
        }
        return o.toString().replace("\n", "\n    ");
    }
}

然后我可以使用Alt + Shift + S -> "Generate toString()..." 和 "select Custom toString() builder" 并选择我的@987654326 @。这样,Eclipse 将为SongAlbum 生成以下代码:

//Song
@Override
public String toString() {
    CustomToStringBuilder builder = new CustomToStringBuilder(this);
    builder.appendItem("title", title).appendItem("lengthInSeconds", lengthInSeconds);
    return builder.getString();
}

//Album
@Override
public String toString() {
    CustomToStringBuilder builder = new CustomToStringBuilder(this);
    builder.appendItem("songs", songs).appendItem("songCount", songCount);
    return builder.getString();
}

将它们放在一起并再次运行我的测试会给我想要的结果:

class Album{ 
    songs: [class Song{ 
        title: We Will Rock You
        lengthInSeconds: 200
    }, class Song{ 
        title: Beat it
        lengthInSeconds: 150
    }, class Song{ 
        title: Piano Man
        lengthInSeconds: 400
    }]
    songCount: 3
}

但是,如果可能的话,我仍然更喜欢不需要向源代码添加新类的方法,所以我将把问题留一两天,看看是否有人能找到不同的方法来做这件事更容易。

【讨论】:

    猜你喜欢
    • 2020-07-11
    • 2017-09-12
    • 2014-11-12
    • 1970-01-01
    • 1970-01-01
    • 2012-04-25
    • 2020-06-06
    • 2011-09-19
    • 1970-01-01
    相关资源
    最近更新 更多