Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Generic array creation of inner class

The line where I create the array gives me a Generic array creation warning. What is a good way to deal with this?

public class Foo<T> {

    void someMethod() {
        Point[] points = new Point[3];
    }

    class Point {
        float x, y;
    }
}
like image 980
clankill3r Avatar asked Jan 15 '15 17:01

clankill3r


2 Answers

First, let's figure out the reason why Java thinks that new Point[3] creates a generic array, while Point appears to be a non-generic class. This happens because Point is a non-static class, meaning that it has a hidden reference to Foo<T> embedded by the compiler. The class looks like this to Java:

class Foo$Point<T> {
    Foo<T> _hidden_Foo;
    float x, y;
}

The Foo$, <T> and _hidden_Foo are not there in the text of your program, but the compiler thinks that they are, because Point is an inner class of a generic class Foo<T>.

There are two ways of fixing this problem:

  • You could make static your class Point, assuming that this is what you intended to do. See ajb's answer. However, any instance methods of Point would no longer be able to access Foo<T>'s members
  • If static is not an option, replace the array with a List<Point> or another collection suitable to your needs. The restriction applies only to generic arrays, but generic collections are fine.

Here is how you can use a collection:

public class Foo<T> {
    void someMethod() {
        List<Point> points = new ArrayList<Point>();
        ... // add three points to the list
    }
    class Point {
        float x, y;
    }
}
like image 157
Sergey Kalinichenko Avatar answered Oct 14 '22 17:10

Sergey Kalinichenko


It appears to me that your Point class is just there to hold an x and a y, and there's no reason for it to have a hidden reference to an instance of a Foo<T>. If this is correct, then Point should be a nested class, instead of an inner class. Add the static keyword:

public class Foo<T> {

    void someMethod() {
        Point[] points = new Point[3];
    }

    static class Point {
        float x, y;
    }
}
like image 23
ajb Avatar answered Oct 14 '22 16:10

ajb