Генератор Eclipse toString () с вложенным отступом - PullRequest
0 голосов
/ 03 января 2019

Eclipse имеет удобный шаблон для автоматической генерации метода toString() для класса.Вы можете получить к нему доступ, нажав Alt + Shift + S и нажав «Generate toString()...»

. Здесь вы можете выбрать, какие поля включить в производную toString(), иустановите другие параметры, чтобы определить, как это должно быть сгенерировано.

Я хотел бы использовать его для быстрой генерации toString() методов для большого количества классов.

Возьмите этот пример, вотSong class:

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, который содержит массив Song s:

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

}

В настоящее время я использую этот шаблон для генерации моего *Методы 1023 * (с опцией «StringBuilder / StringBuffer - chained Calls»):

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

, которые теперь можно использовать для генерации toString() для Song:

@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
}

и продолжать делать это в случае of больше классов внутри каждого объекта, если это имеет смысл.

Я пытался создать метод, который мог бы заменить символ новой строки на 4 пробела и символ новой строки перед вызовом его toString():

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

Идея состояла в том, что он мог бы повернуться "\n " в приложении к "\n " и так далее, но я не уверен, возможно ли вообще вызвать функцию внутри шаблона затмения.

Кто-нибудь знает, как это сделать?Я проверил документацию, но она довольно редкая.Посмотрел также SO, но я не вижу подобных вопросов.

Для справки я специально использую Spring Tool Suite версии 4.0.1RELEASE.

1 Ответ

0 голосов
/ 04 января 2019

Я не надеялся это сделать, но у меня есть решение. Я смог выполнить то, что хотел, создав пользовательский класс конструктора toString ()

Вот класс, который я создал:

/*
 * 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 () ...» и « выбрать Custom toString () builder » и выбрать мой CustomToStringBuilder , При этом Eclipse генерирует следующий код для Song и Album:

//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
}

Однако я все же предпочел бы метод, который не требует добавления нового класса в исходный код, если это возможно, поэтому я оставлю вопрос открытым на день или два, чтобы посмотреть, сможет ли кто-нибудь найти другой способ сделать это легче.

...