Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java Generics Creating Array from Class

I have a hierarchy where Square, Triangle and Circle all extend from Shape. I have a working method:

public void someMethod() {
   File file = new File("File_with_squares");
   ThirdPartyClass foo = new ThirdPartyClass();
   Square[] squares = foo.someMajicMethod(Square[].class,file);
   for (Square square: squares) 
      square.draw();

}

Now I want to make this method generic so that it can accept any shape. I want to be able to call it someMethod(Triangle.class,new File("File_with_triangles") or someMethod(Circle.class, new File("File_with_circles"). I am trying like this:

public void someMethod(Class<? extends Shape> type, File shapeFile) {
   ThirdPartyClass foo = new ThirdPartyClass();
   #### What goes here??? ####
   for (Shape shape: shapes)
       shape.draw();
}

What should be there at #### What goes here??? #### ???

like image 575
Mohamed Avatar asked Aug 15 '11 18:08

Mohamed


1 Answers

Assuming ThirdPartClass.someMajicMethod has a signature something like this:

public <T> T someMajicMethod(Class<T> class1, File file);

Then you should be able to do something like this:

public void someMethod(Class<? extends Shape> type, File shapeFile) {
    ThirdPartyClass foo = new ThirdPartyClass();

    @SuppressWarnings("unchecked")
    Class<? extends Shape[]> arrayType = 
        (Class<? extends Shape[]>) Array.newInstance(type, 0).getClass();
    assert Shape[].class.isAssignableFrom(arrayType);

    Shape[] shapes = foo.someMajicMethod(arrayType, shapeFile);

    for (Shape shape: shapes)
        shape.draw();
}

So if you call someMethod(Triangle.class, file), then arrayType will be Triangle[].class in the call to someMajicMethod.

Though you may find it simpler to have someMethod take the array type as a parameter instead of the element type so you can avoid that step.

like image 156
avh4 Avatar answered Nov 08 '22 05:11

avh4