🔍 Ответ на вопрос про сравнение объектов в Java:
Разберемся, как Java сравнивает объекты и что скрывается за методами equals() и hashCode().
У нас есть два объекта:
Object o1 = new Object();
Object o2 = new Object();
Теперь давайте посмотрим, что произойдет, если мы их сравним:
1️⃣ Сравнение ссылок (оператор ==):
System.out.println((o1 == o2)); // Выводит: false
🔸 Оператор == сравнивает адреса в памяти. Поскольку o1 и o2 — разные объекты, они находятся по разным адресам, что возвращает false.
2️⃣ Сравнение методом equals():
System.out.println(o1.equals(o2)); // Выводит: false
🔸 Метод equals() по умолчанию в классе Object работает как ==, сравнивая ссылки. Без переопределения возвращает false.
3️⃣ Сравнение значений hashCode():
System.out.println(o1.hashCode() == o2.hashCode()); // Выводит: false
🔸 Метод hashCode() вычисляет уникальное значение на основе текущего объекта (реализация может быть различна и может зависеть от платформы). Обычно для двух разных объектов значения будут уникальными.
Почитать подробнее можно тут.
💡 Итак, вывод программы:
false
false
false
➖➖➖➖➖
✍️ В реальной практике нужно переопределять equals() и hashCode(), чтобы они отражали бизнес-логику ваших объектов.
Будьте внимательны и прописывайте правильные сравнения! 🤓
➖➖➖➖➖
🎓 Надеюсь, это было полезно! Оставьте свои вопросы и комментарии ниже. 👇
#java #программирование #equals #hashcode #разработка
Разберемся, как Java сравнивает объекты и что скрывается за методами equals() и hashCode().
У нас есть два объекта:
Object o1 = new Object();
Object o2 = new Object();
Теперь давайте посмотрим, что произойдет, если мы их сравним:
1️⃣ Сравнение ссылок (оператор ==):
System.out.println((o1 == o2)); // Выводит: false
🔸 Оператор == сравнивает адреса в памяти. Поскольку o1 и o2 — разные объекты, они находятся по разным адресам, что возвращает false.
2️⃣ Сравнение методом equals():
System.out.println(o1.equals(o2)); // Выводит: false
🔸 Метод equals() по умолчанию в классе Object работает как ==, сравнивая ссылки. Без переопределения возвращает false.
3️⃣ Сравнение значений hashCode():
System.out.println(o1.hashCode() == o2.hashCode()); // Выводит: false
🔸 Метод hashCode() вычисляет уникальное значение на основе текущего объекта (реализация может быть различна и может зависеть от платформы). Обычно для двух разных объектов значения будут уникальными.
Почитать подробнее можно тут.
💡 Итак, вывод программы:
false
false
false
➖➖➖➖➖
✍️ В реальной практике нужно переопределять equals() и hashCode(), чтобы они отражали бизнес-логику ваших объектов.
Будьте внимательны и прописывайте правильные сравнения! 🤓
➖➖➖➖➖
🎓 Надеюсь, это было полезно! Оставьте свои вопросы и комментарии ниже. 👇
#java #программирование #equals #hashcode #разработка
Telegram
Java Interview Tasks
Что напечатает код? (Супермаловероятными событиями тут пренебрегаем)
👍15🔥5🙏2
🔍 Ответ на вопрос про пропавший эксепшен:
Привет, друзья! Сегодня обсудим скрытую проблему с логированием исключений, которая часто возникает в многопоточной среде.
На первый взгляд все кажется довольно обычным: мы отправляем задачу на выполнение, которая вызывает метод logString с null значением. Это должно вызвать NullPointerException.
❓ Где же исключение? Вы могли заметить, что исключение не будет напечатано в логи, даже если оно происходит. Почему?
🔎 Объяснение:
Исключения в Java, возникающие в потоке, обрабатываются контекстом этого потока.
В случае использования ExecutorService.submit(...), если задача выбрасывает исключение, оно остается незамеченным, потому что submit возвращает Future, который просто тихо удаляет это исключение.
Если вы не вызываете методы get() у Future и не обрабатываете возможное исключение, вы его просто не увидите.
💡 Как это исправить? Чтобы исключение стало видимым, можно сделать следующее:
public static void main(String[] args) {
ExecutorService executorService = Executors.newSingleThreadExecutor();
Future<?> future = executorService.submit(() -> logString(null));
try {
future.get(); // Обрабатываем возможное исключение
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace(); // Выводим исключение в логи
} finally {
executorService.shutdown();
}
}
📌 В этом изменении future.get() либо вернёт результат, либо выбросит ExecutionException, если что-то пошло не так, позволяя вам логировать и обрабатывать ситуацию корректно.
👨💻 Вывод: Будьте внимательны при работе с многопоточностью. Убедитесь, что вы корректно обрабатываете возможные исключения, особенно при использовании ExecutorService.
➖➖➖➖➖
🎓 Надеюсь, это было полезно! Оставьте свои вопросы и комментарии ниже. 👇
Подписывайтесь, чтобы не пропустить важные советы и приемы! 🔥
#java #многопоточность #исключения #программирование #лучшиепрактики
Привет, друзья! Сегодня обсудим скрытую проблему с логированием исключений, которая часто возникает в многопоточной среде.
На первый взгляд все кажется довольно обычным: мы отправляем задачу на выполнение, которая вызывает метод logString с null значением. Это должно вызвать NullPointerException.
❓ Где же исключение? Вы могли заметить, что исключение не будет напечатано в логи, даже если оно происходит. Почему?
🔎 Объяснение:
Исключения в Java, возникающие в потоке, обрабатываются контекстом этого потока.
В случае использования ExecutorService.submit(...), если задача выбрасывает исключение, оно остается незамеченным, потому что submit возвращает Future, который просто тихо удаляет это исключение.
Если вы не вызываете методы get() у Future и не обрабатываете возможное исключение, вы его просто не увидите.
💡 Как это исправить? Чтобы исключение стало видимым, можно сделать следующее:
public static void main(String[] args) {
ExecutorService executorService = Executors.newSingleThreadExecutor();
Future<?> future = executorService.submit(() -> logString(null));
try {
future.get(); // Обрабатываем возможное исключение
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace(); // Выводим исключение в логи
} finally {
executorService.shutdown();
}
}
📌 В этом изменении future.get() либо вернёт результат, либо выбросит ExecutionException, если что-то пошло не так, позволяя вам логировать и обрабатывать ситуацию корректно.
👨💻 Вывод: Будьте внимательны при работе с многопоточностью. Убедитесь, что вы корректно обрабатываете возможные исключения, особенно при использовании ExecutorService.
➖➖➖➖➖
🎓 Надеюсь, это было полезно! Оставьте свои вопросы и комментарии ниже. 👇
Подписывайтесь, чтобы не пропустить важные советы и приемы! 🔥
#java #многопоточность #исключения #программирование #лучшиепрактики
🔥15❤4👍4🙏1
🔍 Ответ на вопрос про volatile и массивы в Java:
📌 Многие разработчики могут ошибочно полагать, что при объявлении массива volatile все его элементы также будут обладать свойствами volatile. Однако это не так!
Пример выше как раз демонстрирует эту особенность.
🔎 Объяснение:
volatile int[] arr делает переменную arr ссылкой volatile. Это означает, что любые изменения ссылки на массив будут видны другим потокам.
Однако элементы массива не наследуют volatile-свойство. Таким образом, arr[0] и arr[1] не имеют гарантий видимости друг для друга.
➖➖➖➖➖
Ставьте лайк , если нашли это полезным и задавайте свои вопросы и комментарии ниже для получения дополнительных знаний! 🚀
#java #многопоточность #volatile #программирование
📌 Многие разработчики могут ошибочно полагать, что при объявлении массива volatile все его элементы также будут обладать свойствами volatile. Однако это не так!
Пример выше как раз демонстрирует эту особенность.
🔎 Объяснение:
volatile int[] arr делает переменную arr ссылкой volatile. Это означает, что любые изменения ссылки на массив будут видны другим потокам.
Однако элементы массива не наследуют volatile-свойство. Таким образом, arr[0] и arr[1] не имеют гарантий видимости друг для друга.
➖➖➖➖➖
Ставьте лайк , если нашли это полезным и задавайте свои вопросы и комментарии ниже для получения дополнительных знаний! 🚀
#java #многопоточность #volatile #программирование
Telegram
Java Interview Tasks
Какие значения могут напечататься? (thread1 и thread2 запускаются одновременно в разных потоках)
🔥10👍4❤3👎1👏1🙏1🐳1
🔍 Ответ на задачу про то, как Java выбирает перегрузку метода?
🚀🚀🚀Когда вы вызываете метод в Java, который имеет несколько перегруженных вариантов, компилятор должен решить, какой из них использовать. Давайте разберёмся, как он это делает на примере вызова метода printFor(42).
Вот правила, которыми руководствуется компилятор:
🚀 Точный тип: Ищет метод с точным совпадением типа аргумента. У нас его нет для int, так как метода printFor(int) нет.
🚀 Примитивное расширение (widening): Далее проверяется, можно ли расширить примитивный тип. 42 (int) может быть преобразован в long, и метод printFor(long) подходит.
🚀 Автоупаковка (boxing): Если расширение невозможно, оценивается автоупаковка. int может стать Integer, что делает метод printFor(Integer) возможным, но менее предпочтительным, чем printFor(long).
🚀 Varargs (массив произвольной длины): Как запасной вариант, компилятор рассматривает использование varargs. Метод printFor(int...) подходит, но также менее предпочтителен.
🚀 Автоупаковка в Object: Ещё менее специфичный вариант — преобразование в Integer и затем в Object для printFor(Object).
🔗🔗 🔗 В итоге, компилятор выбирает printFor(long), потому что расширение примитивного типа более предпочтительно, чем автоупаковка и varargs. Это позволяет Java эффективно и предсказуемо обрабатывать вызовы методов!
🎓 Надеюсь, это было полезно! Оставьте свои вопросы, лайки и комментарии ниже. 👇
#Java #Программирование #CodingTips #JavaTips #java_interview_tasks
🚀🚀🚀Когда вы вызываете метод в Java, который имеет несколько перегруженных вариантов, компилятор должен решить, какой из них использовать. Давайте разберёмся, как он это делает на примере вызова метода printFor(42).
Вот правила, которыми руководствуется компилятор:
🚀 Точный тип: Ищет метод с точным совпадением типа аргумента. У нас его нет для int, так как метода printFor(int) нет.
🚀 Примитивное расширение (widening): Далее проверяется, можно ли расширить примитивный тип. 42 (int) может быть преобразован в long, и метод printFor(long) подходит.
🚀 Автоупаковка (boxing): Если расширение невозможно, оценивается автоупаковка. int может стать Integer, что делает метод printFor(Integer) возможным, но менее предпочтительным, чем printFor(long).
🚀 Varargs (массив произвольной длины): Как запасной вариант, компилятор рассматривает использование varargs. Метод printFor(int...) подходит, но также менее предпочтителен.
🚀 Автоупаковка в Object: Ещё менее специфичный вариант — преобразование в Integer и затем в Object для printFor(Object).
🔗🔗 🔗 В итоге, компилятор выбирает printFor(long), потому что расширение примитивного типа более предпочтительно, чем автоупаковка и varargs. Это позволяет Java эффективно и предсказуемо обрабатывать вызовы методов!
🎓 Надеюсь, это было полезно! Оставьте свои вопросы, лайки и комментарии ниже. 👇
#Java #Программирование #CodingTips #JavaTips #java_interview_tasks
1👍23🔥5❤3
🔍 Ответ на задачу про то, как Java выбирает перегрузку метода с null?
В Java, когда вы вызываете перегруженный метод с аргументом null, компилятор должен решить, какую версию метода использовать. Давайте разберём конкретный пример с вызовом printFor(null).
👉 Как компилятор принимает решение?
👉👉Когда мы передаём null как аргумент, Java ищет наиболее специфичный метод, который может быть вызван. В этом конкретном случае, null может быть преобразован как в String, так и в Object, поскольку String является подтипом (наследником) Object.
👉👉Специфичность типа: Согласно правилам Java, если возможны несколько перегруженных методов, компилятор выбирает тот, чьё требование более специфично. Поскольку String является более специфичной версией Object, метод printFor(String o) будет выбран.
🔗 В итоге, когда вызывается printFor(null), на консоль будет выведено "String".
Такие правила выбора метода помогают Java обрабатывать вызовы предсказуемо и логично, даже с неопределёнными значениями, как null!
🎓 Надеюсь, это было полезно! Оставьте свои вопросы, лайки и комментарии ниже. 👇
#Java #Программирование #CodingTips #JavaTips #java_interview_tasks
В Java, когда вы вызываете перегруженный метод с аргументом null, компилятор должен решить, какую версию метода использовать. Давайте разберём конкретный пример с вызовом printFor(null).
👉 Как компилятор принимает решение?
👉👉Когда мы передаём null как аргумент, Java ищет наиболее специфичный метод, который может быть вызван. В этом конкретном случае, null может быть преобразован как в String, так и в Object, поскольку String является подтипом (наследником) Object.
👉👉Специфичность типа: Согласно правилам Java, если возможны несколько перегруженных методов, компилятор выбирает тот, чьё требование более специфично. Поскольку String является более специфичной версией Object, метод printFor(String o) будет выбран.
🔗 В итоге, когда вызывается printFor(null), на консоль будет выведено "String".
Такие правила выбора метода помогают Java обрабатывать вызовы предсказуемо и логично, даже с неопределёнными значениями, как null!
🎓 Надеюсь, это было полезно! Оставьте свои вопросы, лайки и комментарии ниже. 👇
#Java #Программирование #CodingTips #JavaTips #java_interview_tasks
🔥18👍6⚡1❤1👏1🐳1