I would like to offer my two cents on the no-args constructor. These have been disdained in recent years because of the issues pointed out recently of making invalid instances. They would also tend to make instances that are not thread safe. That's partly because the creational thread could be part-way through completing the instance' data when the instance is used by another thread, but also because you can never be sure if the completed instance might get
changed by one thread while another is using it.
One alternative offered is an "all-args" constructor, which I think you mentioned. That's a term used in the Lombok framework. That is fine, but at a certain point you can get an unwieldy number of arguments, or you can end up with multiple "many-arg" constructors (as the OP mentioned). There is an excellent discussion of this in Bloch's "Effective Java". What Bloch suggests is that above a certain number (4?), you employ a Builder pattern. That one has a builder supplying the created object (which can have an all-args constructor with appropriate defaulting for variations you might run into). This builder is responsible for having setters (which don't have to be called set*) for any parameter you might want, as well as doing validation before returning your completed object from a "build()" method at the end. This is usually done with a fluent coding style. He also mentions the use of static factory methods, which can return an instance of an interface, so that for things like testing (maybe) you could return a different implementation. Under other circumstances, you could return the same object multiple times, etc.
That said, if you are going to be making objects with some kind of automated tooling (you mentioned introspection and newInstance) doing the classic "bean" pattern with no-args + many setters might be just fine. If you setup packages just right, you might even be able to avoid having anything with
access for changing it once it has been populated. Bean pattern is how many of the older frameworks do it. It is what Java Beans were initially intended for.
This part the OP mentioned about
I couldn't simply throw a list of values at the class definition and get what I wanted. I had to scan the entire list of available constructors and match the values supplied to the constructor argument lists to see which constructor to invoke.
is something Bloch also describes in his book. It is what I alluded to above--variations in the arguments needed to make a complete object. His solution was multiple different factory methods with names like "of(arg1,arg2)" or "of(arg3,arg4)", and each of those is responsible for completing and returning a validated object. Builder could still work for that as well. Different names for factory methods specific to the situation could be chosen as well.
I hope that helps