Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Методы класса Object в Java
Все классы в Java наследуют методы из класса java.lang.Object. Это фундаментальный класс, от которого наследуются все остальные классы по умолчанию. Давайте рассмотрим все методы, которые переходят по наследованию.
1. equals(Object obj) — сравнение объектов
public class Person {
private String name;
private int age;
// По умолчанию Object.equals() сравнивает по ссылке (==)
// Нужно переопределить для сравнения по значению
@Override
public boolean equals(Object obj) {
if (this == obj) return true; // Проверка по ссылке
if (obj == null || getClass() != obj.getClass()) return false;
Person person = (Person) obj;
return age == person.age &&
Objects.equals(name, person.name);
}
}
public class Example {
public static void main(String[] args) {
Person p1 = new Person("John", 30);
Person p2 = new Person("John", 30);
System.out.println(p1 == p2); // false (разные объекты в памяти)
System.out.println(p1.equals(p2)); // true (одинаковые значения)
}
}
Важно: При переопределении equals() ВСЕГДА переопределяй и hashCode()!
2. hashCode() — получить хеш-код объекта
public class Person {
private String name;
private int age;
@Override
public int hashCode() {
return Objects.hash(name, age);
}
@Override
public boolean equals(Object obj) {
// ...
}
}
public class Example {
public static void main(String[] args) {
Person person = new Person("John", 30);
System.out.println(person.hashCode());
// Использование в HashMap
Map<Person, String> map = new HashMap<>();
map.put(person, "Developer");
}
}
Контракт: Если a.equals(b) возвращает true, то a.hashCode() == b.hashCode().
3. toString() — строковое представление объекта
public class Person {
private String name;
private int age;
@Override
public String toString() {
return String.format("Person(name='%s', age=%d)", name, age);
}
}
public class Example {
public static void main(String[] args) {
Person person = new Person("John", 30);
System.out.println(person); // Person(name='John', age=30)
System.out.println(person.toString()); // То же самое
}
}
По умолчанию возвращает что-то вроде Person@1f96302c (класс + хеш).
4. getClass() — получить класс объекта (FINAL метод)
public class Example {
public static void main(String[] args) {
Person person = new Person("John", 30);
Class<?> personClass = person.getClass();
System.out.println(personClass.getName()); // Person
System.out.println(personClass.getSimpleName()); // Person
// Проверка типа
if (person.getClass() == Person.class) {
System.out.println("Это экземпляр Person");
}
// Рефлексия
Method[] methods = personClass.getDeclaredMethods();
for (Method method : methods) {
System.out.println(method.getName());
}
}
}
Этот метод нельзя переопределить (final).
5. clone() — создать копию объекта
public class Person implements Cloneable {
private String name;
private List<String> hobbies;
@Override
public Object clone() throws CloneNotSupportedException {
// Поверхностное копирование
Person cloned = (Person) super.clone();
// Для изменяемых полей нужно глубокое копирование
cloned.hobbies = new ArrayList<>(this.hobbies);
return cloned;
}
}
public class Example {
public static void main(String[] args) throws CloneNotSupportedException {
Person original = new Person("John", Arrays.asList("Reading", "Coding"));
Person cloned = (Person) original.clone();
System.out.println(original == cloned); // false (разные объекты)
System.out.println(original.equals(cloned)); // true (если переопределено)
}
}
Важно: Класс ДОЛЖЕН реализовать интерфейс Cloneable, иначе выбросится CloneNotSupportedException.
6. finalize() — подготовка к удалению (DEPRECATED)
public class Resource implements AutoCloseable {
private FileInputStream fileInputStream;
// DEPRECATED! Не используй в новом коде
@Override
@Deprecated(since = "9", forRemoval = true)
protected void finalize() throws Throwable {
try {
if (fileInputStream != null) {
fileInputStream.close();
}
} finally {
super.finalize();
}
}
// Предпочитай AutoCloseable
@Override
public void close() throws Exception {
if (fileInputStream != null) {
fileInputStream.close();
}
}
}
public class Example {
public static void main(String[] args) {
// Используй try-with-resources вместо finalize()
try (Resource resource = new Resource()) {
// Работа с ресурсом
} // Автоматически вызовется close()
}
}
Рекомендация: Используй AutoCloseable и try-with-resources вместо finalize().
7. wait(), notify(), notifyAll() — синхронизация потоков
public class Message {
private String content;
private boolean isReady = false;
public synchronized void produce(String msg) throws InterruptedException {
while (isReady) {
wait(); // Ждём, пока consumer заберёт сообщение
}
this.content = msg;
this.isReady = true;
notifyAll(); // Пробуждаем ждущие потоки
}
public synchronized String consume() throws InterruptedException {
while (!isReady) {
wait(); // Ждём, пока producer создаст сообщение
}
String msg = content;
isReady = false;
notifyAll(); // Пробуждаем ждущие потоки
return msg;
}
}
public class Example {
public static void main(String[] args) throws InterruptedException {
Message message = new Message();
Thread producer = new Thread(() -> {
try {
message.produce("Hello from producer!");
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
});
Thread consumer = new Thread(() -> {
try {
String msg = message.consume();
System.out.println(msg);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
});
producer.start();
consumer.start();
producer.join();
consumer.join();
}
}
Современный подход — используй java.util.concurrent:
public class ModernExample {
public static void main(String[] args) throws InterruptedException {
BlockingQueue<String> queue = new LinkedBlockingQueue<>();
Thread producer = new Thread(() -> {
try {
queue.put("Message");
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
});
Thread consumer = new Thread(() -> {
try {
String msg = queue.take();
System.out.println(msg);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
});
producer.start();
consumer.start();
}
}
Полный список методов Object
public final class Object {
public native int hashCode(); // Хеш-код
public boolean equals(Object obj); // Сравнение
protected native Object clone() throws CloneNotSupportedException; // Копирование
public String toString(); // Строковое представление
public final Class<?> getClass(); // Получить класс
protected void finalize() throws Throwable; // (DEPRECATED) Финализация
public final void notify(); // Разбудить один поток
public final void notifyAll(); // Разбудить все потоки
public final void wait() throws InterruptedException; // Ждать
public final void wait(long timeout) throws InterruptedException;
public final void wait(long timeout, int nanos) throws InterruptedException;
}
Практические рекомендации
-
Всегда переопределяй
equals()иhashCode()вместе- Используй IDE для автогенерации
- Или используй
@Dataв Lombok
-
Переопределяй
toString()для отладки// IDE может автогенерировать @Override public String toString() { return "Person{" + "name='" + name + '\'' + ", age=" + age + '}'; } -
Избегай
clone()если возможно- Используй конструктор копирования
- Или copy factory method
- Или builder pattern
-
Используй
java.util.concurrentвместоwait()/notify()- BlockingQueue, ReentrantLock, Semaphore и т.д.
-
Никогда не переопределяй
getClass()- Это final метод, нельзя переопределить