Excellent call out - thank you, Paul A.
Fabio, if you're studying for Java 17, it's probably a good idea to be running JDK 17 when you're
testing things. Usually, it's OK to use a later version. But in this case, they later allowed something that was initially not allowed. If you try compiling with JDK 17, you should see the error you expected.
Thinking more though, I think that
if the book says something like "the pattern variable must be a subtype of the variable on the left side of the expression" (still haven't seen an actual quote), then it's still wrong here. Because the pattern variable (right hand side) may actually be totally unrelated to the type of the expression (left hand side).
The compiler will accept this, because it knows that it's theoretically possible for a Foo instance to also implement Serializable. It would have to be a subclass, and that's not what we have here, obviously. But if the compiler considers only the type of the expression f, which is Foo, and the type of the pattern s, which is Serializable... considering only those things, and the declarations of Foo and Serializable... it is possible that a Foo could also be Serializable. So it's allowed.
If you make class Foo final, then it becomes impossible, and is not allowed. Because Foo itself is not Serializable, and no other subclass of Foo can exist, so no Foo is Serializable, ever.
This is pretty similar to the rules for casting - if a cast is probably impossible based on the types involved, it will not be allowed. If it's at least theoretically possible based on the type, it's allowed. It may fail at runtime, but it's allowed.