1

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

user1953794
  • 27
  • 1
  • 7
  • 6
    If you're getting a *compilation error* and you need our help, then common sense tells you that you should post that error here, no? – Hovercraft Full Of Eels Jan 07 '13 at 01:39
  • 3
    Maybe you should show us what the error is? – OldProgrammer Jan 07 '13 at 01:40
  • 1
    Make `public class OreoJar` to `private class OreoJar` then try again? – Marcus Jan 07 '13 at 01:41
  • Or are you confused about the difference between a compilation error and a logic error? – Hovercraft Full Of Eels Jan 07 '13 at 01:44
  • 1
    i don't think it's an operator problem,test it with string.getClass().toString – Bourkadi Jan 07 '13 at 01:44
  • 4
    The error is `Incompatible operand types Class and Class` – Patricia Shanahan Jan 07 '13 at 01:51
  • From what I gather, == checks if the two refer to the same object. string.getClass() and jojo.getClass() both create different objects, and so I would think the line should return false. Yet instead of returning any boolean value, the code just doesn't run. Note that the first boolean statement runs when I compare the two Oreojar objects jojo and momo. – user1953794 Jan 07 '13 at 02:00
  • @user1953794 Please read my answer for detailed explanation. Just like you cannot do `if ("dummystring" == jojo)`, compiler is in fact checking if both side of `==` is comparable. In your question, they are not. – Adrian Shum Jan 07 '13 at 03:28
  • BTW no class objects are created here. They already exist. – user207421 Jan 07 '13 at 09:11

3 Answers3

6

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)

Adrian Shum
  • 38,812
  • 10
  • 83
  • 131
  • I'm not very familiar with Java's generics, especially when it comes to type erasure. So, while your answer seems correct to me, it creates this question in my mind: what types *can* be compared? – Theodoros Chatzigiannakis Jan 07 '13 at 02:01
  • 2
    @TheodorosChatzigiannakis 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 Jan 07 '13 at 02:04
  • Hmmm, that also explains why you can use `.getClass()` without a problem when you override `.equals()` and check against the argument's class: any class can be cast to an `Object`, which means you can compare `Class extends MyClass>` to `Class extends Object>` (and I guess the latter is probably equivalent to `Class>`?) – fge Jan 07 '13 at 02:08
3

I think the reason it won't compile is due to the fact that Class has generic component. Try using momo.getClass().equals(jojo.getClass()) And you might also try comparing the canonical names of the classes for a similar effect: momo.getClass().getCanonicalName().equals(jojo.getClass().getCanonicalName())

Maybe_Factor
  • 370
  • 3
  • 10
-1

getClass() returns an instance of a Class. getClass().getName() returns a string. The String.equals(otherString) method is the correct way to compare Strings for equality.

GaryMcM
  • 425
  • 3
  • 9
  • 1
    But this would cause a *logic* error, not a *compilation* error, unless the original poster is confused about the difference between these two. – Hovercraft Full Of Eels Jan 07 '13 at 01:43
  • The question indicates that the intent is to check whether two references point to the same object. == is the correct way to do that. a.equals(b) asks whether two possibly distinct objects referenced by a and b are equal as equality is defined in a's class, a different question. – Patricia Shanahan Jan 07 '13 at 01:58
  • 1
    I don't see that the OP intended to compare strings at all here. Unless he has misread the javadoc for `.getClass()`. Badly misread. – fge Jan 07 '13 at 01:58
  • I was trying to read their intent, i.e. are the classes the same. I appreciate the feedback though. – GaryMcM Jan 07 '13 at 02:15