Java 如何确定对象的类?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/541749/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 16:00:11  来源:igfitidea点击:

How to determine an object's class?

javainheritance

提问by carrier

If class Band class Cextend class Aand I have an object of type Bor C, how can I determine of which type it is an instance?

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

采纳答案by IAdapter

if (obj instanceof C) {
//your code
}

回答by Bill the Lizard

Use Object.getClass(). It returns the runtime type of the object.

使用Object.getClass()。它返回对象的运行时类型。

回答by Johannes Weiss

You can use:

您可以使用:

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

HTH. But I think most of the time it is no good practice to use that for control flow or something similar...

哈。但我认为大多数时候将它用于控制流或类似的东西并不是什么好习惯......

回答by Yuval Adam

Any use of any of the methods suggested is considered a code smell which is based in a bad OO design.

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

If your design is good, you should not find yourself needing to use getClass()or instanceof.

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

Any of the suggested methods will do, but just something to keep in mind, design-wise.

任何建议的方法都可以,但在设计方面需要牢记一些事情。

回答by Andreas Petersson

There is also an .isInstancemethod on the "Class" class. if you get an object's class via myBanana.getClass()you can see if your object myAppleis an instance of the same class as myBananavia

.isInstanceClass”类上还有一个方法。如果你通过获取一个对象的类,myBanana.getClass()你可以查看你的对象myApple是否是与myBananavia相同类的实例

myBanana.getClass().isInstance(myApple)

回答by user1884500

We can use reflection in this case

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

objectName.getClass().getName();

Example:-

例子:-

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

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

In this case you will get name of the class which object pass to HttpServletRequestinterface refference variable.

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

回答by icza

Multiple right answers were presented, but there are still more methods: Class.isAssignableFrom()and simply attempting to cast the object (which might throw a ClassCastException).

提供了多个正确答案,但还有更多方法:Class.isAssignableFrom()并且只是尝试强制转换对象(可能会抛出ClassCastException)。

Possible ways summarized

可能的方法总结

Let's summarize the possible ways to test if an object objis an instance of type C:

让我们总结一下测试对象obj是否是 type 实例的可能方法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) {
}

Differences in nullhandling

null处理方式的差异

There is a difference in nullhandling though:

null但处理方式有所不同:

  • In the first 2 methods expressions evaluate to falseif objis null(nullis not instance of anything).
  • The 3rd method would throw a NullPointerExceptionobviously.
  • The 4th and 5th methods on the contrary accept nullbecause nullcan be cast to any type!
  • 在前 2 个方法中,表达式的计算结果为falseif objis null(null不是任何东西的实例)。
  • 第三种方法NullPointerException显然会抛出一个。
  • 相反,第 4 和第 5 种方法接受,null因为null可以转换为任何类型!

To remember: nullis notan instance of any type but it can be castto any type.

要记住:null不是任何类型的实例,但它可以转换为任何类型。

Notes

笔记

  • Class.getName()should not be used to perform an "is-instance-of"test becase if the object is not of type Cbut a subclass of it, it may have a completely different name and package (therefore class names will obviously not match) but it is still of type C.
  • For the same inheritance reason Class.isAssignableFrom()is not symmetric:
    obj.getClass().isAssignableFrom(C.class)would return falseif the type of objis a subclass of C.
  • Class.getName()不应该用于执行“is-instance-of”测试,因为如果对象不是类型C而是它的子类,它可能具有完全不同的名称和包(因此类名显然不匹配)但它是仍然是 类型C
  • 出于同样传承的原因Class.isAssignableFrom()是不是对称的
    obj.getClass().isAssignableFrom(C.class)将返回false如果类型obj是一个子类C

回答by Alon Gouldman

checking with isinstance()would not be enough if you want to know in run time. use:

isinstance()如果您想在运行时知道,检查是不够的。用:

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

回答by Ahmed Salem

I use the blow function in my GeneralUtils class, check it may be useful

我在 GeneralUtils 类中使用了吹气功能,检查它可能有用

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

回答by Saurabh Verma

I Used Java 8 generics to get what is the object instance at runtime rather than having to use switch case

我使用 Java 8 泛型来获取运行时的对象实例,而不必使用 switch case

 public <T> void print(T data) {
    System.out.println(data.getClass().getName()+" => The data is " + data);
}

pass any type of data and the method will print the type of data you passed while calling it. eg

传递任何类型的数据,该方法将打印您在调用它时传递的数据类型。例如

    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);

Following is the output

以下是输出

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 []