You can achieve this final effect from java by having a private constructor for your class, it will prevent the class from being extended, BUT it will also prevent the class from being instantiated (only in the same file both will be possible):
class MyString {
MyString._(); // use _ for private constructor.
static void print(String s) {
print(s);
}
}
Call with
String message = "Hello World";
MyString.print(message);
Dart considers that we are all adults, preventing class extension is hence part of the design and responsability of the developers to have clear class names, and not part of the language:
AVOID extending a class that isn’t intended to be subclassed.
If a constructor is changed from a generative constructor to a factory constructor, any subclass constructor calling that constructor will break. Also, if a class changes which of its own methods it invokes on this, that may break subclasses that override those methods and expect them to be called at certain points.
Difference of meaning for final with Java
Dart has a very simple definition of what is final: a variable in dart can only be set once, id est: is immutable.
Final and const
If you never intend to change a variable, use final or const, either instead of var or in addition to a type.
A final variable can be set only once; a const variable is a compile-time constant. (Const variables are implicitly final.) A final top-level or class variable is initialized the first time it’s used.