Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>Here's how to use generics to get an array of precisely the type you’re looking for while preserving type safety (as opposed to the other answers, which will either give you back an <code>Object</code> array or result in warnings at compile time):</p> <pre><code>import java.lang.reflect.Array; public class GenSet&lt;E&gt; { private E[] a; public GenSet(Class&lt;E[]&gt; clazz, int length) { a = clazz.cast(Array.newInstance(clazz.getComponentType(), length)); } public static void main(String[] args) { GenSet&lt;String&gt; foo = new GenSet&lt;String&gt;(String[].class, 1); String[] bar = foo.a; foo.a[0] = "xyzzy"; String baz = foo.a[0]; } } </code></pre> <p>That compiles without warnings, and as you can see in <code>main</code>, for whatever type you declare an instance of <code>GenSet</code> as, you can assign <code>a</code> to an array of that type, and you can assign an element from <code>a</code> to a variable of that type, meaning that the array and the values in the array are of the correct type.</p> <p>It works by using class literals as runtime type tokens, as discussed in the <a href="http://download.oracle.com/javase/tutorial/extra/generics/literals.html" rel="noreferrer">Java Tutorials</a>. Class literals are treated by the compiler as instances of <code>java.lang.Class</code>. To use one, simply follow the name of a class with <code>.class</code>. So, <code>String.class</code> acts as a <code>Class</code> object representing the class <code>String</code>. This also works for interfaces, enums, any-dimensional arrays (e.g. <code>String[].class</code>), primitives (e.g. <code>int.class</code>), and the keyword <code>void</code> (i.e. <code>void.class</code>). </p> <p><code>Class</code> itself is generic (declared as <code>Class&lt;T&gt;</code>, where <code>T</code> stands for the type that the <code>Class</code> object is representing), meaning that the type of <code>String.class</code> is <code>Class&lt;String&gt;</code>.</p> <p>So, whenever you call the constructor for <code>GenSet</code>, you pass in a class literal for the first argument representing an array of the <code>GenSet</code> instance's declared type (e.g. <code>String[].class</code> for <code>GenSet&lt;String&gt;</code>). Note that you won't be able to get an array of primitives, since primitives can't be used for type variables.</p> <p>Inside the constructor, calling the method <code>cast</code> returns the passed <code>Object</code> argument cast to the class represented by the <code>Class</code> object on which the method was called. Calling the static method <code>newInstance</code> in <code>java.lang.reflect.Array</code> returns as an <code>Object</code> an array of the type represented by the <code>Class</code> object passed as the first argument and of the length specified by the <code>int</code> passed as the second argument. Calling the method <code>getComponentType</code> returns a <code>Class</code> object representing the component type of the array represented by the <code>Class</code> object on which the method was called (e.g. <code>String.class</code> for <code>String[].class</code>, <code>null</code> if the <code>Class</code> object doesn't represent an array).</p> <p>That last sentence isn't entirely accurate. Calling <code>String[].class.getComponentType()</code> returns a <code>Class</code> object representing the class <code>String</code>, but its type is <code>Class&lt;?&gt;</code>, not <code>Class&lt;String&gt;</code>, which is why you can't do something like the following.</p> <pre><code>String foo = String[].class.getComponentType().cast("bar"); // won't compile </code></pre> <p>Same goes for every method in <code>Class</code> that returns a <code>Class</code> object.</p> <p>Regarding Joachim Sauer's comment on <a href="https://stackoverflow.com/questions/529085/java-how-to-generic-array-creation/529094#529094">this answer</a> (I don't have enough reputation to comment on it myself), the example using the cast to <code>T[]</code> will result in a warning because the compiler can't guarantee type safety in that case.</p> <hr> <p>Edit regarding Ingo's comments:</p> <pre><code>public static &lt;T&gt; T[] newArray(Class&lt;T[]&gt; type, int size) { return type.cast(Array.newInstance(type.getComponentType(), size)); } </code></pre>
    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. 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