我应该显式处理 Graphics 对象吗?

Should I explicitly dispose the Graphics object?

javadoc 说:

For efficiency, programmers should call dispose when finished using a Graphics object only if it was created directly from a component or another Graphics object.

所以在下面的代码中,我应该在返回之前调用graphics.dispose()吗? 或者,我可以吗?

{  ...  
BufferedImage result = new BufferedImage(toWidth, toHeight, BufferedImage.TYPE_INT_RGB);  

java.awt.Graphics graphics=result.getGraphics();

graphics.drawImage(im.getScaledInstance(toWidth, toHeight, java.awt.Image.SCALE_SMOOTH), 0, 0, null);  

return result;  
}

返回 BufferedImage result 并在别处使用。

因为 JavaDoc getGpahics() 方法转发到 createGraphics() 你应该在你的方法结束时处理 Graphics 对象。

public class Main{

    public static void main(String[] args) {
        BufferedImage img = get();

        Graphics g = img.getGraphics();

        //g.drawOval(5, 5, 5, 5); //this statement will work (you'll see the cirle)

        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        try {
            ImageIO.write( img, "jpg", baos );

            baos.flush();
            byte[] imageInByte = baos.toByteArray();
            baos.close();

            Files.write(Paths.get("test2.png"), imageInByte);
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }


    public static BufferedImage get(){
        BufferedImage res = new BufferedImage(50, 50, BufferedImage.TYPE_INT_ARGB);

        Graphics g = res.getGraphics();

        g.drawRect(0, 0, 20, 20);

        g.dispose();

        g.drawOval(5, 5, 5, 5); //this statement won't work, you'll only see the rect

        return res;
    }


}

如您所见,您可以(并且应该)在您的方法中处理 graphics

后面的方法中不能使用图形对象,所以运行代码的时候,图片中不会出现圆圈。但是如果你在方法中注释掉了g.drawOval(5,5,5,5),但是在main-Method中的同一条语句中注释掉了,就会看到一个圆圈。这样你以后就可以用了。

Graphics 对象可以被释放并且应该被释放。

BufferedImagegetGraphics调用内部委托给了createGraphics,所以没有区别。 createGraphics 调用最终委托给相应的 GraphicsEnvironment 实现,其中(对于 SunGraphicsEnvironment)它创建一个 new 实例SunGraphics2D

最后,SunGraphics2Ddispose 方法表示如下:

  /**
   * This object has no resources to dispose of per se, but the
   * doc comments for the base method in java.awt.Graphics imply
   * that this object will not be useable after it is disposed.
   * So, we sabotage the object to prevent further use to prevent
   * developers from relying on behavior that may not work on
   * other, less forgiving, VMs that really need to dispose of
   * resources.
   */
  public void dispose() {
      surfaceData = NullSurfaceData.theInstance;
      invalidatePipe();
  }

这也给出了 理由 为什么 dispose 确实 应该 被调用(即使它不是绝对必要的默认实现)