1. Обзор
В этой статье мы рассмотрим различные способы поиска класса объекта в Java.
2. Использование метода getClass()
Первый метод, который мы проверим, — это метод getClass()
.
Во-первых, давайте посмотрим на наш код. Мы напишем класс пользователя :
public class User {
// implementation details
}
Теперь давайте создадим класс Lender
, который расширяет User
:
public class Lender extends User {
// implementation details
}
Точно так же мы создадим класс Borrower , который также расширяет
User
:
public class Borrower extends User {
// implementation details
}
Метод getClass()
просто возвращает класс времени выполнения объекта, который мы оцениваем , поэтому мы не рассматриваем наследование.
Как мы видим, getClass()
показывает, что класс нашего объекта кредитора
имеет тип Lender
, но не тип User
:
@Test
public void givenLender_whenGetClass_thenEqualsLenderType() {
User lender = new Lender();
assertEquals(Lender.class, lender.getClass());
assertNotEquals(User.class, lender.getClass());
}
3. Использование метода isInstance()
При использовании метода isInstance()
мы проверяем, относится ли объект к определенному типу , и по типу мы говорим либо о классе, либо об интерфейсе.
Этот метод вернет true
, если наш объект, отправленный в качестве аргумента метода, пройдет тест IS-A для класса или типа интерфейса .
Мы можем использовать метод isInstance()
для проверки класса объекта во время выполнения. Кроме того, isInstance() также
обрабатывает автоупаковку .
Если мы проверим следующий код, мы обнаружим, что код не компилируется:
@Ignore
@Test
public void givenBorrower_whenDoubleOrNotString_thenRequestLoan() {
Borrower borrower = new Borrower();
double amount = 100.0;
if(amount instanceof Double) { // Compilation error, no autoboxing
borrower.requestLoan(amount);
}
if(!(amount instanceof String)) { // Compilation error, incompatible operands
borrower.requestLoan(amount);
}
}
Проверим автобоксинг в действии с помощью метода isInstance()
:
@Test
public void givenBorrower_whenLoanAmountIsDouble_thenRequestLoan() {
Borrower borrower = new Borrower();
double amount = 100.0;
if(Double.class.isInstance(amount)) { // No compilation error
borrower.requestLoan(amount);
}
assertEquals(100, borrower.getTotalLoanAmount());
}
Теперь давайте попробуем оценить наш объект во время выполнения:
@Test
public void givenBorrower_whenLoanAmountIsNotString_thenRequestLoan() {
Borrower borrower = new Borrower();
Double amount = 100.0;
if(!String.class.isInstance(amount)) { // No compilation error
borrower.requestLoan(amount);
}
assertEquals(100, borrower.getTotalLoanAmount());
}
Мы также можем использовать isInstance()
для проверки возможности приведения объекта к другому классу перед его приведением :
@Test
public void givenUser_whenIsInstanceOfLender_thenDowncast() {
User user = new Lender();
Lender lender = null;
if(Lender.class.isInstance(user)) {
lender = (Lender) user;
}
assertNotNull(lender);
}
Когда мы используем метод isInstance()
, мы защищаем нашу программу от попыток незаконных преобразований вниз, хотя использование оператора instanceof
в этом случае будет более плавным. Давайте проверим это дальше. ``
4. Использование оператора instanceof
Аналогично методу isInstance() оператор
instanceof
возвращает значение true
, если оцениваемый объект принадлежит к данному типу — другими словами, если наш объект, указанный в левой части оператора, проходит тест IS-A для класса или тип интерфейса с правой стороны .
Мы можем оценить, является ли объект Lender
типом Lender
и типом User
:
@Test
public void givenLender_whenInstanceOf_thenReturnTrue() {
User lender = new Lender();
assertTrue(lender instanceof Lender);
assertTrue(lender instanceof User);
}
Чтобы получить более подробное представление о том, как работает оператор instanceof
, мы можем найти дополнительную информацию в нашей статье Java instanceOf Operator .
5. Вывод
В этой статье мы рассмотрели три разных способа поиска класса объекта в Java: метод getClass()
, метод isInstance()
и оператор instanceof .
Как обычно, полные примеры кода доступны на GitHub .