JDK-6563734 : Path2D.Float and Path2D.Double should have final getPathIterator methods
  • Type: Bug
  • Component: client-libs
  • Sub-Component: 2d
  • Affected Version: 6
  • Priority: P3
  • Status: Closed
  • Resolution: Fixed
  • OS: generic
  • CPU: generic
  • Submitted: 2007-05-30
  • Updated: 2017-05-16
  • Resolved: 2011-05-23
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 7
7 b142Fixed
Description
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.

Comments
EVALUATION Fixed by making the 3 methods final: Path2D.getPathIterator(AffineTransform, double) Path2D.Float.getPathIterator(AffineTransform) Path2D.Double.getPathIterator(AffineTransform)
02-05-2011

SUGGESTED FIX Add "final" to the methods: - Path2D.Float.getPathIterator(AffineTransform) - Path2D.Double.getPathIterator(AffineTransform) - Path2D.getPathIterator(AffineTransform, flatness)
30-05-2007