title: How to handle the default value of an ArrayList
body: <p>I'm creating an application containing a class I'm writing called Person. One of the fields of Person is 'aliases' which is an <code>ArrayList&lt;String&gt;</code>. Ultimately the aliases will be displayed to the user according to the following logic: If Person has aliases then they should be displayed as <code>[Finch, Wren, Admin, etc...]</code>, otherwise <code>UNKNOWN</code> should be displayed. So far I've tried implementing this in one of three ways:</p>
  
  <ol>
  <li><p>Person contains the method <code>getAliases()</code> which simply returns a copy of the ArrayList as is. The caller checks for an empty array to implement the desired behavior. </p></li>
  <li><p>Person contains the method <code>aliasesToString()</code> which can be called to produce the desired string.</p></li>
  <li><p>Instead of using <code>ArrayList&lt;String&gt;</code>, aliases is an implementation of <code>DefaultableArrayList&lt;T&gt;</code>. This class extends ArrayList and holds a default value with type T. The <code>toString()</code> method is overriden to produce the desired string. The application calls <code>some_person.getAliases().toString()</code> to produce the desired behavior.</p></li>
  </ol>
  
  <p>Below is my implementation of option 3:</p>
  
  <pre><code>public class DefaultableArrayList&lt;T&gt; extends ArrayList&lt;T&gt; {
  
      private static final long serialVersionUID = -6735356930885363889L; // Auto-generated
      private final T defaultElement;
  
  
      public DefaultableArrayList(T defaultElement) {
          super();
          this.defaultElement = defaultElement;
      }
  
  
      public DefaultableArrayList(Collection&lt;? extends T&gt; c, T defaultElement) {
          super(c);
          this.defaultElement = defaultElement;
      }
  
  
      public DefaultableArrayList(int initialCapacity, T defaultElement) {
          super(initialCapacity);
          this.defaultElement = defaultElement;
      }
  
  
      public T getDefaultElement() {
          return defaultElement;
      }
  
  
      @Override
      public String toString() {
          if (!isEmpty()) {
              return super.toString();
  
          } else {
              return defaultElement.toString();
          }
      }
  }
  </code></pre>
  
  <p>What concerns me about options 2 and 3 is that I might be adding needless complexity whilst violating OOP guidelines. Should Person really be concerned with what happens if there's no aliases and does it make sense for aliases to define how it's ultimately implemented in the application? I think that I should be letting the caller handle the empty case. Which option should I choose that best meets standard OOP design guidelines? Or is there a fourth option that I haven't considered?</p>