Search code examples
javaequivalence

Compilation error with == operator


I've isolated the error to this line: string.getClass() == jojo.getClass() Shouldn't this line create two Class objects and then check if they (as in the two references) point to the same object? Rather than returning a value of false, the code won't run.

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!");
    }
}

This comment is kind of hidden and I think its worth mentioning since it makes the most sense to a beginner (such as myself)

-According to the JLS "It is a compile-time error if it is impossible to convert the type of either operand to the type of the other by a casting conversion" so two references of types A and B can be compared if, and only if, either A can be cast to B or B can be cast to A. – Patricia Shanahan


Solution

  • I agree OP should quote the compilation error.

    Anyway the compilation error is quite obvious when anyone actually does a compilation.

    The error is:

    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()){
                              ^
    

    Reason seems obvious.

    From Javadoc of Object.getClass():

    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.
    

    That means, an String instance is going to return a reference to Class<? extends String>, while an OreoJar instance is going to return reference to Class<? extends OreoJar>

    The two types are simply not compatible, as the compiler knows that there is no chance that any type that extends String can be a type extends OreoJar. So comparison is going to cause compilation error.


    A bit off topic but I think worth mentioning, you said:

    Shouldn't this line create two Class objects and then check if they point to the same object

    I think it is better to have clearer understanding. It is not going to "create" two Class objects. getClass() is going to return you a reference to Class object. And, it is always a reference that can point to an object, not object that point to object (it sounds weird too)