Differentiate Java's final, finalize, and finally. Define what final means for variables, methods, and classes and give examples; explain what finalize was intended to do and why it is discouraged or obsolete, and what to use instead; and describe the semantics of the finally block in try-catch-finally, including how it interacts with returns and exceptions. Include edge cases and best practices.