如何确定一个对象的类?

如果类B和类C扩展类A,并且我有一个类型为BC的对象,我如何确定它是哪种类型的实例?

780924 次浏览

使用# EYZ1。它返回对象的运行时类型。下面是如何使用你的例子来调用它:

class A {}
class B extends A {}
class C extends A {}


class Main {
public static void main(String args[]) {
C c = new C();
Class clazz = c.getClass();
System.out.println(clazz);
}
}

输出:

class C

您还可以比较两个Class实例,以查看两个对象是否属于同一类型。

class A {}
class B extends A {}
class C extends A {}


class Main {
public static void main(String args[]) {
B b = new B();
Class c1 = b.getClass();
C c = new C();
Class c2 = c.getClass();
System.out.println(c1 == c2);
}
}
if (obj instanceof C) {
//your code
}

你可以使用:

Object instance = new SomeClass();
instance.getClass().getName(); //will return the name (as String) (== "SomeClass")
instance.getClass(); //will return the SomeClass' Class object

HTH。但我认为大多数时候,将其用于控制流或类似的东西并不是一个好的实践……

任何建议的方法的使用都被认为是基于糟糕的OO设计的代码气味。

如果你的设计很好,你不应该发现自己需要使用getClass()instanceof

任何建议的方法都可以,但只是在设计方面要记住一些东西。

在“Class”类上还有一个.isInstance方法。如果你通过myBanana.getClass()获得一个对象的类,你可以看到你的对象myApple是否与myBanana via是同一个类的实例

myBanana.getClass().isInstance(myApple)

在这种情况下我们可以使用反射

objectName.getClass().getName();

例子:-

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {


String name = request.getClass().getName();
}

在这种情况下,您将获得对象传递给HttpServletRequest接口引用变量的类的名称。

给出了多个正确答案,但仍然有更多方法: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处理中有一个区别:

  • 在前两个方法中,如果objnull (null不是任何东西的实例),表达式计算为false
  • 第三个方法显然会抛出NullPointerException
  • 相反,第4和第5个方法接受null,因为null可以转换为任何类型!

要记住:null 不是是任何类型的实例,可以铸造是任何类型的实例。

笔记

  • Class.getName()不应该用于执行“is-instance-of”测试,因为如果对象不是C类型,而是它的子类,它可能有完全不同的名称和包(因此类名显然不匹配),但它仍然是C类型。
  • 由于同样的继承原因Class.isAssignableFrom()不是对称的:
    如果obj的类型是C的子类,则obj.getClass().isAssignableFrom(C.class)将返回false

如果你想在运行时知道,检查isinstance()是不够的。 用途:< / p >

if(someObject.getClass().equals(C.class){
// do something
}

我在我的GeneralUtils类中使用blow函数,检查它可能有用

    public String getFieldType(Object o) {
if (o == null) {
return "Unable to identify the class name";
}
return o.getClass().getName();
}

我使用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 []

您可以使用getSimpleName ()

假设我们有一个对象:狗d =新狗()

我们可以使用下面的语句来获取类名:Dog。例如:

.getSimpleName d.getClass () (); //返回String 'Dog'。

PS: d.g getclass()会给你对象的全名。

使用instanceof operator来确定对象是否是特定的class

booleanValue = (object instanceof class)
JDK 14扩展了instanceof操作符:你可以指定一个绑定 变量;如果instanceof操作符的结果为真,则 被测试的对象被赋值给绑定变量

请访问官方java# EYZ0以获得更多参考。

示例程序说明使用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

your_instance.getClass().getSimpleName()将给出类型名称,例如:字符串,整数,双精度,布尔…