Есть некоторые проблемы, заслуживающие внимания, если вы имеете дело с классами, которые сохраняются с использованием Object-Relationship Mapper (ORM), такого как Hibernate, если вы не думаете, что это было необоснованно уже сложно!
Lazy загруженные объекты являются подклассами
Если ваши объекты сохраняются с использованием ORM, во многих случаях вы будете иметь дело с динамическими прокси, чтобы избежать слишком раннего извлечения объекта из хранилища данных. Эти прокси реализованы как подклассы вашего собственного класса. Это означает, что this.getClass() == o.getClass()
вернет false
. Например:
Person saved = new Person("John Doe");
Long key = dao.save(saved);
dao.flush();
Person retrieved = dao.retrieve(key);
saved.getClass().equals(retrieved.getClass()); // Will return false if Person is loaded lazy
Если вы имеете дело с ORM, использование o instanceof Person
- это единственное, что будет вести себя правильно.
Lazy загруженные объекты имеют нулевые поля
ORM обычно используют геттеры для принудительной загрузки ленивых загружаемых объектов. Это означает, что person.name
будет null
, если person
ленив загружен, даже если person.getName()
принудительно загружает и возвращает «John Doe». По моему опыту, это чаще встречается в hashCode()
и equals()
.
Если вы имеете дело с ORM, обязательно используйте геттеры и никогда не ссылайтесь на ссылки в hashCode()
и equals()
.
Сохранение объекта изменит его состояние
Стойкие объекты часто используют поле id
, чтобы удерживать клавишу объекта. Это поле будет автоматически обновляться при первом сохранении объекта. Не используйте поле id в hashCode()
. Но вы можете использовать его в equals()
.
Я часто использую шаблон
if (this.getId() == null) {
return this == other;
}
else {
return this.getId().equals(other.getId());
}
Но: вы не можете включить getId()
в hashCode()
. Если вы это сделаете, когда объект сохраняется, изменяется его hashCode
. Если объект находится в HashSet
, вы «никогда» не найдете его снова.
В моем примере Person
я, вероятно, использовал бы getName()
для hashCode
и getId()
plus getName()
(только для паранойи) для equals()
. Это нормально, если есть риск «столкновения» для hashCode()
, но никогда не подходит для equals()
.
hashCode()
должен использовать неизменяемый поднабор свойств из equals()
Я нашел решение:
В вашей деятельности, в которой установлен стиль Theme.Dialog
, сделайте следующее:
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.your_layout);
getWindow().setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
}
Важно, чтобы вы позвонили по номеру Window.setLayout ()
после вы вызываете setContentView ()
, иначе это не сработает.