Short answer
Building paths by string concatenation hardcodes separators (breaking cross-platform) and is error-prone, whereas Path.resolve and the Paths/Path API handle separators and normalization correctly.
Explanation
The security angle is path traversal: if you join user input naively, a value like '../../etc/passwd' escapes your intended directory. The defense is to resolve against a known base, call normalize(), and then verify the result still startsWith the base directory before touching the file.
Common mistakes
- Building paths with string concatenation and '/' separators.
- Not normalising user paths, which allows ../ path traversal.