Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <h3>On generic <code>static</code> factory methods for parameterized types</h3> <p>It looks like you want to write convenient factory methods to instantiate generic collections.</p> <p>You can write generic methods like these:</p> <pre><code>public static &lt;T&gt; List&lt;T&gt; newArrayList() { return new ArrayList&lt;T&gt;(); } public static &lt;K,V&gt; Map&lt;K,V&gt; newHashMap() { return new HashMap&lt;K,V&gt;(); } </code></pre> <p>Then you can simply write:</p> <pre><code>// absolutely type-safe!!! no compilation warnings at all!!! List&lt;String&gt; names = newArrayList(); List&lt;Integer&gt; nums = newArrayList(); Map&lt;String, List&lt;String&gt;&gt; map = newHashMap(); </code></pre> <p>Note that in some contexts, the above methods do not have to be <code>static</code>, and you may opt to leave out the implementation <code>class</code> names out of the methods and only use the <code>interface</code> names (e.g. <code>newList</code>, <code>newMap</code>).</p> <hr> <h3>An endorsement from <em>Effective Java 2nd Edition</em></h3> <p>This kind of generic type-inferring <code>static</code> factory method is actually endorsed by <em>Effective Java 2nd Edition</em>; it had the unique privilege of being the <em>very first</em> item discussed in the book.</p> <p>Here are the relevant quotes from <em>Item 1: Consider <code>static</code> factory methods instead of constructors</em>:</p> <blockquote> <p>A <em>fourth</em> advantage of <code>static</code> factory methods is that they reduce the verbosity of creating parameterized type instances.</p> <p>When you invoke the constructor of a parameterized class, unfortunately you must specify the type parameters even if they're obvious from context. This typically requires you to provide the type parameters twice in quick succession:</p> <pre><code> Map&lt;String,List&lt;String&gt;&gt; m = new HashMap&lt;String,List&lt;String&gt;&gt;(); </code></pre> <p>This redundant specification quickly becomes painful as the length and complexity of the type parameters increase. With <code>static</code> factories, however, the compiler can figure out the type parameters for you. This is known as <em>type inference</em>. For example, <em>suppose</em> that <code>HashMap</code> provided this <code>static</code> factory:</p> <pre><code> public static &lt;K,V&gt; HashMap&lt;K,V&gt; newInstance() { return new HashMap&lt;K,V&gt;(); } </code></pre> <p>Then you could replace the wordy declaration above with this succinct alternative:</p> <pre><code> Map&lt;String,List&lt;String&gt;&gt; m = HashMap.newInstance(); </code></pre> <p>Unfortunately the standard collection implementations such as <code>HashMap</code> do not have <code>static</code> factory methods as of release 1.6, but you can put these methods in your own utility class. More importantly you can provide such <code>static</code> factories in your own parameterized classes.</p> </blockquote> <p>The item also prescribes the common naming convention for these <code>static</code> factory methods:</p> <blockquote> <ul> <li><code>getInstance</code> - returns an instance that is described by the parameters […]</li> <li><code>newInstance</code> - Like <code>getInstance</code>, except it guarantees that each instance returned is distinct from all others.</li> <li><code>new</code><em><code>Type</code></em> - Like <code>newInstance</code>, but used when the factory method is in a different class. <em><code>Type</code></em> indicates the type of object returned by the factory method.</li> </ul> </blockquote> <hr> <h3>On explicit type parameters</h3> <p>You do not have to explicitly provide the type parameters in most cases, since the Java generics type inference system can usually figure out what you need.</p> <p>Nevertheless, to provide explicit type parameters, the syntax is to put it <em>before</em> the method name (not <em>after</em>). Here's an example of invoking with explicit parameter the generic method <code>&lt;T&gt; List&lt;T&gt; emptyList()</code> from <a href="http://download.oracle.com/javase/6/docs/api/java/util/Collections.html#emptyList%28%29" rel="noreferrer"><code>java.util.Collections</code></a>:</p> <pre><code>Collections.&lt;String&gt;emptyList(); // Collections.emptyList&lt;String&gt;(); // DOES NOT COMPILE </code></pre> <p>Note that a syntax quirk of the explicit type parameterization for generic method invocation is that you <em>must</em> qualify the type (if <code>static</code>) or the object that you're invoking the method on, even if they can be omitted if it was not an explicit parameterization.</p> <hr> <h3>References</h3> <ul> <li><a href="http://www.angelikalanger.com/GenericsFAQ/JavaGenericsFAQ.html" rel="noreferrer">Angelika Langer's Java Generics FAQS</a> <ul> <li><a href="http://www.angelikalanger.com/GenericsFAQ/FAQSections/ParameterizedMethods.html#FAQ001" rel="noreferrer">What is a generic method?</a></li> <li><a href="http://www.angelikalanger.com/GenericsFAQ/FAQSections/TechnicalDetails.html#FAQ400" rel="noreferrer">What is type argument inference?</a></li> <li><a href="http://www.angelikalanger.com/GenericsFAQ/FAQSections/TechnicalDetails.html#FAQ402" rel="noreferrer">What is explicit type argument specification?</a></li> </ul></li> <li><a href="http://docs.oracle.com/javase/specs/jls/se5.0/html/classes.html#8.4.4" rel="noreferrer">JLS 8.4.4 Generic Methods</a></li> </ul> <hr> <h3>Appendix: Collection factory methods from Guava</h3> <p>It should be noted that <a href="http://guava-libraries.googlecode.com/" rel="noreferrer">Guava</a> in fact already provides the <code>static</code> factory methods for the types in <a href="http://download.oracle.com/javase/tutorial/collections/index.html" rel="noreferrer">Java Collections Framework</a>:</p> <p>From the main <a href="http://guava-libraries.googlecode.com/svn/trunk/javadoc/com/google/common/collect/package-summary.html" rel="noreferrer"><code>package com.google.common.collect</code></a>:</p> <ul> <li><a href="http://guava-libraries.googlecode.com/svn/trunk/javadoc/com/google/common/collect/package-summary.html" rel="noreferrer"><code>Lists.newArrayList()</code></a>, <a href="http://guava-libraries.googlecode.com/svn/trunk/javadoc/com/google/common/collect/Lists.html#newLinkedList%28%29" rel="noreferrer"><code>newLinkedList()</code></a>, …</li> <li><a href="http://guava-libraries.googlecode.com/svn/trunk/javadoc/com/google/common/collect/Sets.html#newHashSet%28%29" rel="noreferrer"><code>Sets.newHashSet()</code></a>, <a href="http://guava-libraries.googlecode.com/svn/trunk/javadoc/com/google/common/collect/Sets.html#newTreeSet%28%29" rel="noreferrer"><code>newTreeSet()</code></a>, <a href="http://guava-libraries.googlecode.com/svn/trunk/javadoc/com/google/common/collect/Sets.html#newEnumSet%28java.lang.Iterable,%20java.lang.Class%29" rel="noreferrer"><code>newEnumSet(…)</code></a>, …</li> <li><a href="http://guava-libraries.googlecode.com/svn/trunk/javadoc/com/google/common/collect/Maps.html#newHashMap%28%29" rel="noreferrer"><code>Maps.newHashMap()</code></a>, <a href="http://guava-libraries.googlecode.com/svn/trunk/javadoc/com/google/common/collect/Maps.html#newTreeMap%28%29" rel="noreferrer"><code>newTreeMap()</code></a>, <a href="http://guava-libraries.googlecode.com/svn/trunk/javadoc/com/google/common/collect/Maps.html#newEnumMap%28java.lang.Class%29" rel="noreferrer"><code>newEnumMap(…)</code></a>, …</li> </ul> <p>In fact, in the spirit of <em>Effective Java 2nd Edition</em> recommendation, Guava's own collections do not provide <code>public</code> constructors, but instead provide <code>static create()</code> factory methods:</p> <ul> <li><a href="http://guava-libraries.googlecode.com/svn/trunk/javadoc/com/google/common/collect/HashMultiset.html#create%28%29" rel="noreferrer"><code>HashMultiSet.create()</code></a>, a <a href="http://guava-libraries.googlecode.com/svn/trunk/javadoc/com/google/common/collect/Multiset.html" rel="noreferrer"><code>Multiset</code></a> implementation</li> <li><a href="http://guava-libraries.googlecode.com/svn/trunk/javadoc/com/google/common/collect/TreeMultimap.html#create%28%29" rel="noreferrer"><code>TreeMultimap.create()</code></a>, a <a href="http://guava-libraries.googlecode.com/svn/trunk/javadoc/com/google/common/collect/Multimap.html" rel="noreferrer"><code>Multimap</code></a> implementation</li> </ul> <p>The rest of the library also provides many highly useful functionality.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload