dart-lang / language

Design of the Dart language

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Why is Object not considered a superclass for null?

meg4cyberc4t opened this issue · comments

According to the documentation, I can get the following information:

Some other types also have special roles in the Dart language:

  • Object: The superclass of all Dart classes except Null.

However, when creating the dump of kernel binary file I can find the following lines:

@/* from org-dartlang-sdk:///sdk/lib/_internal/vm_shared/lib/null_patch.dart */ #C55
  @/* from org-dartlang-sdk:///sdk/lib/_internal/vm_shared/lib/null_patch.dart */ #C433
  @/* from org-dartlang-sdk:///sdk/lib/_internal/vm_shared/lib/null_patch.dart */ #C3
  @#C3
  final class Null extends core::Object { // from org-dartlang-sdk:///sdk/lib/core/null.dart
    static const field core::int _HASH_CODE = #C2837 /* from org-dartlang-sdk:///sdk/lib/_internal/vm_shared/lib/null_patch.dart */;
    get /* from org-dartlang-sdk:///sdk/lib/_internal/vm_shared/lib/null_patch.dart */ _identityHashCode() → core::int
      return #C2837;
    static factory _uninstantiable() → Null {
      throw new core::UnsupportedError::•("class Null cannot be instantiated");
    }
    @#C55
    get /* from org-dartlang-sdk:///sdk/lib/_internal/vm_shared/lib/null_patch.dart */ hashCode() → core::int
      return #C2837;
    method toString() → core::String
      return "null";
  }

They show that null is inherited from the object, and also implements toString and hashCode in patches.
I can find the relevant information in the language specification (chapter 17.4):

The Null class extends the Object class
and declares no methods except those also declared by Object. In particular, the Null class does not override the ‘==’ operator inherited from the Object class.

Why is it considered that object is not a superclass for null?
If not, is the superclass formulation correct and should we explain this language behavior in more detail in the documentation?

The way Null is defined in Kernel is an implementation detail. What specification says is that null is Object evaluates to false.

That language specification does not include the Null Safety feature, and is no longer correct. Null is not a subclass or subtype of Object.
Implementations may cheat, but as long as you can't tell, it's OK.

As for why Null is not a subclass of Object, it's because then there is a supertype for all non-null values.
Without that, you could do, fx, T? valueOf<T extends Object>(T value, bool useValue) => useValue ? value : null; and know that the value will not itself be null.

Thanks for the answers! It's much clearer to me now how it works.