2015-03-26 2 views
4

Javadoc сказал:Должен ли я явно удалять объект Graphics?

Для повышения эффективности, программисты должны позвонить распоряжаться, когда закончили использование графического объекта, только если он был создан непосредственно из компонента или другой объект Graphics.

Итак, в следующем коде, следует ли мне позвонить 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 возвращен и используется в других местах.

+0

Поскольку «результат» и связанный с ним графический объект («графика») выходят за пределы области после вызова метода, я бы сказал «да». –

+0

Java возвращает объекты по ссылке. Итак, если он располагает графическим объектом, может ли он использовать его снова для возвращаемого объекта? Я понятия не имею, возможно, кто-то может ответить на это. – Loki

+0

@Loki Если он распоряжается им, он больше не сможет его использовать. – Kayaman

ответ

3

Объект Graphics может быть расположен и должен быть удален.

getGraphics звонок BufferedImage внутренне делегаты createGraphics, поэтому нет никакой разницы. createGraphics вызов в конечном итоге делегирует соответствующую реализацию GraphicsEnvironment, где (для SunGraphicsEnvironment) создается new экземпляр SunGraphics2D.

Наконец, dispose метод SunGraphics2D говорит следующее:

/** 
    * 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 действительно должны назвать (даже если это не является строго необходимым в реализации по умолчанию)

0

Потому что в связи с тем, что метод JavaDoc getGpahics() отправляется в createGraphics(), вы должны удалить объект Graphics в конце вашего метода.

1
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, вы увидите круг. Поэтому вы можете использовать его впоследствии.