2011-05-27 55 views
34

我想比较Java中的类类型。在Java中比较类类型

我想我能做到这一点:

class MyObject_1 {} 
class MyObject_2 extends MyObject_1 {} 

public boolean function(MyObject_1 obj) { 
    if(obj.getClass() == MyObject_2.class) System.out.println("true"); 
} 

我想在情况比较,如果传递给函数的OBJ从MyObject_1或不延长。 但这不起作用。看起来像getClass()方法和.class提供了不同类型的信息。

如何比较两个类的类型,而不必创建另一个虚拟对象来比较类的类型?

+0

这个问题令人困惑,并且在比较类/接口的情况下,我误导了“==”的工作方式。这个例子应该是独立的。在这个例子中,你传递给你的函数应该是这样的! – croraf 2017-01-02 13:35:23

回答

40

试试这个:

MyObject obj = new MyObject(); 
if(obj instanceof MyObject){System.out.println("true");} //true 

因为继承的,这是有效的接口,太:

class Animal {} 
class Dog extends Animal {}  

Dog obj = new Dog(); 
Animal animal = new Dog(); 
if(obj instanceof Animal){System.out.println("true");} //true 
if(animal instanceof Animal){System.out.println("true");} //true 
if(animal instanceof Dog){System.out.println("true");} //true 

进一步的阅读上的instanceof:http://mindprod.com/jgloss/instanceof.html

+0

但是如果我想检查动物是狗的一个实例会发生什么?它仍然有可能吗? 说: 公共无效支票(动物的obj){ 如果(OBJ的instanceof狗){的System.out.println( “真”);}} 这仍然是可能的吗? – Carven 2011-05-27 08:50:17

+0

@xEnON:这是可能的,但会一直返回false。你不能检查一个接口是否是一个具体类的实例。 – Thor 2011-05-27 08:56:52

+0

因此,如果我有使用此多态性功能的函数,我无法在运行时检查其确切的类类型? – Carven 2011-05-27 09:00:17

9

它在我的机器上打印true。它应该,否则Java中的任何内容都不会按预期工作。 (这在JLS中有解释:4.3.4 When Reference Types Are the Same

你有多个类加载器吗?


啊,而且响应此评论:

我意识到我在我的 问题一个错字。我应该是这样的:

MyImplementedObject obj = new MyImplementedObject(); 
if(obj.getClass() == MyObjectInterface.class) System.out.println("true"); 

MyImplementedObject实现 MyObjectInterface因此,换句话说,我 正与它的实现 对象比较它。

OK,如果你想查询你可以做两种:

if(MyObjectInterface.class.isAssignableFrom(obj.getClass())) 

或更简洁

if(obj instanceof MyobjectInterface) 
+0

我知道我的问题有一个错字。我应该是这样的: MyImplementedObject obj = new MyImplementedObject(); (obj.getClass()== MyObjectInterface .class)System.out.println(“true”);如果(obj.getClass()== MyObjectInterface .class) MyImplementedObject实现MyObjectInterface 换句话说,我将它与它的实现对象进行比较。 – Carven 2011-05-27 08:33:47

+0

我用我的意思是正确的代码更新了我的帖子。对困惑感到抱歉。 – Carven 2011-05-27 08:40:41

+0

@xEnOn和我已更新我的:-) – 2011-05-27 08:42:02

24

如果你不想或者不能使用instanceof,然后用equals比较:

if(obj.getClass().equals(MyObject.class)) System.out.println("true"); 

顺便说一句 - 这很奇怪,因为声明中的两个Class实例应该是相同的,至少在您的示例代码中。他们可以是不同的,如果:

  • 类具有相同的短名称,但在不同的包中定义
  • 类具有相同的全名,但由不同的类加载器加载。
3

如前所述,除非您在两个不同的类加载器上加载了相同的类,否则您的代码将工作。 如果你需要同一时间在内存中同一个类的多个版本,或者你正在做一些奇怪的事情(就像我一样),这可能会发生。

在这种情况下,如果您想将它们视为同一类(根据具体情况而定,这可能是合理的),您可以匹配它们的名称进行比较。

public static boolean areClassesQuiteTheSame(Class<?> c1, Class<?> c2) { 
    // TODO handle nulls maybe? 
    return c1.getCanonicalName().equals(c2.getCanonicalName()); 
} 

请记住,这种比较只会做它的工作:比较类名;我认为你不能从一个版本的类到另一个版本,并且在考虑反思之前,你可能想确保你的类加载器有一个很好的理由。

1

检查Class.java来源的equals())代码

public boolean equals(Object obj) { 
return (this == obj); 
} 
0

嗯......请记住,类可能会或可能不会实现equals( - 这是不规范所要求。例如,HP Fortify将标记myClass.equals(myOtherClass)。