Interesting Bug I just discovered. If you have `-X...
# announcements
j
Interesting Bug I just discovered. If you have
-Xjsr305=strict
enabled and you have a java class annotated with:
@ParametersAreNonnullByDefault
. If that class overrides
equals(Object other)
without having
@Nullable
on the
other
param, kotlin can't use the
==
operator. Eg. The following won't compile:
JavaSomething("one") == JavaSomething( "one")
Java side:
Copy code
@ParametersAreNonnullByDefault
public class JavaSomething {

    private final String something;

    JavaSomething(String something) {
        this.something = something;
    }

    @Override
    public boolean equals(final Object other) {
        if (this == other) return true;
        if (other == null) return false;
        if (this.getClass() != other.getClass()) return false;
        final JavaSomething javaOther = (JavaSomething) other;
        return something.equals(javaOther.something);
    }
}
a
What error do you get during compilation?
j
a
I'm not entirely sure that this is actually a bug.
==
requires you to have a
equals(other: Any?): Boolean
, but you only have
equals(other: Any): Boolean
j
I suppose you're correct, but what if the java code is a third part library?
a
Then you can do it the old-fashioned way
this.equals(other)
d
This should be considered a compatibility bug.
a
compatibility bug in what way?
d
In Kotlin, you can't override a function with a parameter declared nullable with one that declares the same parameter not-null. In Java, you can, because annotations are only hints and the constraints they declare are not enforced. Thus, Kotlin should discard the not-null constraint present in your code when resolving the target of the
==
operator. I mean that, when it tries to find
fun equals(Any?): Boolean
, it should realize that the method you declared is matching it because the not-null constraint it declares is invalid.
a
but what if the library author added the
@NotNull
annotation on purpose and doesn't handle the null-case inside
equals
? Kotlin can't just assume that
@NotNull
is invalid here
d
yeah, maybe there should just be an exception for
equals
.
Thing is, if the type of the object were
Any
at compile time, there wouldn't be a problem. It's really the library author's fault if they don't carry over nullability.
a
right, in Java
other
is actually nullable, because Java doesn't care about annotations
IMO it should be enforced on the java side, but on the other hand java has no notion of nullable vs non-nullable
it is an interop edge-case and from past decisions we know that kotlin chooses the "rather safe than sorry" way
==
could be changed so that it checks
other == null
first, but is it worth it when the library is at fault?
d
Good question.
Maybe it's not so good to swallow the problem like that.