I didn’t leave any public MultiPhraseQuery constructors like you did for PhraseQuery. Adding a few afterwards shouldn’t break anything
I think it's good this way: I added them for PhraseQuer because I thought it should be easy to create simple phrase queries but maybe it was a mistake. MultiPhraseQuery on the other hand is an expert query so I'm totally fine with not having convenience constructors.
The private termArrays and positions members could become fixed arrays like you did for PhraseQuery. This would change the signature
of getTermArrays() and getPositions(), so perhaps it should happen now…
Actually I think returning a list is better: with arrays you need to perform a deep copy if you want to make sure that the user cannot change the internal state of the query. We could keep arrays internally and call Collections.unmodifiableList(Arrays.asList(termArrays)) when returning the terms to the user?