When the Path2D class and its type-specific subclasses were all created, the new classes were all left non-final for a couple of reasons: - GeneralPath needed to subclass Path2D.Float so Path2D.Float could not be final - there was an existing bug against GeneralPath being final To satisfy these two design issues we decided to make the classes non-final, but to make all of the method implementations final so that developers could create "decorated subclasses" with additional non-geometric functionality, but so that we could retain strict control over the implementation to enable optimizing assumptions to be made. The problem with the plan is that we left 2 methods non-final: - Path2D.Float.getPathIterator(AffineTransform) - Path2D.Double.getPathIterator(AffineTransform) This is sloppy and it creates a practical problem in that there is nothing in the method signature that prevents a rogue class from subclassing these variants and returning a Path Iterator that produces different geometry. There are several reasons why anyone taking advantage of this override hole would be unhappy in the attempt. First, there are several places in the JDK where we examine an object, discover that it is one of the known subclasses of Path2D, and bypass the methods and work on it directly. These include (but not limited to): Graphics2D.fill(Path2D) Graphics2D.draw(Path2D) new Path2D.Float/Double(Path2D) Second, there are other final methods on Path2D which produce answers based on the internal representation of the geometry, rather than based on the geometry that might be expressed by the PathIterator. These methods include: Path2D.contains(xy) Path2D.contains(Point2D) Path2D.contains(xywh) Path2D.contains(Rectangle2D) Path2D.intersects(xywh) Path2D.intersects(Rectangle2D) Path2D.getBounds() Path2D.getBounds2D() Path2D.clone() Path2D.getCurrentPoint() Path2D.createTransformedShape() Lastly, there is no really compelling reason why someone would want to override this method other than "because they can". The lack of any useful purpose in overriding the method, in addition to the problems outlined above that one might encounter if one were to attempt do do this, both recommend that the compatibility hit to add "final" to the method signature would be warranted in this case.
|