I have a class Shape
and a class Circle
that extends Shape
as follows:
public class Shape {
private double area;
public Shape(double thatArea) {
this.area = thatArea;
}
public double getArea() {
return this.area;
}
}
public class Circle extends Shape {
private double radius;
public Circle(double radius) {
super(3.14*radius*radius);
}
public double getRadius() {
return this.radius;
}
}
Supposed that I create an array of shapes as follows
Shape[] shapes = new Shape[3];
shapes[0] = new Shape(100.0);
shapes[1] = new Circle(5.0);
shapes[2] = new Shape(35.0);
And have a filter by area method like this
public Shape[] filterByMaxArea(double maxArea) {
ArrayList<Shape> shapeResult = new ArrayList<>();
for (Shape s : shapes) {
if (s.getArea < maxArea) shapeResult.add(s);
}
return (Shape[]) shapeResult.toArray();
}
If I call the filterByMaxArea()
method like this
filterByMaxArea(1000); // in order to include the
circle too
Then the compiler throws a ClassCastException
Exception in thread "main" java.lang.ClassCastException: java.base/[Ljava.lang.Object; cannot be cast to [Lmypackage.Shape;
at mypackage.Main.filterByMaxArea(Main.java:74)
Where line 74 in the code is this
return (Shape[]) shapeResult.toArray();
Can someone explain me why does the cast fail even though the Circle is a subtype of Shape and previously I had an array of Shape and Circle instances ?
P.S I have tried also declaring the ArrayList with bounded wildcards without any luck.
ArrayList<? extends Shape> shapeResult = new ArrayList<>();
toArray()
returns Object[]
, there is a overloaded version of toArray(T[] a)
which will give the desired result, use it like
return shapeResult.toArray(new Shape[shapeResult.size()]);