I could provide a PR. You can use set Length instead of delete in String Builder btw  @SplotyCode please if you have time :) @SplotyCode Thanks for your suggestion, it's much better.
please keep old "for loop" style to reduce GC.  Please keep using old "for loop" style to reduce GC
The method toString() of MqttSubscribePayload throw ArrayIndexOutOfBoundsException
### Expected behavior
print MqttSubscribePayload correctly
### Actual behavior
ArrayIndexOutOfBoundsException was thrown
### Steps to reproduce
new a MqttSubscribePayload which has no topicSubscriptions(size of List<MqttTopicSubscription> is 0)

Though the MqttSubscribePayload couldn't be empty in MQTT protocol. There also some cases like unit test that should cover this situation.
So, I think the code below seems not gracefully enough.

```
    @Override
    public String toString() {
        StringBuilder builder = new StringBuilder(StringUtil.simpleClassName(this)).append('[');
        for (int i = 0; i < topicSubscriptions.size() - 1; i++) {
            builder.append(topicSubscriptions.get(i)).append(", ");
        }
        builder.append(topicSubscriptions.get(topicSubscriptions.size() - 1));
        builder.append(']');
        return builder.toString();
    }
```
Could we implement it like this below?
```
    @Override
    public String toString() {
        StringBuilder builder = new StringBuilder(StringUtil.simpleClassName(this)).append('[');
        for (int i = 0; i <= topicSubscriptions.size() - 1; i++) {
            builder.append(topicSubscriptions.get(i)).append(", ");
        }
        if (builder.substring(builder.length() - 2).equals(", ")) {
            builder.delete(builder.length() - 2, builder.length());
        }
        builder.append(']');
        return builder.toString();
    }
```
### Minimal yet complete reproducer code (or URL to code)
```
    @Test
    public void test_MqttSubscribePayload_toString() {
        List<MqttTopicSubscription> subscriptions = new ArrayList<>();
        MqttSubscribePayload payload = new MqttSubscribePayload(subscriptions);

        System.out.println(payload.toString());
    }
```
### Netty version
4.1.32.Final
### JVM version (e.g. `java -version`)
java version "1.8.0_201"
Java(TM) SE Runtime Environment (build 1.8.0_201-b09)
Java HotSpot(TM) 64-Bit Server VM (build 25.201-b09, mixed mode)

### OS version (e.g. `uname -a`)
windows
codec-mqtt/src/main/java/io/netty/handler/codec/mqtt/MqttSubscribePayload.java codec-mqtt/src/main/java/io/netty/handler/codec/mqtt/MqttUnsubscribePayload.java
codec-mqtt/src/main/java/io/netty/handler/codec/mqtt/MqttSubscribePayload.java codec-mqtt/src/main/java/io/netty/handler/codec/mqtt/MqttUnsubscribePayload.java
codec-mqtt/src/test/java/io/netty/handler/codec/mqtt/MqttConnectPayloadTest.java
diff --git a/codec-mqtt/src/main/java/io/netty/handler/codec/mqtt/MqttSubscribePayload.java b/codec-mqtt/src/main/java/io/netty/handler/codec/mqtt/MqttSubscribePayload.java
index eb1b9c9c572..aa3a3244740 100644
--- a/codec-mqtt/src/main/java/io/netty/handler/codec/mqtt/MqttSubscribePayload.java
+++ b/codec-mqtt/src/main/java/io/netty/handler/codec/mqtt/MqttSubscribePayload.java
@@ -39,11 +39,12 @@ public List<MqttTopicSubscription> topicSubscriptions() {
     @Override
     public String toString() {
         StringBuilder builder = new StringBuilder(StringUtil.simpleClassName(this)).append('[');
-        for (int i = 0; i < topicSubscriptions.size() - 1; i++) {
+        for (int i = 0; i < topicSubscriptions.size(); i++) {
             builder.append(topicSubscriptions.get(i)).append(", ");
         }
-        builder.append(topicSubscriptions.get(topicSubscriptions.size() - 1));
-        builder.append(']');
-        return builder.toString();
+        if (!topicSubscriptions.isEmpty()) {
+            builder.setLength(builder.length() - 2);
+        }
+        return builder.append(']').toString();
     }
 }
diff --git a/codec-mqtt/src/main/java/io/netty/handler/codec/mqtt/MqttUnsubscribePayload.java b/codec-mqtt/src/main/java/io/netty/handler/codec/mqtt/MqttUnsubscribePayload.java
index b032d12067a..9812bd9923c 100644
--- a/codec-mqtt/src/main/java/io/netty/handler/codec/mqtt/MqttUnsubscribePayload.java
+++ b/codec-mqtt/src/main/java/io/netty/handler/codec/mqtt/MqttUnsubscribePayload.java
@@ -39,11 +39,12 @@ public List<String> topics() {
     @Override
     public String toString() {
         StringBuilder builder = new StringBuilder(StringUtil.simpleClassName(this)).append('[');
-        for (int i = 0; i < topics.size() - 1; i++) {
+        for (int i = 0; i < topics.size(); i++) {
             builder.append("topicName = ").append(topics.get(i)).append(", ");
         }
-        builder.append("topicName = ").append(topics.get(topics.size() - 1))
-               .append(']');
-        return builder.toString();
+        if (!topics.isEmpty()) {
+            builder.setLength(builder.length() - 2);
+        }
+        return builder.append("]").toString();
     }
 }

diff --git a/codec-mqtt/src/test/java/io/netty/handler/codec/mqtt/MqttConnectPayloadTest.java b/codec-mqtt/src/test/java/io/netty/handler/codec/mqtt/MqttConnectPayloadTest.java
index 5a929dc1e5e..f1d9dc0db10 100644
--- a/codec-mqtt/src/test/java/io/netty/handler/codec/mqtt/MqttConnectPayloadTest.java
+++ b/codec-mqtt/src/test/java/io/netty/handler/codec/mqtt/MqttConnectPayloadTest.java
@@ -21,6 +21,8 @@
 import io.netty.util.CharsetUtil;
 import org.junit.Test;
 
+import java.util.Collections;
+
 public class MqttConnectPayloadTest {
 
     @Test
@@ -88,4 +90,11 @@ public void testBuilderNullWillMessage() throws Exception {
         assertNull(mqttConnectPayload.willMessageInBytes());
         assertNull(mqttConnectPayload.willMessage());
     }
+
+    /* See https://github.com/netty/netty/pull/9202 */
+    @Test
+    public void testEmptyTopicsToString() {
+        new MqttSubscribePayload(Collections.<MqttTopicSubscription>emptyList()).toString();
+        new MqttUnsubscribePayload(Collections.<String>emptyList()).toString();
+    }
 }
