Как определить класс объекта?
Если класс B
и класс C
продлить класс A
и у меня есть объект типа B
или же C
Как я могу определить, какой тип это экземпляр?
13 ответов
Используйте Object.getClass (). Возвращает тип времени выполнения объекта.
Было представлено несколько правильных ответов, но есть еще несколько методов: Class.isAssignableFrom()
и просто пытается разыграть объект (который может бросить ClassCastException
).
Возможные пути обобщены
Давайте подведем итоги возможных способов проверить, является ли объект obj
это экземпляр типа C
:
// Method #1
if (obj instanceof C)
;
// Method #2
if (C.class.isInstance(obj))
;
// Method #3
if (C.class.isAssignableFrom(obj.getClass()))
;
// Method #4
try {
C c = (C) obj;
// No exception: obj is of type C or IT MIGHT BE NULL!
} catch (ClassCastException e) {
}
// Method #5
try {
C c = C.class.cast(obj);
// No exception: obj is of type C or IT MIGHT BE NULL!
} catch (ClassCastException e) {
}
Отличия в null
обращение
Есть разница в null
обработка хотя:
- В первых двух методах выражения оцениваются как
false
еслиobj
являетсяnull
(null
это не экземпляр ничего). - 3-й метод бросил бы
NullPointerException
очевидно. - 4-й и 5-й методы наоборот принимают
null
так какnull
может быть приведен к любому типу!
Помнить:
null
не является экземпляром любого типа, но он может быть приведен к любому типу.
Заметки
Class.getName()
не должен использоваться для выполнения теста "is-instance-of", если объект не относится к типуC
но его подкласс может иметь совершенно другое имя и пакет (поэтому имена классов, очевидно, не будут совпадать), но он по-прежнему имеет типC
,- По той же причине наследования
Class.isAssignableFrom()
не симметрично:obj.getClass().isAssignableFrom(C.class)
вернетсяfalse
если типobj
это подклассC
,
Ты можешь использовать:
Object instance = new SomeClass();
instance.getClass().getName(); //will return the name (as String) (== "SomeClass")
instance.getClass(); //will return the SomeClass' Class object
НТН. Но я думаю, что в большинстве случаев не рекомендуется использовать это для управления потоком данных или чего-то подобного...
Любое использование любого из предложенных методов считается запахом кода, основанным на плохом ОО-дизайне.
Если ваш дизайн хороший, вам не нужно использовать getClass()
или же instanceof
,
Подойдет любой из предложенных методов, но только то, что нужно иметь в виду, с точки зрения дизайна.
Мы можем использовать отражение в этом случае
objectName.getClass().getName();
Пример:-
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String name = request.getClass().getName();
}
В этом случае вы получите имя класса, которому передается объект HttpServletRequest
Переменная интерфейса.
Также есть .isInstance
метод на " Class
"класс. если вы получаете класс объекта через myBanana.getClass()
вы можете увидеть, если ваш объект myApple
является экземпляром того же класса, что и myBanana
с помощью
myBanana.getClass().isInstance(myApple)
Проверка с isinstance()
было бы недостаточно, если вы хотите знать во время выполнения. использование:
if(someObject.getClass().equals(C.class){
// do something
}
your_instance.getClass().getSimpleName()
даст имя типа, например: String, Integer, Double, Boolean...
Вы можете использовать getSimpleName ().
Допустим, у нас есть объект: Dog d = new Dog (),
Чтобы получить имя класса, мы можем использовать оператор ниже: Dog. Например:
d.getClass (). getSimpleName();// возвращаем String 'Dog'.
PS: d.getClass () даст вам полное имя вашего объекта.
Я использовал дженерики Java 8, чтобы узнать, что является экземпляром объекта во время выполнения, вместо того, чтобы использовать случай переключения
public <T> void print(T data) {
System.out.println(data.getClass().getName()+" => The data is " + data);
}
передать любой тип данных, и метод распечатает тип данных, которые вы передали при его вызове. например
String str = "Hello World";
int number = 10;
double decimal = 10.0;
float f = 10F;
long l = 10L;
List list = new ArrayList();
print(str);
print(number);
print(decimal);
print(f);
print(l);
print(list);
Ниже приводится вывод
java.lang.String => The data is Hello World
java.lang.Integer => The data is 10
java.lang.Double => The data is 10.0
java.lang.Float => The data is 10.0
java.lang.Long => The data is 10
java.util.ArrayList => The data is []
использовать, чтобы найти погоду, объект является особенным
class
или нет.
booleanValue = (object instanceof class)
JDK 14 расширяет оператор instanceof: вы можете указать переменную привязки; если результат оператора instanceof истинен, то тестируемый объект присваивается переменной привязки.
пожалуйста, посетите официальную документацию по Java для получения дополнительной информации.
Пример программы для иллюстрации использования
instanceof
operator
:
import java.util.*;
class Foo{
@Override
public String toString(){
return "Bar";
}
}
class Bar{
public Object reference;
@Override
public String toString(){
return "Foo";
}
}
public class InstanceofUsage{
public static void main(final String ... $){
final List<Object> list = new ArrayList<>();
var out = System.out;
list.add(new String("Foo Loves Bar"));
list.add(33.3);
list.add(404_404);
list.add(new Foo());
list.add(new Bar());
for(final var o : list){
if(o instanceof Bar b && b.reference == null){
out.println("Bar : Null");
}
if(o instanceof String s){
out.println("String : "+s);
}
if(o instanceof Foo f){
out.println("Foo : "+f);
}
}
}
}
выход:
$ javac InstanceofUsage.java && java InstanceofUsage
String : Foo Loves Bar
Foo : Bar
Bar : Null
Я использую функцию обдува в своем классе GeneralUtils, проверю, может быть полезно
public String getFieldType(Object o) {
if (o == null) {
return "Unable to identify the class name";
}
return o.getClass().getName();
}