Добрый, предобрый день.
В сети распространены различные варианты вопросов на собеседование по
Java SE6. Но ответов на эти вопросы нет. Подумав, я решил, что это очень интересная тема для поста и дальнейшего обсуждения. И поэтому начинается цикл статей, посвященный ответам на вопросы по
Java Core. За основу я взял
50 вопросов для интервьюирования.
Итак первые 5 вопросов с моими вариантами ответов:
1. Что такое класс Object? Какие в нем есть методы?
Object это базовый класс для всех остальных объектов в Java
. Каждый класс наследуется от Object. Соответственно все классы наследуют методы класса Object
.
Методы класса Object:
- public final native Class getClass()
- public native int hashCode()
- public boolean equals(Object obj)
- protected native Object clone() throws CloneNotSupportedException
- public String toString()
- public final native void notify()
- public final native void notifyAll()
- public final native void wait(long timeout) throws InterruptedException
- public final void wait(long timeout, int nanos) throws InterruptedException
- public final void wait() throws InterruptedException
- protected void finalize() throws Throwable
Замечание: Для полноты обзора можно сказать, что существует ещё один метод private static native void registerNatives() .
2. Что такое метод equals(). Чем он отличается от операции ==.
Метод
equals() обозначает отношение эквивалентности объектов. Эквивалентным называется отношение, которое является симметричным, транзитивным и рефлексивным.
- Рефлексивность: для любого ненулевого x, x.equals(x) вернет true;
- Транзитивность: для любого ненулевого x, y и z, если x.equals(y) и y.eqals(z) вернет true, тогда и x.equals(z) вернет true;
- Симметричность: для любого ненулевого x и y, x.equals(y) должно вернуть true, тогда и только тогда, когда y.equals(x) вернет true.
Также для любого ненулевого
x
,
x.equals(null)
должно вернуть false.
Отличия equals() от операции == в классе Object нет. Это видно, если взглянуть исходный код метода equals класса Object:
Однако, нужно не забывать, что, если объект ни на что не ссылается(null), то вызов метода equals этого объекта приведет к NullPointerException. Также нужно помнить, что при сравнении объектов оба они могут быть null и операция obj1 == obj2 в данном случае будет true, а вызов equals приведет к исключению NullPointerException.Как мы видим, при помощи операции == сравниваются ссылки на объекты. Но мы можем переопределять метод equals, тем самым задавая логику сравнения двух объектов. Например, рассмотрим сравнение двух одинаковых чисел, созданных при помощи класса Integer:
Если взглянуть внутрь метода equals класса Integer, то мы увидим:
Понятно, что тут уже нет сравнения ссылок, а сравниваются int значения.
3. Если вы хотите переопределить equals(), какие условия должны удовлетворяться для переопределенного метода?
Эти условия приведены в пункте 2.
4. Если equals() переопределен, есть ли какие-либо другие методы, которые следует переопределить?
Да, есть.Нужно переопределить метод hashCode(). Равные объекты должны возвращать одинаковые хэш коды.
Например у класса Integer метод hashCode() переопределен следующим образом:
public int hashCode
() {return value;
}Syhi-подсветка кодаvalue это private значение, которое хранит объект класса Integer. Собственно это и есть число.
5. Для чего нужен метод hashCode()?
Для начала вспомним, что такое
хэш и
хэширование. Теперь вспоминаем такие известные классы, как HashMap, HashSet, Hashtable, в основе которых лежит вычисление хэш-функции. Именно за счет хэша мы можем вставлять и получать данные за O(1), то есть за время пропорциональное вычислению хэш-функции.
Например, рассмотрим вставку элементов в HashMap:
public V put
(K key, V value
) {...
int hash = hash
(key.
hashCode());
int i = indexFor
(hash, table.
length);
...
addEntry(hash, key, value, i
);
...
}Syhi-подсветка кода Как мы видим, i-е место вставки объекта вычисляется при помощи хэша.
А для вычисления нам нужна хорошая хэш функция, чтобы давала
равномерное распределение и поменьше
коллизий.
То есть ответ на вопрос заключается в том, что существуют коллекции(HashMap, HashSet), которые используют хэш код, как основу при работе с объектами. А если хэш для равных объектов будет разным, то в HashMap будут два равных значения, что является ошибкой. Поэтому необходимо соответствующим образом переопределить метод hashCode().
Пока, что всё. Впереди нас ждет много интересных вопросов!
До встречи.
Продолжение:
Ответы на вопросы для собеседования по Java SE (Часть 2)