Revisit array conversion: introduce/use empty arrays.

Change-Id: I9fda3ebd979ceb5549b37baf00b419e638b3dcea
diff --git a/src/main/java/com/android/tools/r8/code/Instruction.java b/src/main/java/com/android/tools/r8/code/Instruction.java
index c451db2..d7e67d4 100644
--- a/src/main/java/com/android/tools/r8/code/Instruction.java
+++ b/src/main/java/com/android/tools/r8/code/Instruction.java
@@ -19,9 +19,10 @@
 import java.util.function.BiPredicate;
 
 public abstract class Instruction {
+  public static final Instruction[] EMPTY_ARRAY = {};
 
   public final static int[] NO_TARGETS = null;
-  public final static int[] EXIT_TARGET = new int[]{};
+  public final static int[] EXIT_TARGET = {};
 
   public int offset;
 
diff --git a/src/main/java/com/android/tools/r8/code/InstructionFactory.java b/src/main/java/com/android/tools/r8/code/InstructionFactory.java
index 83b0570..6b60f29 100644
--- a/src/main/java/com/android/tools/r8/code/InstructionFactory.java
+++ b/src/main/java/com/android/tools/r8/code/InstructionFactory.java
@@ -26,7 +26,7 @@
       Instruction instruction = readFrom(range, mapping);
       insn.add(instruction);
     }
-    return insn.toArray(new Instruction[insn.size()]);
+    return insn.toArray(Instruction.EMPTY_ARRAY);
   }
 
   private static class ShortBufferBytecodeStream implements BytecodeStream {
diff --git a/src/main/java/com/android/tools/r8/dex/ApplicationWriter.java b/src/main/java/com/android/tools/r8/dex/ApplicationWriter.java
index d4fb8e3..ac91a4f 100644
--- a/src/main/java/com/android/tools/r8/dex/ApplicationWriter.java
+++ b/src/main/java/com/android/tools/r8/dex/ApplicationWriter.java
@@ -443,7 +443,7 @@
         DexAnnotation[] copy =
             ObjectArrays.concat(
                 clazz.annotations.annotations,
-                annotations.toArray(new DexAnnotation[annotations.size()]),
+                annotations.toArray(DexAnnotation.EMPTY_ARRAY),
                 DexAnnotation.class);
         clazz.annotations = new DexAnnotationSet(copy);
       }
diff --git a/src/main/java/com/android/tools/r8/dex/DexParser.java b/src/main/java/com/android/tools/r8/dex/DexParser.java
index 9f28bfc..28044b5 100644
--- a/src/main/java/com/android/tools/r8/dex/DexParser.java
+++ b/src/main/java/com/android/tools/r8/dex/DexParser.java
@@ -530,7 +530,7 @@
         }
       }
     }
-    return new DexDebugInfo(start, parameters, events.toArray(new DexDebugEvent[events.size()]));
+    return new DexDebugInfo(start, parameters, events.toArray(DexDebugEvent.EMPTY_ARRAY));
   }
 
   private static class MemberAnnotationIterator<S extends Descriptor<?, S>, T extends DexItem> {
@@ -1131,7 +1131,7 @@
         int size = lazyAnnotations.size();
         return size == 0
             ? DexAnnotationSet.empty()
-            : new DexAnnotationSet(lazyAnnotations.toArray(new DexAnnotation[size]));
+            : new DexAnnotationSet(lazyAnnotations.toArray(DexAnnotation.EMPTY_ARRAY));
       }
       return originalAnnotations;
     }
diff --git a/src/main/java/com/android/tools/r8/dex/JumboStringRewriter.java b/src/main/java/com/android/tools/r8/dex/JumboStringRewriter.java
index b2a3e09..2936d80 100644
--- a/src/main/java/com/android/tools/r8/dex/JumboStringRewriter.java
+++ b/src/main/java/com/android/tools/r8/dex/JumboStringRewriter.java
@@ -126,7 +126,7 @@
             oldCode.registerSize,
             oldCode.incomingRegisterSize,
             oldCode.outgoingRegisterSize,
-            newInstructions.toArray(new Instruction[newInstructions.size()]),
+            newInstructions.toArray(Instruction.EMPTY_ARRAY),
             newTries,
             newHandlers,
             newDebugInfo);
@@ -245,7 +245,7 @@
       return new DexDebugInfo(
           code.getDebugInfo().startLine,
           code.getDebugInfo().parameters,
-          events.toArray(new DexDebugEvent[events.size()]));
+          events.toArray(DexDebugEvent.EMPTY_ARRAY));
     }
     return code.getDebugInfo();
   }
diff --git a/src/main/java/com/android/tools/r8/graph/DexAnnotation.java b/src/main/java/com/android/tools/r8/graph/DexAnnotation.java
index 1168c45..6fc1e1d 100644
--- a/src/main/java/com/android/tools/r8/graph/DexAnnotation.java
+++ b/src/main/java/com/android/tools/r8/graph/DexAnnotation.java
@@ -22,6 +22,7 @@
 import java.util.function.Function;
 
 public class DexAnnotation extends DexItem {
+  public static final DexAnnotation[] EMPTY_ARRAY = {};
   public static final int VISIBILITY_BUILD = 0x00;
   public static final int VISIBILITY_RUNTIME = 0x01;
   public static final int VISIBILITY_SYSTEM = 0x02;
@@ -198,7 +199,7 @@
     return createSystemValueAnnotation(factory.annotationDefault, factory,
         new DexValueAnnotation(
             new DexEncodedAnnotation(type,
-                defaults.toArray(new DexAnnotationElement[defaults.size()])))
+                defaults.toArray(DexAnnotationElement.EMPTY_ARRAY)))
     );
   }
 
@@ -306,7 +307,7 @@
       at = endAt;
     }
 
-    return new DexValueArray(parts.toArray(new DexValue[parts.size()]));
+    return new DexValueArray(parts.toArray(DexValue.EMPTY_ARRAY));
   }
 
   private static DexValue toDexValue(String string, DexItemFactory factory) {
diff --git a/src/main/java/com/android/tools/r8/graph/DexAnnotationElement.java b/src/main/java/com/android/tools/r8/graph/DexAnnotationElement.java
index 040d256..10c6535 100644
--- a/src/main/java/com/android/tools/r8/graph/DexAnnotationElement.java
+++ b/src/main/java/com/android/tools/r8/graph/DexAnnotationElement.java
@@ -7,6 +7,7 @@
 import com.android.tools.r8.dex.MixedSectionCollection;
 
 public class DexAnnotationElement extends DexItem {
+  public static final DexAnnotationElement[] EMPTY_ARRAY = {};
 
   public final DexString name;
   public final DexValue value;
diff --git a/src/main/java/com/android/tools/r8/graph/DexClass.java b/src/main/java/com/android/tools/r8/graph/DexClass.java
index 8f9a0b6..82678c7 100644
--- a/src/main/java/com/android/tools/r8/graph/DexClass.java
+++ b/src/main/java/com/android/tools/r8/graph/DexClass.java
@@ -23,6 +23,7 @@
 import java.util.function.Predicate;
 
 public abstract class DexClass extends DexDefinition {
+  public static final DexClass[] EMPTY_ARRAY = {};
 
   public interface FieldSetter {
     void setField(int index, DexEncodedField field);
@@ -32,8 +33,6 @@
     void setMethod(int index, DexEncodedMethod method);
   }
 
-  private static final DexEncodedMethod[] NO_METHODS = {};
-  private static final DexEncodedField[] NO_FIELDS = {};
   private Optional<DexEncodedMethod> cachedClassInitializer = null;
 
   public final Origin origin;
@@ -44,16 +43,16 @@
   public DexString sourceFile;
 
   /** Access has to be synchronized during concurrent collection/writing phase. */
-  protected DexEncodedField[] staticFields = NO_FIELDS;
+  protected DexEncodedField[] staticFields = DexEncodedField.EMPTY_ARRAY;
 
   /** Access has to be synchronized during concurrent collection/writing phase. */
-  protected DexEncodedField[] instanceFields = NO_FIELDS;
+  protected DexEncodedField[] instanceFields = DexEncodedField.EMPTY_ARRAY;
 
   /** Access has to be synchronized during concurrent collection/writing phase. */
-  protected DexEncodedMethod[] directMethods = NO_METHODS;
+  protected DexEncodedMethod[] directMethods = DexEncodedMethod.EMPTY_ARRAY;
 
   /** Access has to be synchronized during concurrent collection/writing phase. */
-  protected DexEncodedMethod[] virtualMethods = NO_METHODS;
+  protected DexEncodedMethod[] virtualMethods = DexEncodedMethod.EMPTY_ARRAY;
 
   /** Enclosing context of this class if it is an inner class, null otherwise. */
   private EnclosingMethodAttribute enclosingMethod;
@@ -182,7 +181,7 @@
 
   public void setDirectMethods(DexEncodedMethod[] methods) {
     cachedClassInitializer = null;
-    directMethods = MoreObjects.firstNonNull(methods, NO_METHODS);
+    directMethods = MoreObjects.firstNonNull(methods, DexEncodedMethod.EMPTY_ARRAY);
     assert verifyCorrectnessOfMethodHolders(directMethods());
     assert verifyNoDuplicateMethods();
   }
@@ -232,7 +231,7 @@
   }
 
   public void setVirtualMethods(DexEncodedMethod[] methods) {
-    virtualMethods = MoreObjects.firstNonNull(methods, NO_METHODS);
+    virtualMethods = MoreObjects.firstNonNull(methods, DexEncodedMethod.EMPTY_ARRAY);
     assert verifyCorrectnessOfMethodHolders(virtualMethods());
     assert verifyNoDuplicateMethods();
   }
@@ -394,7 +393,7 @@
   }
 
   public void setStaticFields(DexEncodedField[] fields) {
-    staticFields = MoreObjects.firstNonNull(fields, NO_FIELDS);
+    staticFields = MoreObjects.firstNonNull(fields, DexEncodedField.EMPTY_ARRAY);
     assert verifyCorrectnessOfFieldHolders(staticFields());
     assert verifyNoDuplicateFields();
   }
@@ -453,7 +452,7 @@
   }
 
   public void setInstanceFields(DexEncodedField[] fields) {
-    instanceFields = MoreObjects.firstNonNull(fields, NO_FIELDS);
+    instanceFields = MoreObjects.firstNonNull(fields, DexEncodedField.EMPTY_ARRAY);
     assert verifyCorrectnessOfFieldHolders(instanceFields());
     assert verifyNoDuplicateFields();
   }
diff --git a/src/main/java/com/android/tools/r8/graph/DexDebugEvent.java b/src/main/java/com/android/tools/r8/graph/DexDebugEvent.java
index 779678d..f790131 100644
--- a/src/main/java/com/android/tools/r8/graph/DexDebugEvent.java
+++ b/src/main/java/com/android/tools/r8/graph/DexDebugEvent.java
@@ -11,6 +11,7 @@
 import java.util.Objects;
 
 abstract public class DexDebugEvent extends DexItem {
+  public static final DexDebugEvent[] EMPTY_ARRAY = {};
 
   @Override
   public void collectIndexedItems(IndexedItemCollection collection,
diff --git a/src/main/java/com/android/tools/r8/graph/DexDebugEventBuilder.java b/src/main/java/com/android/tools/r8/graph/DexDebugEventBuilder.java
index 6be948b..53d2835 100644
--- a/src/main/java/com/android/tools/r8/graph/DexDebugEventBuilder.java
+++ b/src/main/java/com/android/tools/r8/graph/DexDebugEventBuilder.java
@@ -118,7 +118,7 @@
         params[i] = (local == null || local.signature != null) ? null : local.name;
       }
     }
-    return new DexDebugInfo(startLine, params, events.toArray(new DexDebugEvent[events.size()]));
+    return new DexDebugInfo(startLine, params, events.toArray(DexDebugEvent.EMPTY_ARRAY));
   }
 
   private void updateBlockEntry(Instruction instruction) {
diff --git a/src/main/java/com/android/tools/r8/graph/DexEncodedField.java b/src/main/java/com/android/tools/r8/graph/DexEncodedField.java
index ec1506a..3a1dfc5 100644
--- a/src/main/java/com/android/tools/r8/graph/DexEncodedField.java
+++ b/src/main/java/com/android/tools/r8/graph/DexEncodedField.java
@@ -11,8 +11,7 @@
 import com.android.tools.r8.utils.InternalOptions;
 
 public class DexEncodedField extends KeyedDexItem<DexField> {
-
-  public static final DexEncodedField[] EMPTY_ARRAY = new DexEncodedField[]{};
+  public static final DexEncodedField[] EMPTY_ARRAY = {};
 
   public final DexField field;
   public final FieldAccessFlags accessFlags;
diff --git a/src/main/java/com/android/tools/r8/graph/DexEncodedMethod.java b/src/main/java/com/android/tools/r8/graph/DexEncodedMethod.java
index 9546590..3d3ed81 100644
--- a/src/main/java/com/android/tools/r8/graph/DexEncodedMethod.java
+++ b/src/main/java/com/android/tools/r8/graph/DexEncodedMethod.java
@@ -91,7 +91,7 @@
     PROCESSED_INLINING_CANDIDATE_SAME_CLASS,
   }
 
-  public static final DexEncodedMethod[] EMPTY_ARRAY = new DexEncodedMethod[]{};
+  public static final DexEncodedMethod[] EMPTY_ARRAY = {};
   public static final DexEncodedMethod SENTINEL =
       new DexEncodedMethod(null, null, null, null, null);
 
diff --git a/src/main/java/com/android/tools/r8/graph/DexProgramClass.java b/src/main/java/com/android/tools/r8/graph/DexProgramClass.java
index 4312bfd..20f4b19 100644
--- a/src/main/java/com/android/tools/r8/graph/DexProgramClass.java
+++ b/src/main/java/com/android/tools/r8/graph/DexProgramClass.java
@@ -19,9 +19,10 @@
 import java.util.function.Supplier;
 
 public class DexProgramClass extends DexClass implements Supplier<DexProgramClass> {
+  public static final DexProgramClass[] EMPTY_ARRAY = {};
 
   private static final DexEncodedArray SENTINEL_NOT_YET_COMPUTED =
-      new DexEncodedArray(new DexValue[0]);
+      new DexEncodedArray(DexValue.EMPTY_ARRAY);
 
   private final ProgramResource.Kind originKind;
   private DexEncodedArray staticValues = SENTINEL_NOT_YET_COMPUTED;
@@ -282,12 +283,10 @@
             length = i + 1;
           }
         }
-        if (length > 0) {
-          staticValues = new DexEncodedArray(
-              values.subList(0, length).toArray(new DexValue[length]));
-        } else {
-          staticValues = null;
-        }
+        staticValues =
+            length > 0
+                ? new DexEncodedArray(values.subList(0, length).toArray(DexValue.EMPTY_ARRAY))
+                : null;
       }
     }
   }
diff --git a/src/main/java/com/android/tools/r8/graph/DexType.java b/src/main/java/com/android/tools/r8/graph/DexType.java
index 83ab503..f41f466 100644
--- a/src/main/java/com/android/tools/r8/graph/DexType.java
+++ b/src/main/java/com/android/tools/r8/graph/DexType.java
@@ -30,14 +30,14 @@
 import java.util.function.Predicate;
 
 public class DexType extends DexReference implements PresortedComparable<DexType> {
-
-  private final static int ROOT_LEVEL = 0;
-  private final static int UNKNOWN_LEVEL = -1;
-  private final static int INTERFACE_LEVEL = -2;
+  public static final DexType[] EMPTY_ARRAY = {};
+  private static final int ROOT_LEVEL = 0;
+  private static final int UNKNOWN_LEVEL = -1;
+  private static final int INTERFACE_LEVEL = -2;
 
   // Since most Java types has no sub-types, we can just share an empty immutable set until we need
   // to add to it.
-  private final static Set<DexType> NO_DIRECT_SUBTYPE = ImmutableSet.of();
+  private static final Set<DexType> NO_DIRECT_SUBTYPE = ImmutableSet.of();
 
   public final DexString descriptor;
   private String toStringCache = null;
diff --git a/src/main/java/com/android/tools/r8/graph/DexTypeList.java b/src/main/java/com/android/tools/r8/graph/DexTypeList.java
index 45a1548..a124bc4 100644
--- a/src/main/java/com/android/tools/r8/graph/DexTypeList.java
+++ b/src/main/java/com/android/tools/r8/graph/DexTypeList.java
@@ -20,7 +20,7 @@
   }
 
   private DexTypeList() {
-    this.values = new DexType[0];
+    this.values = DexType.EMPTY_ARRAY;
   }
 
   public DexTypeList(DexType[] values) {
diff --git a/src/main/java/com/android/tools/r8/graph/DexValue.java b/src/main/java/com/android/tools/r8/graph/DexValue.java
index c582d0f..4f12fda 100644
--- a/src/main/java/com/android/tools/r8/graph/DexValue.java
+++ b/src/main/java/com/android/tools/r8/graph/DexValue.java
@@ -22,6 +22,7 @@
 import org.objectweb.asm.Type;
 
 public abstract class DexValue extends DexItem {
+  public static final DexValue[] EMPTY_ARRAY = {};
 
   public static final UnknownDexValue UNKNOWN = UnknownDexValue.UNKNOWN;
 
diff --git a/src/main/java/com/android/tools/r8/graph/JarClassFileReader.java b/src/main/java/com/android/tools/r8/graph/JarClassFileReader.java
index 3170b63..e788222 100644
--- a/src/main/java/com/android/tools/r8/graph/JarClassFileReader.java
+++ b/src/main/java/com/android/tools/r8/graph/JarClassFileReader.java
@@ -335,10 +335,10 @@
               enclosingMember,
               innerClasses,
               createAnnotationSet(annotations),
-              staticFields.toArray(new DexEncodedField[staticFields.size()]),
-              instanceFields.toArray(new DexEncodedField[instanceFields.size()]),
-              directMethods.toArray(new DexEncodedMethod[directMethods.size()]),
-              virtualMethods.toArray(new DexEncodedMethod[virtualMethods.size()]),
+              staticFields.toArray(DexEncodedField.EMPTY_ARRAY),
+              instanceFields.toArray(DexEncodedField.EMPTY_ARRAY),
+              directMethods.toArray(DexEncodedMethod.EMPTY_ARRAY),
+              virtualMethods.toArray(DexEncodedMethod.EMPTY_ARRAY),
               application.getFactory().getSkipNameValidationForTesting());
       if (clazz.isProgramClass()) {
         context.owner = clazz.asProgramClass();
@@ -416,7 +416,7 @@
   private static DexAnnotationSet createAnnotationSet(List<DexAnnotation> annotations) {
     return annotations == null || annotations.isEmpty()
         ? DexAnnotationSet.empty()
-        : new DexAnnotationSet(annotations.toArray(new DexAnnotation[annotations.size()]));
+        : new DexAnnotationSet(annotations.toArray(DexAnnotation.EMPTY_ARRAY));
   }
 
   private static class CreateFieldVisitor extends FieldVisitor {
@@ -673,8 +673,8 @@
               method, parent.origin, parameterCount, parameterNames.size());
         }
         getAnnotations().add(DexAnnotation.createMethodParametersAnnotation(
-            parameterNames.toArray(new DexValue[parameterNames.size()]),
-            parameterFlags.toArray(new DexValue[parameterFlags.size()]),
+            parameterNames.toArray(DexValue.EMPTY_ARRAY),
+            parameterFlags.toArray(DexValue.EMPTY_ARRAY),
             parent.application.getFactory()));
       }
       DexEncodedMethod dexMethod =
@@ -765,7 +765,7 @@
     public AnnotationVisitor visitArray(String name) {
       return new CreateAnnotationVisitor(application, (names, values) -> {
         assert names == null;
-        addElement(name, new DexValueArray(values.toArray(new DexValue[values.size()])));
+        addElement(name, new DexValueArray(values.toArray(DexValue.EMPTY_ARRAY)));
       });
     }
 
diff --git a/src/main/java/com/android/tools/r8/graph/ObjectToOffsetMapping.java b/src/main/java/com/android/tools/r8/graph/ObjectToOffsetMapping.java
index 5cbdf26..a29ae60 100644
--- a/src/main/java/com/android/tools/r8/graph/ObjectToOffsetMapping.java
+++ b/src/main/java/com/android/tools/r8/graph/ObjectToOffsetMapping.java
@@ -134,8 +134,8 @@
     }
   }
 
-  private static DexProgramClass[] sortClasses(DexApplication application,
-      Collection<DexProgramClass> classes) {
+  private static DexProgramClass[] sortClasses(
+      DexApplication application, Collection<DexProgramClass> classes) {
     // Collect classes in subtyping order, based on a sorted list of classes to start with.
     ProgramClassDepthsMemoized classDepths = new ProgramClassDepthsMemoized(application);
     List<DexProgramClass> sortedClasses =
@@ -148,7 +148,7 @@
                   return dx != dy ? dx - dy : x.type.compareTo(y.type);
                 })
             .collect(Collectors.toList());
-    return sortedClasses.toArray(new DexProgramClass[sortedClasses.size()]);
+    return sortedClasses.toArray(DexProgramClass.EMPTY_ARRAY);
   }
 
   private static <T> Collection<T> keysOrEmpty(Map<T, ?> map) {
diff --git a/src/main/java/com/android/tools/r8/ir/conversion/CallGraph.java b/src/main/java/com/android/tools/r8/ir/conversion/CallGraph.java
index f8465d0..1668959 100644
--- a/src/main/java/com/android/tools/r8/ir/conversion/CallGraph.java
+++ b/src/main/java/com/android/tools/r8/ir/conversion/CallGraph.java
@@ -154,7 +154,7 @@
       InternalOptions options,
       Timing timing) {
     CallGraph graph = new CallGraph(options);
-    DexClass[] classes = application.classes().toArray(new DexClass[application.classes().size()]);
+    DexClass[] classes = application.classes().toArray(DexClass.EMPTY_ARRAY);
     Arrays.sort(classes, (DexClass a, DexClass b) -> a.type.slowCompareTo(b.type));
     for (DexClass clazz : classes) {
       for (DexEncodedMethod method : clazz.allMethodsSorted()) {
@@ -304,7 +304,7 @@
 
       // Sort the callees before calling traverse recursively. This will ensure cycles are broken
       // the same way across multiple invocations of the R8 compiler.
-      Node[] callees = node.callees.toArray(new Node[node.callees.size()]);
+      Node[] callees = node.callees.toArray(new Node[]{});
       Arrays.sort(callees, (Node a, Node b) -> a.method.method.slowCompareTo(b.method.method));
       if (options.testing.nondeterministicCycleElimination) {
         reorderNodes(Arrays.asList(callees));
diff --git a/src/main/java/com/android/tools/r8/ir/conversion/DexBuilder.java b/src/main/java/com/android/tools/r8/ir/conversion/DexBuilder.java
index 6fbe1e2..f295ddd 100644
--- a/src/main/java/com/android/tools/r8/ir/conversion/DexBuilder.java
+++ b/src/main/java/com/android/tools/r8/ir/conversion/DexBuilder.java
@@ -266,7 +266,7 @@
             registerAllocator.registersUsed(),
             inRegisterCount,
             outRegisterCount,
-            dexInstructions.toArray(new Instruction[dexInstructions.size()]),
+            dexInstructions.toArray(Instruction.EMPTY_ARRAY),
             tryInfo.tries,
             tryInfo.handlers,
             debugEventBuilder.build());
@@ -809,7 +809,7 @@
           pairs.add(new TypeAddrPair(type, targetOffset));
         }
       }
-      TypeAddrPair[] pairsArray = pairs.toArray(new TypeAddrPair[pairs.size()]);
+      TypeAddrPair[] pairsArray = pairs.toArray(new TypeAddrPair[]{});
       handlers[j] = new TryHandler(pairsArray, catchAllOffset);
     }
     return handlers;
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/InterfaceProcessor.java b/src/main/java/com/android/tools/r8/ir/desugar/InterfaceProcessor.java
index e91f1cc..eabaec5 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/InterfaceProcessor.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/InterfaceProcessor.java
@@ -111,8 +111,7 @@
 
     // If at least one bridge method was removed then update the table.
     if (remainingMethods.size() < iface.virtualMethods().size()) {
-      iface.setVirtualMethods(remainingMethods.toArray(
-          new DexEncodedMethod[remainingMethods.size()]));
+      iface.setVirtualMethods(remainingMethods.toArray(DexEncodedMethod.EMPTY_ARRAY));
     }
     remainingMethods.clear();
 
@@ -165,8 +164,7 @@
       }
     }
     if (remainingMethods.size() < iface.directMethods().size()) {
-      iface.setDirectMethods(remainingMethods.toArray(
-          new DexEncodedMethod[remainingMethods.size()]));
+      iface.setDirectMethods(remainingMethods.toArray(DexEncodedMethod.EMPTY_ARRAY));
     }
 
     if (companionMethods.isEmpty()) {
@@ -198,7 +196,7 @@
             DexAnnotationSet.empty(),
             DexEncodedField.EMPTY_ARRAY,
             DexEncodedField.EMPTY_ARRAY,
-            companionMethods.toArray(new DexEncodedMethod[companionMethods.size()]),
+            companionMethods.toArray(DexEncodedMethod.EMPTY_ARRAY),
             DexEncodedMethod.EMPTY_ARRAY,
             rewriter.factory.getSkipNameValidationForTesting(),
             Collections.singletonList(iface));
@@ -273,7 +271,7 @@
             DexAnnotationSet.empty(),
             DexEncodedField.EMPTY_ARRAY,
             DexEncodedField.EMPTY_ARRAY,
-            dispatchMethods.toArray(new DexEncodedMethod[dispatchMethods.size()]),
+            dispatchMethods.toArray(DexEncodedMethod.EMPTY_ARRAY),
             DexEncodedMethod.EMPTY_ARRAY,
             rewriter.factory.getSkipNameValidationForTesting(),
             callers);
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/LambdaClass.java b/src/main/java/com/android/tools/r8/ir/desugar/LambdaClass.java
index 857de34..3dd9322 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/LambdaClass.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/LambdaClass.java
@@ -296,8 +296,9 @@
   // Build a list of implemented interfaces.
   private DexTypeList buildInterfaces() {
     List<DexType> interfaces = descriptor.interfaces;
-    return interfaces.isEmpty() ? DexTypeList.empty()
-        : new DexTypeList(interfaces.toArray(new DexType[interfaces.size()]));
+    return interfaces.isEmpty()
+        ? DexTypeList.empty()
+        : new DexTypeList(interfaces.toArray(DexType.EMPTY_ARRAY));
   }
 
   // Creates a delegation target for this particular lambda class. Note that we
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/Outliner.java b/src/main/java/com/android/tools/r8/ir/optimize/Outliner.java
index f5fca72..41c0073 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/Outliner.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/Outliner.java
@@ -566,7 +566,7 @@
 
     DexProto buildProto() {
       if (proto == null) {
-        DexType[] argumentTypesArray = argumentTypes.toArray(new DexType[argumentTypes.size()]);
+        DexType[] argumentTypesArray = argumentTypes.toArray(DexType.EMPTY_ARRAY);
         proto = appView.dexItemFactory().createProto(returnType, argumentTypesArray);
       }
       return proto;
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/lambda/kotlin/KotlinLambdaGroupClassBuilder.java b/src/main/java/com/android/tools/r8/ir/optimize/lambda/kotlin/KotlinLambdaGroupClassBuilder.java
index 237b044..4226daa 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/lambda/kotlin/KotlinLambdaGroupClassBuilder.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/lambda/kotlin/KotlinLambdaGroupClassBuilder.java
@@ -61,9 +61,10 @@
   // Take the attribute from the group, if exists.
   @Override
   protected List<InnerClassAttribute> buildInnerClasses() {
-    return !id.hasInnerClassAttribute() ? Collections.emptyList()
-        : Lists.newArrayList(new InnerClassAttribute(
-            id.innerClassAccess, group.getGroupClassType(), null, null));
+    return !id.hasInnerClassAttribute()
+        ? Collections.emptyList()
+        : Lists.newArrayList(
+            new InnerClassAttribute(id.innerClassAccess, group.getGroupClassType(), null, null));
   }
 
   @Override
@@ -71,9 +72,10 @@
     // Kotlin-style lambdas supported by the merged may only contain optional signature and
     // kotlin metadata annotations. We remove the latter, but keep the signature if present.
     String signature = id.signature;
-    return signature == null ? DexAnnotationSet.empty()
-        : new DexAnnotationSet(new DexAnnotation[]{
-            DexAnnotation.createSignatureAnnotation(signature, factory)});
+    return signature == null
+        ? DexAnnotationSet.empty()
+        : new DexAnnotationSet(
+            new DexAnnotation[]{DexAnnotation.createSignatureAnnotation(signature, factory)});
   }
 
   @Override
@@ -130,7 +132,7 @@
       }
     }
 
-    return result.toArray(new DexEncodedMethod[result.size()]);
+    return result.toArray(DexEncodedMethod.EMPTY_ARRAY);
   }
 
   // Build a map of virtual methods with unique name/proto pointing to a list of methods
@@ -231,7 +233,7 @@
       }
     });
     assert result.isEmpty() == !group.hasAnySingletons();
-    return result.toArray(new DexEncodedField[result.size()]);
+    return result.toArray(DexEncodedField.EMPTY_ARRAY);
   }
 
   @Override
diff --git a/src/main/java/com/android/tools/r8/naming/MemberNaming.java b/src/main/java/com/android/tools/r8/naming/MemberNaming.java
index e8ea970..a0912d0 100644
--- a/src/main/java/com/android/tools/r8/naming/MemberNaming.java
+++ b/src/main/java/com/android/tools/r8/naming/MemberNaming.java
@@ -14,6 +14,7 @@
 import com.android.tools.r8.naming.MemberNaming.Signature.SignatureKind;
 import com.android.tools.r8.position.Position;
 import com.android.tools.r8.utils.DescriptorUtils;
+import com.android.tools.r8.utils.StringUtils;
 import java.io.IOException;
 import java.io.StringWriter;
 import java.io.Writer;
@@ -214,7 +215,7 @@
     public MethodSignature(String name, String type, Collection<String> parameters) {
       super(name);
       this.type = type;
-      this.parameters = parameters.toArray(new String[parameters.size()]);
+      this.parameters = parameters.toArray(StringUtils.EMPTY_ARRAY);
     }
 
     public static MethodSignature fromDexMethod(DexMethod method) {
diff --git a/src/main/java/com/android/tools/r8/naming/ProguardMapReader.java b/src/main/java/com/android/tools/r8/naming/ProguardMapReader.java
index a21adfa..81b745c 100644
--- a/src/main/java/com/android/tools/r8/naming/ProguardMapReader.java
+++ b/src/main/java/com/android/tools/r8/naming/ProguardMapReader.java
@@ -8,6 +8,7 @@
 import com.android.tools.r8.naming.MemberNaming.Signature;
 import com.android.tools.r8.position.TextPosition;
 import com.android.tools.r8.utils.IdentifierUtils;
+import com.android.tools.r8.utils.StringUtils;
 import java.io.BufferedReader;
 import java.io.IOException;
 import java.util.HashMap;
@@ -397,7 +398,7 @@
           expect(',');
           items.add(parseType(true));
         }
-        arguments = items.toArray(new String[items.size()]);
+        arguments = items.toArray(StringUtils.EMPTY_ARRAY);
       }
       expect(')');
       signature = new MethodSignature(name, type, arguments);
diff --git a/src/main/java/com/android/tools/r8/shaking/AbstractMethodRemover.java b/src/main/java/com/android/tools/r8/shaking/AbstractMethodRemover.java
index f5250d8..500f0d8 100644
--- a/src/main/java/com/android/tools/r8/shaking/AbstractMethodRemover.java
+++ b/src/main/java/com/android/tools/r8/shaking/AbstractMethodRemover.java
@@ -74,7 +74,7 @@
       }
     }
     if (methods != null) {
-      return methods.toArray(new DexEncodedMethod[methods.size()]);
+      return methods.toArray(DexEncodedMethod.EMPTY_ARRAY);
     }
     return null;
   }
diff --git a/src/main/java/com/android/tools/r8/shaking/VerticalClassMerger.java b/src/main/java/com/android/tools/r8/shaking/VerticalClassMerger.java
index b8fd5f6..0420876 100644
--- a/src/main/java/com/android/tools/r8/shaking/VerticalClassMerger.java
+++ b/src/main/java/com/android/tools/r8/shaking/VerticalClassMerger.java
@@ -1033,7 +1033,7 @@
       target.interfaces =
           interfaces.isEmpty()
               ? DexTypeList.empty()
-              : new DexTypeList(interfaces.toArray(new DexType[0]));
+              : new DexTypeList(interfaces.toArray(DexType.EMPTY_ARRAY));
       // Step 2: replace fields and methods.
       target.appendDirectMethods(directMethods.values());
       target.appendVirtualMethods(virtualMethods.values());
diff --git a/src/main/java/com/android/tools/r8/utils/FlagFile.java b/src/main/java/com/android/tools/r8/utils/FlagFile.java
index 5f5003f..319580d 100644
--- a/src/main/java/com/android/tools/r8/utils/FlagFile.java
+++ b/src/main/java/com/android/tools/r8/utils/FlagFile.java
@@ -44,6 +44,6 @@
         flags.add(arg);
       }
     }
-    return flags.toArray(new String[flags.size()]);
+    return flags.toArray(StringUtils.EMPTY_ARRAY);
   }
 }
diff --git a/src/main/java/com/android/tools/r8/utils/LineNumberOptimizer.java b/src/main/java/com/android/tools/r8/utils/LineNumberOptimizer.java
index 277bf8a..ffbe255 100644
--- a/src/main/java/com/android/tools/r8/utils/LineNumberOptimizer.java
+++ b/src/main/java/com/android/tools/r8/utils/LineNumberOptimizer.java
@@ -513,7 +513,7 @@
         new DexDebugInfo(
             positionEventEmitter.getStartLine(),
             debugInfo.parameters,
-            processedEvents.toArray(new DexDebugEvent[processedEvents.size()]));
+            processedEvents.toArray(DexDebugEvent.EMPTY_ARRAY));
 
     // TODO(b/111253214) Remove this as soon as we have external tests testing not only the
     // remapping but whether the non-positional debug events remain intact.
diff --git a/src/main/java/com/android/tools/r8/utils/StringUtils.java b/src/main/java/com/android/tools/r8/utils/StringUtils.java
index c91c288..e5d0227 100644
--- a/src/main/java/com/android/tools/r8/utils/StringUtils.java
+++ b/src/main/java/com/android/tools/r8/utils/StringUtils.java
@@ -13,12 +13,12 @@
 import java.util.function.Function;
 
 public class StringUtils {
+  public static final String[] EMPTY_ARRAY = {};
+  public static final String LINE_SEPARATOR = System.getProperty("line.separator");
 
-  public final static String LINE_SEPARATOR = System.getProperty("line.separator");
-
-  private final static char[] IDENTIFIER_LETTERS
+  private static final char[] IDENTIFIER_LETTERS
       = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_".toCharArray();
-  private final static int NUMBER_OF_LETTERS = IDENTIFIER_LETTERS.length;
+  private static final int NUMBER_OF_LETTERS = IDENTIFIER_LETTERS.length;
 
   public enum BraceType {
     PARENS,
diff --git a/src/test/examplesAndroidO/stringconcat/TestGenerator.java b/src/test/examplesAndroidO/stringconcat/TestGenerator.java
index e72f438..12e5004 100644
--- a/src/test/examplesAndroidO/stringconcat/TestGenerator.java
+++ b/src/test/examplesAndroidO/stringconcat/TestGenerator.java
@@ -89,9 +89,11 @@
                     recentConstants.set(0,
                         ((String) recentConstants.get(0)).substring(RECIPE_PREFIX.length()));
 
-                    mv.visitInvokeDynamicInsn(MAKE_CONCAT_WITH_CONSTANTS.getName(),
-                        removeLastParams(desc, recentConstants.size()), MAKE_CONCAT_WITH_CONSTANTS,
-                        recentConstants.toArray(new Object[recentConstants.size()]));
+                    mv.visitInvokeDynamicInsn(
+                        MAKE_CONCAT_WITH_CONSTANTS.getName(),
+                        removeLastParams(desc, recentConstants.size()),
+                        MAKE_CONCAT_WITH_CONSTANTS,
+                        recentConstants.toArray());
                     recentConstants.clear();
                     return;
                   }
diff --git a/src/test/java/com/android/tools/r8/DXTestBuilder.java b/src/test/java/com/android/tools/r8/DXTestBuilder.java
index 39782ed..e9e7f9c 100644
--- a/src/test/java/com/android/tools/r8/DXTestBuilder.java
+++ b/src/test/java/com/android/tools/r8/DXTestBuilder.java
@@ -9,6 +9,7 @@
 import com.android.tools.r8.errors.Unimplemented;
 import com.android.tools.r8.utils.AndroidApp;
 import com.android.tools.r8.utils.InternalOptions;
+import com.android.tools.r8.utils.StringUtils;
 import java.io.IOException;
 import java.nio.file.Path;
 import java.util.ArrayList;
@@ -50,7 +51,7 @@
       List<String> args = new ArrayList<>();
       args.add("--output=" + outJar.toString());
       args.addAll(injars.stream().map(Path::toString).collect(Collectors.toList()));
-      ProcessResult result = ToolHelper.runDX(args.toArray(new String[0]));
+      ProcessResult result = ToolHelper.runDX(args.toArray(StringUtils.EMPTY_ARRAY));
       if (result.exitCode != 0) {
         throw new CompilationFailedException(result.toString());
       }
diff --git a/src/test/java/com/android/tools/r8/R8CFRunExamplesJava9Test.java b/src/test/java/com/android/tools/r8/R8CFRunExamplesJava9Test.java
index c710ed2..de47d8a 100644
--- a/src/test/java/com/android/tools/r8/R8CFRunExamplesJava9Test.java
+++ b/src/test/java/com/android/tools/r8/R8CFRunExamplesJava9Test.java
@@ -9,6 +9,7 @@
 
 import com.android.tools.r8.ToolHelper.ProcessResult;
 import com.android.tools.r8.origin.Origin;
+import com.android.tools.r8.utils.StringUtils;
 import com.android.tools.r8.utils.codeinspector.CodeInspector;
 import com.google.common.collect.ImmutableList;
 import java.io.IOException;
@@ -112,7 +113,11 @@
       thrown.expect(Throwable.class);
     }
     String[] mainAndArgs =
-        ImmutableList.builder().add(qualifiedMainClass).addAll(args).build().toArray(new String[0]);
+        ImmutableList.builder()
+            .add(qualifiedMainClass)
+            .addAll(args)
+            .build()
+            .toArray(StringUtils.EMPTY_ARRAY);
     ProcessResult outputResult = ToolHelper.runJava(Arrays.asList(outputJars), mainAndArgs);
     ToolHelper.ProcessResult inputResult =
         ToolHelper.runJava(ImmutableList.copyOf(inputJars), mainAndArgs);
diff --git a/src/test/java/com/android/tools/r8/RunExamplesAndroidOTest.java b/src/test/java/com/android/tools/r8/RunExamplesAndroidOTest.java
index d103efc..daab81d 100644
--- a/src/test/java/com/android/tools/r8/RunExamplesAndroidOTest.java
+++ b/src/test/java/com/android/tools/r8/RunExamplesAndroidOTest.java
@@ -16,6 +16,7 @@
 import com.android.tools.r8.utils.AndroidApp;
 import com.android.tools.r8.utils.InternalOptions;
 import com.android.tools.r8.utils.OffOrAuto;
+import com.android.tools.r8.utils.StringUtils;
 import com.android.tools.r8.utils.TestDescriptionWatcher;
 import com.android.tools.r8.utils.codeinspector.CodeInspector;
 import com.android.tools.r8.utils.codeinspector.FoundClassSubject;
@@ -621,7 +622,8 @@
         ArrayList<String> javaArgs = Lists.newArrayList(args);
         javaArgs.add(0, qualifiedMainClass);
         ToolHelper.ProcessResult javaResult =
-            ToolHelper.runJava(ImmutableList.copyOf(jars), javaArgs.toArray(new String[0]));
+            ToolHelper.runJava(
+                ImmutableList.copyOf(jars), javaArgs.toArray(StringUtils.EMPTY_ARRAY));
         assertEquals("JVM run failed", javaResult.exitCode, 0);
         assertTrue(
             "JVM output does not match art output.\n\tjvm: "
diff --git a/src/test/java/com/android/tools/r8/TestBase.java b/src/test/java/com/android/tools/r8/TestBase.java
index 2d08ac1..8fad46b 100644
--- a/src/test/java/com/android/tools/r8/TestBase.java
+++ b/src/test/java/com/android/tools/r8/TestBase.java
@@ -31,6 +31,7 @@
 import com.android.tools.r8.utils.FileUtils;
 import com.android.tools.r8.utils.InternalOptions;
 import com.android.tools.r8.utils.PreloadedClassFileProvider;
+import com.android.tools.r8.utils.StringUtils;
 import com.android.tools.r8.utils.TestDescriptionWatcher;
 import com.android.tools.r8.utils.Timing;
 import com.android.tools.r8.utils.ZipUtils;
@@ -447,7 +448,7 @@
 
   /** Create a temporary JAR file containing the specified test classes. */
   protected Path jarTestClasses(List<Class<?>> classes) throws IOException {
-    return jarTestClasses(classes.toArray(new Class<?>[classes.size()]));
+    return jarTestClasses(classes.toArray(new Class<?>[]{}));
   }
 
   /**
@@ -825,7 +826,8 @@
     mainAndArgs.add(main);
     mainAndArgs.addAll(args);
     return ToolHelper.runJava(
-        Collections.singletonList(writeToJar(classes)), mainAndArgs.toArray(new String[0]));
+        Collections.singletonList(writeToJar(classes)),
+        mainAndArgs.toArray(StringUtils.EMPTY_ARRAY));
   }
 
   protected ProcessResult runOnJavaRaw(AndroidApp app, String mainClass, List<String> args)
@@ -835,14 +837,14 @@
     List<String> mainAndArgs = new ArrayList<>();
     mainAndArgs.add(mainClass);
     mainAndArgs.addAll(args);
-    return ToolHelper.runJava(out, mainAndArgs.toArray(new String[0]));
+    return ToolHelper.runJava(out, mainAndArgs.toArray(StringUtils.EMPTY_ARRAY));
   }
 
   protected ProcessResult runOnJavaRawNoVerify(AndroidApp app, String mainClass, List<String> args)
       throws IOException {
     Path out = File.createTempFile("junit", ".zip", temp.getRoot()).toPath();
     app.writeToZip(out, OutputMode.ClassFile);
-    return ToolHelper.runJavaNoVerify(out, mainClass, args.toArray(new String[0]));
+    return ToolHelper.runJavaNoVerify(out, mainClass, args.toArray(StringUtils.EMPTY_ARRAY));
   }
 
   /** Run application on Art or Java with the specified main class. */
diff --git a/src/test/java/com/android/tools/r8/ToolHelper.java b/src/test/java/com/android/tools/r8/ToolHelper.java
index cd1dcbc..97e0d09 100644
--- a/src/test/java/com/android/tools/r8/ToolHelper.java
+++ b/src/test/java/com/android/tools/r8/ToolHelper.java
@@ -835,8 +835,7 @@
 
   public static Path getPackageDirectoryForTestPackage(Package pkg) {
     List<String> parts = getNamePartsForTestPackage(pkg);
-    return getClassPathForTests().resolve(
-        Paths.get("", parts.toArray(new String[parts.size() - 1])));
+    return getClassPathForTests().resolve(Paths.get("", parts.toArray(StringUtils.EMPTY_ARRAY)));
   }
 
   public static String getJarEntryForTestPackage(Package pkg) {
@@ -873,8 +872,7 @@
 
   public static Path getClassFileForTestClass(Class clazz) {
     List<String> parts = getNamePartsForTestClass(clazz);
-    return getClassPathForTests().resolve(
-        Paths.get("", parts.toArray(new String[parts.size() - 1])));
+    return getClassPathForTests().resolve(Paths.get("", parts.toArray(StringUtils.EMPTY_ARRAY)));
   }
 
   public static Collection<Path> getClassFilesForInnerClasses(Path path) throws IOException {
@@ -901,7 +899,7 @@
 
   public static Path getFileNameForTestClass(Class clazz) {
     List<String> parts = getNamePartsForTestClass(clazz);
-    return Paths.get("", parts.toArray(new String[parts.size() - 1]));
+    return Paths.get("", parts.toArray(StringUtils.EMPTY_ARRAY));
   }
 
   public static String getJarEntryForTestClass(Class clazz) {
@@ -1073,7 +1071,7 @@
     List<String> args = new ArrayList<>();
     Collections.addAll(args, extraArgs);
     Collections.addAll(args, "--output=" + outDir + "/classes.dex", fileName);
-    int result = runDX(args.toArray(new String[args.size()])).exitCode;
+    int result = runDX(args.toArray(StringUtils.EMPTY_ARRAY)).exitCode;
     return result != 0 ? null : builderFromProgramDirectory(Paths.get(outDir)).build();
   }
 
diff --git a/src/test/java/com/android/tools/r8/compatdx/CompatDxTests.java b/src/test/java/com/android/tools/r8/compatdx/CompatDxTests.java
index 7d181bc..4ec0131 100644
--- a/src/test/java/com/android/tools/r8/compatdx/CompatDxTests.java
+++ b/src/test/java/com/android/tools/r8/compatdx/CompatDxTests.java
@@ -125,7 +125,7 @@
     // Only test this with CompatDx, as dx does not like the empty .dex file.
     List<String> d8Args =ImmutableList.of(
         "--output=" + temp.newFolder("out").toString(), jarWithClassesAndDex.toString());
-    CompatDx.main(d8Args.toArray(new String[d8Args.size()]));
+    CompatDx.main(d8Args.toArray(StringUtils.EMPTY_ARRAY));
   }
 
   private void runDexer(String... args) throws IOException {
@@ -164,7 +164,7 @@
     }
     Collections.addAll(d8Args, args);
     System.out.println("running: d8 " + StringUtils.join(d8Args, " "));
-    CompatDx.main(d8Args.toArray(new String[d8Args.size()]));
+    CompatDx.main(d8Args.toArray(StringUtils.EMPTY_ARRAY));
 
     List<String> dxArgs = new ArrayList<>(args.length + 2);
     if (dxOut != null) {
@@ -172,7 +172,7 @@
     }
     Collections.addAll(dxArgs, args);
     System.out.println("running: dx " + StringUtils.join(dxArgs, " "));
-    ProcessResult result = ToolHelper.runDX(dxArgs.toArray(new String[dxArgs.size()]));
+    ProcessResult result = ToolHelper.runDX(dxArgs.toArray(StringUtils.EMPTY_ARRAY));
     assertEquals(result.stderr, 0, result.exitCode);
 
     if (out == null) {
diff --git a/src/test/java/com/android/tools/r8/desugar/BasicTestDependenciesDesugaringTest.java b/src/test/java/com/android/tools/r8/desugar/BasicTestDependenciesDesugaringTest.java
index 8af2f8e..20c7e0e 100644
--- a/src/test/java/com/android/tools/r8/desugar/BasicTestDependenciesDesugaringTest.java
+++ b/src/test/java/com/android/tools/r8/desugar/BasicTestDependenciesDesugaringTest.java
@@ -10,6 +10,7 @@
 import com.android.tools.r8.errors.CompilationError;
 import com.android.tools.r8.utils.AndroidApiLevel;
 import com.android.tools.r8.utils.OffOrAuto;
+import com.android.tools.r8.utils.StringUtils;
 import com.google.common.collect.Sets;
 import java.io.File;
 import java.io.IOException;
@@ -37,14 +38,13 @@
     try {
       allLibs =
           Files.readAllLines(Paths.get(ToolHelper.BUILD_DIR, "generated", "supportlibraries.txt"))
-          .toArray(new String[0]);
+          .toArray(StringUtils.EMPTY_ARRAY);
     } catch (IOException e) {
       throw new AssertionError(e);
     }
   }
 
-  private static Set<String> knownIssues = Sets.newHashSet(new String[]{
-  });
+  private static Set<String> knownIssues = Sets.newHashSet(StringUtils.EMPTY_ARRAY);
 
   @Rule
   public ExpectedException thrown = ExpectedException.none();
diff --git a/src/test/java/com/android/tools/r8/dex/JumboStringProcessing.java b/src/test/java/com/android/tools/r8/dex/JumboStringProcessing.java
index 95e1e76..b46bbbf 100644
--- a/src/test/java/com/android/tools/r8/dex/JumboStringProcessing.java
+++ b/src/test/java/com/android/tools/r8/dex/JumboStringProcessing.java
@@ -97,7 +97,7 @@
     instr.setOffset(offset);
     instructions.add(instr);
     assert instr.getOffset() == lastInstructionOffset;
-    return instructions.toArray(new Instruction[instructions.size()]);
+    return instructions.toArray(Instruction.EMPTY_ARRAY);
   }
 
   private int countJumboStrings(Instruction[] instructions) {
diff --git a/src/test/java/com/android/tools/r8/dexsplitter/DexSplitterTests.java b/src/test/java/com/android/tools/r8/dexsplitter/DexSplitterTests.java
index 784dd8d..f503359 100644
--- a/src/test/java/com/android/tools/r8/dexsplitter/DexSplitterTests.java
+++ b/src/test/java/com/android/tools/r8/dexsplitter/DexSplitterTests.java
@@ -22,6 +22,7 @@
 import com.android.tools.r8.dexsplitter.DexSplitter.Options;
 import com.android.tools.r8.origin.Origin;
 import com.android.tools.r8.utils.FeatureClassMapping.FeatureMappingException;
+import com.android.tools.r8.utils.StringUtils;
 import com.android.tools.r8.utils.codeinspector.ClassSubject;
 import com.android.tools.r8.utils.codeinspector.CodeInspector;
 import com.google.common.collect.ImmutableList;
@@ -302,7 +303,7 @@
         args.add("base_renamed");
       }
 
-      DexSplitter.main(args.toArray(new String[0]));
+      DexSplitter.main(args.toArray(StringUtils.EMPTY_ARRAY));
     }
     String baseOutputName = explicitBase || !renameBase ? "base" : "base_renamed";
     Path base = output.resolve(baseOutputName).resolve("classes.dex");
diff --git a/src/test/java/com/android/tools/r8/maindexlist/MainDexTracingTest.java b/src/test/java/com/android/tools/r8/maindexlist/MainDexTracingTest.java
index 6fbcd9d..dd62cac 100644
--- a/src/test/java/com/android/tools/r8/maindexlist/MainDexTracingTest.java
+++ b/src/test/java/com/android/tools/r8/maindexlist/MainDexTracingTest.java
@@ -396,8 +396,8 @@
       index++;
     }
     // Everything else should be sorted according to name.
-    String[] entriesUnsorted = entryNames.toArray(new String[0]);
-    String[] entriesSorted = entryNames.toArray(new String[0]);
+    String[] entriesUnsorted = entryNames.toArray(StringUtils.EMPTY_ARRAY);
+    String[] entriesSorted = entryNames.toArray(StringUtils.EMPTY_ARRAY);
     Arrays.sort(entriesSorted);
     Assert.assertArrayEquals(entriesUnsorted, entriesSorted);
   }
diff --git a/src/test/java/com/android/tools/r8/smali/DexMoveInstructionsTest.java b/src/test/java/com/android/tools/r8/smali/DexMoveInstructionsTest.java
index c92b73b..677d57a 100644
--- a/src/test/java/com/android/tools/r8/smali/DexMoveInstructionsTest.java
+++ b/src/test/java/com/android/tools/r8/smali/DexMoveInstructionsTest.java
@@ -9,6 +9,7 @@
 
 import com.android.tools.r8.ToolHelper.ProcessResult;
 import com.android.tools.r8.utils.DescriptorUtils;
+import com.android.tools.r8.utils.StringUtils;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
@@ -88,7 +89,7 @@
       main.add("  invoke-virtual { v0, v1 }, Ljava/io/PrintStream;->print(" + typeDesc + ")V");
     }
     main.add("  return-void");
-    builder.addMainMethod(3, main.toArray(new String[0]));
+    builder.addMainMethod(3, main.toArray(StringUtils.EMPTY_ARRAY));
 
     return runOnArtRaw(builder.build(), clazz);
   }
diff --git a/src/test/java/com/android/tools/r8/smali/IfZeroObjectTest.java b/src/test/java/com/android/tools/r8/smali/IfZeroObjectTest.java
index ebcd835..6211aec 100644
--- a/src/test/java/com/android/tools/r8/smali/IfZeroObjectTest.java
+++ b/src/test/java/com/android/tools/r8/smali/IfZeroObjectTest.java
@@ -8,6 +8,7 @@
 import static org.junit.Assert.assertTrue;
 
 import com.android.tools.r8.ToolHelper.ProcessResult;
+import com.android.tools.r8.utils.StringUtils;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
@@ -61,7 +62,7 @@
       main.add("  invoke-virtual { v0, v1 }, Ljava/io/PrintStream;->print(I)V");
     }
     main.add("  return-void");
-    builder.addMainMethod(2, main.toArray(new String[0]));
+    builder.addMainMethod(2, main.toArray(StringUtils.EMPTY_ARRAY));
 
     return runOnArtRaw(builder.build(), clazz);
   }
diff --git a/src/test/java/com/android/tools/r8/smali/OutlineTest.java b/src/test/java/com/android/tools/r8/smali/OutlineTest.java
index bfeac7a..5d524af 100644
--- a/src/test/java/com/android/tools/r8/smali/OutlineTest.java
+++ b/src/test/java/com/android/tools/r8/smali/OutlineTest.java
@@ -36,6 +36,7 @@
 import com.android.tools.r8.utils.AndroidApp;
 import com.android.tools.r8.utils.InternalOptions;
 import com.android.tools.r8.utils.InternalOptions.OutlineOptions;
+import com.android.tools.r8.utils.StringUtils;
 import com.android.tools.r8.utils.codeinspector.ClassSubject;
 import com.android.tools.r8.utils.codeinspector.CodeInspector;
 import com.android.tools.r8.utils.codeinspector.MethodSubject;
@@ -1586,7 +1587,7 @@
         DEFAULT_METHOD_NAME + "1",
         parameters,
         0,
-        codeToOutline.toArray(new String[0])
+        codeToOutline.toArray(StringUtils.EMPTY_ARRAY)
     );
 
     MethodSignature signature2 = builder.addPrivateInstanceMethod(
@@ -1594,7 +1595,7 @@
         DEFAULT_METHOD_NAME + "2",
         parameters,
         0,
-        codeToOutline.toArray(new String[0])
+        codeToOutline.toArray(StringUtils.EMPTY_ARRAY)
     );
 
     builder.addMainMethod(
@@ -1661,7 +1662,7 @@
         DEFAULT_METHOD_NAME + "1",
         parameters,
         0,
-        codeToOutline.toArray(new String[0])
+        codeToOutline.toArray(StringUtils.EMPTY_ARRAY)
     );
 
     MethodSignature signature2 = builder.addPrivateInstanceMethod(
@@ -1669,7 +1670,7 @@
         DEFAULT_METHOD_NAME + "2",
         parameters,
         0,
-        codeToOutline.toArray(new String[0])
+        codeToOutline.toArray(StringUtils.EMPTY_ARRAY)
     );
 
     builder.addMainMethod(
@@ -1733,7 +1734,7 @@
         DEFAULT_METHOD_NAME + "1",
         parameters,
         0,
-        codeToOutline.toArray(new String[0])
+        codeToOutline.toArray(StringUtils.EMPTY_ARRAY)
     );
 
     MethodSignature signature2 = builder.addPrivateInstanceMethod(
@@ -1741,7 +1742,7 @@
         DEFAULT_METHOD_NAME + "2",
         parameters,
         0,
-        codeToOutline.toArray(new String[0])
+        codeToOutline.toArray(StringUtils.EMPTY_ARRAY)
     );
 
     builder.addMainMethod(
@@ -1805,7 +1806,7 @@
         DEFAULT_METHOD_NAME + "1",
         parameters,
         0,
-        codeToOutline.toArray(new String[0])
+        codeToOutline.toArray(StringUtils.EMPTY_ARRAY)
     );
 
     MethodSignature signature2 = builder.addPrivateInstanceMethod(
@@ -1813,7 +1814,7 @@
         DEFAULT_METHOD_NAME + "2",
         parameters,
         0,
-        codeToOutline.toArray(new String[0])
+        codeToOutline.toArray(StringUtils.EMPTY_ARRAY)
     );
 
     builder.addMainMethod(
diff --git a/src/test/java/com/android/tools/r8/utils/codeinspector/FoundClassSubject.java b/src/test/java/com/android/tools/r8/utils/codeinspector/FoundClassSubject.java
index 0fb0b30..6b3cf1e 100644
--- a/src/test/java/com/android/tools/r8/utils/codeinspector/FoundClassSubject.java
+++ b/src/test/java/com/android/tools/r8/utils/codeinspector/FoundClassSubject.java
@@ -19,6 +19,7 @@
 import com.android.tools.r8.naming.MemberNaming.Signature;
 import com.android.tools.r8.naming.signature.GenericSignatureParser;
 import com.android.tools.r8.utils.DescriptorUtils;
+import com.android.tools.r8.utils.StringUtils;
 import java.util.Arrays;
 import java.util.List;
 import java.util.function.Consumer;
@@ -70,9 +71,8 @@
         codeInspector.dexItemFactory.createProto(
             codeInspector.toDexType(codeInspector.getObfuscatedTypeName(returnType)), parameterTypes);
     if (naming != null) {
-      String[] parameterStrings = new String[parameterTypes.length];
       Signature signature =
-          new MethodSignature(name, returnType, parameters.toArray(parameterStrings));
+          new MethodSignature(name, returnType, parameters.toArray(StringUtils.EMPTY_ARRAY));
       MemberNaming methodNaming = naming.lookupByOriginalSignature(signature);
       if (methodNaming != null) {
         name = methodNaming.getRenamedName();