2013-01-07 65 views
1

我已将此错误隔离为以下行: string.getClass()== jojo.getClass() 不应该创建两个Class对象,然后检查它们(如两个引用)指向同一个对象?代码将不会运行,而不是返回false值。使用==运算符编译错误

public class Tester 
{ 
    public static void main(String[] args) 
    { 
     OreoJar jojo = new OreoJar(0); 
     OreoJar momo = new OreoJar(1); 
     String string = "Hello"; 

     if (momo.getClass() == jojo.getClass()) 
     { 
      System.out.println("Momo and jojo are of the same class"); 
     } 

     if (string.getClass() == jojo.getClass()) 
     { 
      System.out.println("String and jojo are of the same class"); 
     } 
    } 
} 

public class OreoJar 
{ 
    int oreos; 

    public OreoJar(int oreos) 
    { 
     this.oreos = oreos; 
    } 

    public void count() 
    { 
     System.out.println(oreos + " oreos in this jar!"); 
    } 
} 

这个评论是一种隐藏的,我认为它值得一提的,因为它最有意义的初学者(比如我)

- 根据该JLS“这是一个编译时错误如果不可能通过转换转换将任一操作数的类型转换为另一操作数的类型“,所以只有在A可以转换为B或B时,可以比较类型A和B的两个引用可以是投给A. - Patricia Shanahan

+6

如果你得到一个*编译错误*,你需要我们的帮助,然后常识告诉你,你应该在这里发布错误,不是吗? –

+3

也许你应该告诉我们错误是什么? – OldProgrammer

+1

将'public class OreoJar'设为'private class OreoJar'然后再试一次? – Marcus

回答

6

我同意OP应引用编译错误。

无论如何,编译错误是非常明显的,当任何人实际进行编译。

的错误是:

Tester.java:15: incomparable types: java.lang.Class<capture#125 of ? extends java.lang.String> and java.lang.Class<capture#29 of ? extends OreoJar> 
    if (string.getClass() == jojo.getClass()){ 
         ^

原因似乎是显而易见的。

从Object.getClass()的Javadoc中:

The java.lang.Class object that represents the runtime class of the 
object. The result is of type Class<? extends X> where X is the 
erasure of the static type of the expression on which getClass is 
called. 

这意味着,一个字符串实例将要参考返回Class<? extends String>,而一个OreoJar实例将返回参考Class<? extends OreoJar>

这两种类型根本不兼容,因为编译器知道任何扩展String的类型都不可能是扩展OreoJar的类型。所以比较会导致编译错误。


一点题外话,但我认为值得一提的,你说:

不应该在该行创建两个Class对象,然后检查是否指向同一对象

我认为最好有更清楚的了解。它不会“创建”两个类对象。 getClass()将返回一个参考到Class对象。而且,它始终是一个参考可以指向一个对象,不对象指向对象(这听起来不可思议太)

+0

我对Java的泛型不是很熟悉,尤其是在类型删除方面。所以,虽然你的回答对我来说似乎是正确的,但它在我的脑海中产生了这样一个问题:哪些类型*可以被比较? –

+2

@TheodorosChatzigiannakis根据JLS“如果不可能通过转换转换将任一操作数的类型转换为另一种操作数的类型,那么编译时错误”,因此可以比较两种类型A和B的引用,并且只有在A可以被转换为B或者B可以被转换为A. –

+0

嗯,这也解释了为什么你可以使用'.getClass()'而没有问题,当你覆盖'.equals()'并且检查参数的类:任何类都可以转换为“Object”,这意味着您可以比较Class <?将MyClass>扩展为'Class <?扩展对象>'(我想后者可能相当于'类'?) – fge

-1

getClass()返回一个Class的实例。 getClass().getName()返回一个字符串。 String.equals(otherString)方法是比较字符串是否相等的正确方法。

+1

但是,这将导致*逻辑*错误,而不是*编译*错误,除非原始海报混淆了这两者之间的差异。 –

+0

该问题表明意图是检查两个引用是否指向同一个对象。 ==是做到这一点的正确方法。 a.equals(b)询问由a和b引用的两个可能不同的对象是否相等,因为在a类中定义了相等性,这是一个不同的问题。 –

+1

我没有看到OP在此打算比较字符串。除非他误解了'.getClass()'的javadoc。严重误读。 – fge

3

我认为它不会编译的原因是因为类具有通用组件。尝试使用momo.getClass().equals(jojo.getClass()) 你也可以尝试比较类的规范名称类似的效果:momo.getClass().getCanonicalName().equals(jojo.getClass().getCanonicalName())