比较Java中的类类型

Car*_*ven 45 java types compare

我想比较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");
}
Run Code Online (Sandbox Code Playgroud)

如果传递给函数的obj是否从MyObject_1扩展,我想比较一下.但这不起作用.似乎getClass()方法和.class提供了不同类型的信息.

如何比较两个类类型,而不必创建另一个虚拟对象只是为了比较类类型?

Tho*_*hor 49

试试这个:

MyObject obj = new MyObject();
if(obj instanceof MyObject){System.out.println("true");} //true
Run Code Online (Sandbox Code Playgroud)

由于继承,这对接口也是有效的:

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
Run Code Online (Sandbox Code Playgroud)

有关instanceof的更多信息,请访问:http://mindprod.com/jgloss/instanceof.html

  • 抱歉,这是错误的,这总是返回 false。没有足够仔细地阅读您的评论。看我的回答。 (2认同)

And*_*s_D 31

如果您不想或不能使用instanceof,请与equals以下内容进行比较:

 if(obj.getClass().equals(MyObject.class)) System.out.println("true");
Run Code Online (Sandbox Code Playgroud)

顺便说一句 - 这很奇怪,因为Class你的语句中的两个实例应该是相同的,至少在你的示例代码中是这样.他们可能是,如果不同的:

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

  • 我想知道为什么这个答案有这么多的赞成票(我猜原因之一是这个答案发布后问题被改变了)?`java.lang.Class` 不会覆盖 `Object.equals`,这意味着对于两个非空的 `cls1` 和 `cls2`: `cls1.equals(cls2)` 为 true 当且仅当 `cls1 == cls2` 是正确的。这意味着所提出的方法与主题启动者描述的方法相同。 (3认同)

Sea*_*oyd 10

它打印true在我的机器上.它应该,否则Java中没有任何东西可以按预期工作.(这在JLS中有解释:4.3.4当引用类型相同时)

你有多个类加载器吗?


啊,并回应这个评论:

我意识到我的问题中有一个错字.我应该是这样的:

MyImplementedObject obj = new MyImplementedObject ();
if(obj.getClass() == MyObjectInterface.class) System.out.println("true");
Run Code Online (Sandbox Code Playgroud)

MyImplementedObject实现MyObjectInterface所以换句话说,我将它与其实现的对象进行比较.

好的,如果你想检查一下你可以做什么:

if(MyObjectInterface.class.isAssignableFrom(obj.getClass()))
Run Code Online (Sandbox Code Playgroud)

或者更简洁

if(obj instanceof MyobjectInterface)
Run Code Online (Sandbox Code Playgroud)


djj*_*eck 5

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

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

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

请记住,这种比较只会做它所做的:比较类名;我认为您无法从一个类的一个版本转换到另一个版本,并且在考虑反射之前,您可能希望确保类加载器混乱有一个很好的理由。