Я работаю над классом, который содержит изображение и рисует его по центру 0, 0; для этого он извлекает высоту и ширину изображения и основывает свое смещение дисплея на этих значениях. Но, делая это ImageObserver в случае изображение еще не полностью загружено, я протечки this
в конструкторе:Безопасно ли утечка этого ImageObserver в конструкторе?
public class Sprite extends SimplePaintable implements ImageObserver {
private final Image sprite;
private int xOffset;
private boolean xOffsetSet;
private int yOffset;
private boolean yOffsetSet;
public Sprite(Image sprite) {
this.sprite = sprite;
//warning: leaking this in constructor
int width = sprite.getWidth(this);
xOffset = width/2;
xOffsetSet = width != -1;
int height = sprite.getHeight(this);
yOffset = height/2;
yOffsetSet = height != -1;
}
@Override
public boolean imageUpdate(Image img, int infoflags, int x, int y, int width, int height) {
assert img == sprite;
if ((infoflags & WIDTH) != 0) {
xOffset = width/2;
xOffsetSet = true;
}
if ((infoflags & HEIGHT) != 0) {
yOffset = height/2;
yOffsetSet = true;
}
return !(xOffsetSet && yOffsetSet);
}
...
Сначала я думал, что это было хорошо, так как только смещенный переменными был неинициализированными и их значения по умолчанию были хорошими для (не) отображения незагруженного изображения, но затем я понял, что если бы имя, загруженное сразу как getWidth(this)
, было вызвано, теоретически можно было бы позвонить imageUpdate
до завершения конструктора, в результате чего смещения будут правильно установлены в imageUpdate
, а затем be unset от конструктора. Это проблема, или изображения загружаются синхронно только на EDT? Если это вызывает озабоченность, сделает метод imageUpdate synchronized
, чтобы он не работал до завершения конструктора?
Нет. Нельзя передавать 'this' из конструктора.Проблема (как вы догадались) заключается в том, что ваш экземпляр еще не был инициализирован. –
Если 'Image' уже загружен,' observer' может быть 'null'. – trashgod
@ ElliottFrisch В целом это не безопасно; однако, если 'Image.getWidth' гарантированно не вызывать' imageUpdate' до тех пор, пока конструктор не будет закончен, тогда это безопасно в этом конкретном случае. – Vitruvius