The contract of equals with regards to null, is as follows:
For any non-null reference value
x,x.equals(null)sho
In the first case o1.equals(o2) returns false because o1 is not equal to o2, which is perfectly fine. In the second case, it throws NullPointerException because o2 is null. One cannot call any method on a null. It may be a limitation of programming languages in general, but we have to live with it.
It is also not a good idea to throw NullPointerException you are violating the contract for the equals method and making things more complex than it has to be.