-
Bagaimana cara membuat objek yang tidak dapat diubah di Java? Cantumkan semua manfaatnya
Kelas yang tidak dapat diubah adalah kelas yang statusnya tidak dapat diubah setelah dibuat. Di sini, keadaan suatu objek pada dasarnya dianggap sebagai nilai yang disimpan dalam sebuah instance kelas, baik itu tipe primitif atau tipe referensi.
Untuk membuat kelas tidak dapat diubah, kondisi berikut harus dipenuhi:
- Jangan menyediakan penyetel atau metode yang mengubah bidang atau objek yang merujuk ke bidang tersebut. Setter menyiratkan perubahan keadaan suatu objek, yang merupakan hal yang ingin kita hindari di sini.
- Buat semua bidang
final
danprivate
. Bidang yang ditandaiprivate
tidak akan dapat diakses dari luar kelas, dan menandainyafinal
memastikan bahwa Anda tidak akan mengubahnya, bahkan secara tidak sengaja. - Jangan izinkan subkelas menimpa metode. Cara termudah untuk melakukan ini adalah dengan mendeklarasikan kelas sebagai
final
. Kelas yang diselesaikan di Java tidak dapat ditimpa. - Ingatlah selalu bahwa instance variabel Anda bisa berubah atau tidak berubah. Tentukan objek tersebut dan kembalikan objek baru dengan konten yang disalin untuk semua objek yang dapat diubah (tipe referensi). Variabel yang tidak dapat diubah (tipe primitif) dapat dikembalikan dengan aman tanpa usaha ekstra apa pun.
Selain itu, Anda perlu mengingat manfaat selanjutnya dari kelas yang tidak dapat diubah. Anda mungkin membutuhkannya saat wawancara. Kelas yang tidak dapat diubah:
- mudah dirancang, diuji, dan digunakan
- secara otomatis aman untuk thread dan tidak memiliki masalah sinkronisasi
- tidak memerlukan konstruktor salinan
- memungkinkan Anda dengan malas menginisialisasi kode hash dan menyimpan nilai kembalian dalam cache
- tidak memerlukan penyalinan aman saat digunakan sebagai bidang
- buat
Map
kunci danSet
elemen yang baik (objek-objek ini tidak boleh berubah status saat berada dalam koleksi) - jadikan kelas Anda permanen dengan membuatnya sekali, dan tidak perlu dicentang lagi
- selalu memiliki “atomisitas kegagalan” (istilah yang diciptakan oleh Joshua Bloch): jika objek yang tidak dapat diubah memunculkan pengecualian, objek tersebut tidak akan pernah berada dalam keadaan yang tidak diinginkan atau tidak ditentukan.
Lihatlah contoh yang tertulis di postingan ini .
-
Di Java, lewati nilai atau referensi?
Spesifikasi Java menyatakan bahwa segala sesuatu di Java diteruskan berdasarkan nilai. Tidak ada yang namanya "lewati referensi" di Jawa. Kondisi ini terkait dengan pemanggilan metode dan meneruskan variabel sebagai parameter metode. Oke, tipe primitif selalu diteruskan berdasarkan nilai tanpa kebingungan. Namun, konsep tersebut harus jelas dalam konteks parameter metode tipe kompleks.
Di Java, ketika kita meneruskan referensi tipe kompleks sebagai parameter metode apa pun, alamat memori selalu disalin ke variabel referensi baru langkah demi langkah. Lihatlah gambar:
Dalam contoh di atas, bit alamat contoh pertama disalin oleh variabel referensi lain, menyebabkan kedua referensi menunjuk ke lokasi memori yang sama tempat objek disimpan. Ingatlah bahwa dengan menetapkan null pada tautan kedua, Anda tidak akan menetapkan nol pada tautan pertama. Namun perubahan status objek dengan satu variabel referensi akan tercermin di link lain.
Lihat detailnya di sini .
-
Apa gunanya blok itu
finally
? Apakah blok ini menjamin eksekusi kodenya? Kapanfinally
sebuah blok tidak dipanggil?Sebuah blok
finally
selalu dipanggil jika blok tersebuttry
ada. Hal ini memastikan bahwa blok tersebutfinally
dipanggil bahkan jika terjadi pengecualian yang tidak terduga. Namunfinally
ini lebih berguna daripada sekadar menangani pengecualian - blok ini memungkinkan Anda membersihkan kode yang secara tidak sengaja melewatireturn
,continue
ataubreak
. Menempatkan kode pembersihan dalam sebuah blokfinally
selalu merupakan praktik yang baik, meskipun tidak ada pengecualian yang diharapkan.Jika mesin virtual keluar saat sebuah blok sedang dieksekusi
try
ataucatch
, maka blok tersebutfinally
tidak akan dieksekusi. Demikian pula, jika thread sedang mengeksekusi suatu bloktry
ataucatch
diinterupsi atau dimatikan, blok tersebutfinally
tidak akan dieksekusi, meskipun aplikasi terus berjalan. -
Почему существует два класса
Date
, один вjava.util package
а другой вjava.sql
?java.util.Date
представляет date и время, аjava.sql.Date
представляет только date. Дополнением кjava.sql.Date
является классjava.sql.Time
, который представляет только время.Класс
java.sql.Date
является субклассом (расширением) классаjava.util.Date
. Итак, что изменилось вjava.sql.Date
:toString()
формирует другое представление строки: yyyy-mm-dd- статический метод
valueOf(String)
создает date из строки с вышеуказанным представлением - исключены геттеры и сеттеры для часов, minutes и секунд
Класс
java.sql.Date
используется в JDBC и предназначен, чтобы не иметь составляющую времени, то есть часы, minutesы, секунды и миллисекунды должны быть нулю… но это не является обязательным для класса. -
Разъясните интерфейсы-маркеры.
Шаблон интерфейса-маркера – это шаблон проектирования в компьютерных науках, используемый языками программирования, которые предоставляют информацию об an objectх во время выполнения. Это предоставляет способ ассоциации метаданных класса, где язык не имеет явной поддержки таких метаданных. В Java для этого используются интерфейсы без указания методов.
Хорошим примером применения интерфейса-маркера в Java является интерфейс
Serializable
. Класс реализует этот интерфейс для указания, что его неtransient
данные могут быть записаны в поток byteов or на файловую систему.Главной проблемой интерфейса-маркера является то, что интерфейс определяет соглашение для реализующих его классов, и это соглашение наследуется всеми субклассами. Это значит, что вы не сможете «де-реализовать» маркер. В приведенном примере, если вы создадите субкласс, который вы бы не хотели сериализовать (возможно потому, что он находится в преходящем (transient) состоянии), вы должны прибегнуть к явному бросанию
NotSerializableException
. -
Почему метод
main()
объявлен Howpublic static void
?Почему public? Метод
main
имеет модификатор доступаpublic
, поэтому он может быть доступен везде и для любого an object, который захочет использовать этот метод для запуска applications. Тут я не говорю, что JDK/JRE имеют подобный повод, поскольку java.exe or javaw.exe (для windows) используют Java Native Interface (JNI) вызов для запуска метода, поэтому они могут вызвать его в любом случае, независимо от модификатора доступа.Почему static? Давайте предположим, что у нас метод
main
не статический. Теперь, для вызова любого метода вам необходим экземпляр класса. Верно? Java разрешает иметь перегруженные конструкторы, это мы все знаем. Тогда который из них должен быть использован, и откуда возьмутся параметры для перегруженного конструктора?Почему void? Нет применения для возвращаемого значения в виртуальной машине, которая фактически вызывает этот метод. Единственное, что приложение захочет сообщить вызвавшему процессу – это нормальное or ненормальное завершение. Это уже возможно используя
System.exit(int)
. Не нулевое meaning подразумевает ненормальное завершение, иначе все в порядке. -
В чем разница между созданием строки How
new()
и литералом (при помощи двойных кавычек)?Когда мы создаем строку используя
new()
, она создается в хипе и также добавляется в пул строк, в то же время строка, созданная при помощи литерала, создается только в пуле строк.Вам необходимо ознакомиться с понятием пула строк глубже, чтобы ответить на этот or подобные вопросы. Мой совет – How следует выучите класс String и пул строк.
-
Как работает метод
substring()
классаString
?Как и в других языках программирования, строки в Java являются последовательностью символов. Этот класс больше похож на служебный класс для работы с этой последовательностью. Последовательность символов обеспечивается следующей переменной:
/** The value is used for character storage. */ /** Значение используется для хранения символов */ private final char value[]; Для доступа к этому массиву в различных сценариях используются следующие переменные
/** The offset is the first index of the storage that is used. */ /** Смещение – это первый индекс используемого хранorща. */ private final int offset; /** The count is the number of characters in the String. */ /** Счет – это количество символов в строке. */ private final int count;
Каждый раз, когда мы создаем подстроку от существующего экземпляра строки, метод
substring()
только устанавливает новые значения переменныхoffset
иcount
. Внутренний массив символов не изменяется. Это возможный источник утечки памяти, если методsubstring()
использовать неосторожно:Первоначальное meaning
value[]
не изменяется. Поэтому если вы создадите строку длиной 10000 символов и создадите 100 подстрок с 5-10 символами в каждой, все 101 an objectы будут содержать один и тот же символьный массив длиной 10000 символов. Это без сомнения расточительство памяти.Этого можно избежать, изменив code следующим образом:
заменить
original.substring(beginIndex)
наnew String(original.substring(beginIndex))
, гдеoriginal
– исходная строка.Примечание переводчика: я затрудняюсь сказать к Howой версии Java это применимо, но на данный момент в Java 7 этот пункт статьи не актуален. Метод substring()
вызывает конструктор классаnew String(value, beginIndex, subLen)
, который в свою очередь обращается к методуArrays.copyOfRange(value, offset, offset+count)
. Это значит, что у нас будет каждый раз новое meaning переменнойvalue[]
, содержащее наше новое количество символов. -
Объясните работу
HashMap
. Как решена проблема дубликатов?Большинство из вас наверняка согласится, что
HashMap
наиболее любимая тема для дискуссий на интервью в настоящее время. Если кто-нибудь попросит меня рассказать «Как работаетHashMap
?», я просто отвечу: «По принципу хэширования». Так просто, How это есть.Итак, хеширование по сути является способом назначить уникальный code для любой переменной/an object после применения любой формулы/алгоритма к своим свойствам.
Определение карты (
Map
) таково: «Объект, который привязывает ключи к значениям». Очень просто, верно? Итак,HashMap
содержит собственный внутренний классEntry
, который имеет вид:static class Entry implements Map.Entry { final K key; V value; Entry next; final int hash; …//More code goes here }
Когда кто-либо пытается поместить пару ключ-meaning в
HashMap
, происходит следующее:- В первую очередь, an object ключа проверяется на
null
. Если ключnull
, meaning сохраняется в позициюtable[0]
. Потому что хэшcode дляnull
всегда 0. - Затем, следующим шагом вычисляется хэш meaning вызывая у переменной-ключа свой метод
hashCode()
. Этот хэш используется для вычисления индекса в массиве для хранение an objectEntry
. Разработчики JDK прекрасно понимали, что методhashCode()
может быть плохо написан и может возвращать очень большое or очень маленькое meaning. Для решения этой проблемы они ввели другойhash()
метод, и передают хэшcode an object этому методу для приведения этого значения к диапазону размера индекса массива. - Теперь вызывается метод
indexFor(hash, table.length)
для вычисления точной позиции для хранения an objectEntry
. - Теперь главная часть. Как мы знаем, два неодинаковых an object могут иметь одинаковое meaning хэшcodeа, How два разных an object будет храниться в одинаковом расположении в архиве [называется корзиной]?
Ответ –
LinkedList
. Если вы помните, классEntry
имеет свойство “next”. Это свойство всегда указывает на следующий an object в цепи. Такое поведение очень похоже наLinkedList
.Итак, в случае совпадений хэшcodeов, an objectы Entry хранятся в форме
LinkedList
. Когда an objectEntry
необходимо разместить на конкретном индексе,HashMap
проверяет, существует ли на этом месте другой an objectEntry
? Если там нет записи, наш an object сохранится в этом месте.Если на нашем индексе уже находится другой an object, проверяется его поле
next
. Если оно равноnull
, наш an object становится следующим узлом вLinkedList
. Если next не равноnull
, эта proceduresа повторяется, пока не будет найдено полеnext
равноеnull
.What будет, если мы добавим другое meaning ключа, равное добавленному ранее? Логично, что оно должно заменить старое meaning. Как это происходит? После определения индекса позиции для an object
Entry
, пробегая поLinkedList
, расположенному на нашем индексе,HashMap
вызывает методequals()
для значения ключа для каждого an objectEntry
. Все эти an objectыEntry
вLinkedList
имеют одинаковое meaning хэшcodeа, но методequals()
будет проверять на настоящее equalsство. Если ключ.equals(k)
будет true, тогда оба будут восприниматься How одинаковый an object. Это вызовет замену только an object-meaning внутри an objectEntry
.Таким образом
HashMap
обеспечивает уникальность ключей. - В первую очередь, an object ключа проверяется на
-
Различия между интерфейсами и абстрактными классами?
Ini adalah pertanyaan yang sangat umum jika Anda melakukan wawancara untuk programmer tingkat junior. Perbedaan paling signifikan tercantum di bawah ini:
- Di antarmuka Java, variabel bersifat apriori
final
. Kelas abstrak dapat berisi non-final
variabel. - Antarmuka di Java sama sekali tidak bisa diimplementasikan. Kelas abstrak dapat memiliki contoh metode yang mengimplementasikan perilaku dasar.
- Komponen antarmuka harus
public
. Kelas abstrak dapat memiliki pengubah akses untuk memenuhi selera apa pun. - Antarmuka harus diimplementasikan dengan kata kunci
implements
. Kelas abstrak harus diperluas menggunakan kata kunci extends . - Di Java, sebuah kelas dapat mengimplementasikan banyak antarmuka, namun hanya dapat mewarisi dari satu kelas abstrak.
- Antarmuka sepenuhnya abstrak dan tidak dapat memiliki instance. Kelas abstrak juga tidak dapat memiliki instance kelas tersebut, tetapi dapat dipanggil jika ada metode
main()
. - Kelas abstrak sedikit lebih cepat daripada antarmuka karena antarmuka mengharapkan pencarian sebelum memanggil metode apa pun yang diganti di Java. Dalam kebanyakan kasus, ini adalah perbedaan kecil, tetapi jika Anda menulis aplikasi yang mendesak, Anda perlu mempertimbangkan fakta ini.
- Di antarmuka Java, variabel bersifat apriori
-
Kapan Anda mengganti metode
hashCode()
danequals()
?Metode
hashCode()
danequals()
didefinisikan di kelasObject
, yang merupakan kelas induk untuk semua objek Java. Oleh karena itu, semua objek Java mewarisi implementasi metode ini.Metode ini
hashCode()
digunakan untuk mendapatkan nilai integer unik untuk objek tertentu. Nilai ini digunakan untuk menentukan lokasi recycle bin ketika objek perlu disimpan dalam struktur data sepertiHashTable
. Secara default, metode inihashCode()
mengembalikan representasi bilangan bulat dari alamat memori tempat objek disimpan.Metode ini
equals()
, seperti namanya, digunakan untuk kesetaraan objek sederhana. Implementasi dasar dari metode ini adalah memeriksa referensi dari dua objek untuk memeriksa apakah keduanya setara.Perhatikan bahwa biasanya suatu metode perlu dikesampingkan
hashCode()
setiap kali suatu metode ditimpaequals()
. Hal ini diperlukan untuk mendukung konvensi umum metodehashCode
, yang menyatakan bahwa objek yang sama harus memiliki kode hash yang sama.Metode equal() harus menentukan kesetaraan antar relasi (harus berulang, simetris, dan transitif). Selain itu, harus persisten (jika objek tidak berubah, metode harus mengembalikan nilai yang sama). Selain itu,
o.equals(null)
itu harus selalu mengembalikan false .hashCode()
juga harus persisten (jika objek tidak berubah di bawah kondisi metodeequals()
, objek harus terus mengembalikan nilai yang sama.Hubungan kedua metode tersebut adalah: selalu, jika
a.equals(b)
, makaa.hashCode()
harus sama denganb.hashCode()
.
Andrey
Level 26
Inti Java. Pertanyaan wawancara, bagian 1
Bagi mereka yang pertama kali mendengar kata Java Core, inilah dasar dasar bahasa tersebut. Dengan pengetahuan ini, Anda dapat dengan aman pergi magang/magang. Pertanyaan-pertanyaan ini akan membantu Anda menyegarkan kembali pengetahuan Anda sebelum wawancara, atau mempelajari sesuatu yang baru untuk diri Anda sendiri. Untuk mendapatkan keterampilan praktis, belajarlah di JavaRush .
GO TO FULL VERSION