Object
is a type like any other that is used as a basis for the other types and have a few members as you can see in documentation. So it’s mostly used to compose other types or indicate that you accept any object at a particular location in the code (what you’re asking in the question).
If you are accessing the object by this type you can only see the members of Object
shown in the documentation. You can only access other members if you cast for a subtype, which is only possible if the specific object is of that subtype (if it is not the application breaks).
So it’s a generalization, an abstraction, but it’s a very simple regular type and it has no specific usefulness.
dynamic
(Did you notice the tiny one? ) is not a type, it is an indication that the object can be of any type and anything you try to access the compiler will leave without giving error (does not mean that it will work, can give error during the execution if the concrete object does not have the member who is accessing). It’s just a syntax to turn off the type check.
So the object that has been declared to be dynamic allows it to work freely as it does in a dynamic typing language without preventing compilation because it is accessing a member that does not exist. It makes the application slower and less robust.
They look the same because the idea is that you can’t define the exact type, but the way you deal with it is quite different. The Object
has little real utility, you need to convert to a subtype to make specific use of some object functionality, while dynamic
subvert the security system of types.
In all languages that have these mechanisms I see programmers abusing, in general they are less necessary than it seems when available Generics and other more secure and useful mechanisms. In Dart is no different, it is more robust and sometimes easier to use a specific object, even if in a generic way. Rare cases that need to accept an object any or an object you do not know its composition.