Purpose of this method is explained in API documentation as follows:
it is invoked if and when the Java virtual machine has determined that there is no longer any means by which this object can be accessed by any thread that has not yet died, except as a result of an action taken by the finalization of some other object or class which is ready to be finalized...
the usual purpose of
finalize... is to perform cleanup actions before the object is irrevocably discarded. For example, the finalize method for an object that represents an input/output connection might perform explicit I/O transactions to break the connection before the object is permanently discarded...
If you're additionally interested in reasons why language designers have chosen that "object is irrevocably discarded" (garbage collected) the way that is beyond application programmer control ("we should never rely"), this has been explained in an answer to related question:
automatic garbage collection... eliminates entire classes of programming errors that bedevil C and C++ programmers. You can develop Java code with confidence that the system will find many errors quickly and that major problems won't lay dormant until after your production code has shipped..
Above quote, in turn, was taken from official documentation about Java design goals, that is it can be considered authoritative reference explaining why Java language designers decided this way.
For a more detailed and language agnostic discussion of this preference, refer OOSC section 9.6 Automatic memory management (actually, not only this section but the whole chapter 9 is very worth reading if you're interested in stuff like that). This section opens with an unambiguous statement:
A good O-O environment should offer an automatic memory management mechanism
which will detect and reclaim unreachable objects, allowing application developers to
concentrate on their job — application development.
The preceding discussion should suffice to show how important it is to have such a
facility available. In the words of Michael Schweitzer and Lambert Strether:
An object-oriented program without automatic memory management is
roughly the same as a pressure cooker without a safety valve: sooner or later
the thing is sure to blow up!