In your public method foo, you have the following
if (str == null) throw new NullPointerException;
This is often called guard clauses and is generally more readable than just letting a null pointer exception be thrown by not including anything.
Regarding assert, it generally as @Sotirios mentions is not used in production code. Check out this answer for additional information: Java assertions underused.
There is definitely some subjectivity here which is better, but from a readability viewpoint, the guard clause in the public method appears to more readable. The assert provides no additional value especially if that private method is only called from that one public method. The assert would never trigger.