This does not have anything to do with 'final'. If you would remove the 'final', you would see that the result is also 'true'.
String literals, such as the "1" in your example, are managed in an internal string pool. If you use the same string literal in your source code more than once (as you have "1" two times), then Java is smart enough to make only one String object, and re-use that object.
So your str1 and str2 both refer to the same String object. The == operator returns true when two variables refer to the same object.
Adding to what Jesper has told, they are treated as compile time constants as the contents of Strings are well determined during the compile time itself. That's where there are being a part of String Literal pool referring the single String object.