Skip to content

Equivalence between KeyImpl and TypedKeyImpl is not symmetric #13678

@NichtStudioCode

Description

@NichtStudioCode

Expected behavior

Object#equals's contract requires:

It is symmetric: for any non-null reference values x and y, x.equals(y) should return true if and only if y.equals(x) returns true.

Observed/Actual behavior

Equivalence between TypedKeyImpl and KeyImpl is not symmetric

Steps/models to reproduce

Key key = Key.key("minecraft:stone"); TypedKey<ItemType> typedKey = TypedKey.create(RegistryKey.ITEM, key); System.out.println(key.equals(typedKey)); // true System.out.println(typedKey.equals(key)); // false

Plugin and Datapack List

None

Paper version

This server is running Paper version 1.21.11-126-main@3f5728e (2026-02-28T11:49:07Z) (Implementing API version 1.21.11-R0.1-SNAPSHOT)

Other

In my opinion TypedKey shouldn't extend Key. But since it is too late to change this now, I think the problem could be solved by:

  1. In TypedKeyImpl, override equals and check if the other object is also a TypedKey. If so, additionally compare registry key. Otherwise, only compare namespace and value.
  2. In TypedKeyImpl, override hashCode and replace its implementation with that of KeyImpl (from adventure), such that the registry key has no influence on the hash code and equal keys have equal hash codes.

Metadata

Metadata

Assignees

No one assigned

    Type

    No fields configured for Bug.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions