I think it would work, and it could be really useful.
Imagine:
Code:
@NotEmpty
String name;
@NotEmpty
List<Insurance> insurances;
@NotEmpty
byte a;
If the framework could look at the declared type to which it is attaching the specific Contraint instance, it could immediately tell the third annotations is wrong. @NotEmpty accepts Arrays, String, Collection and Map, any subclass will still be accepted. If there were code trying to put a byte in insurance, it wouldn't compile anyway.
It could have some nice consequences:
* tools could use it to produce coding-time warnings
* you won't get RunTimeExceptions for that one value you forgot testing
* separate concerns in Constraint implementation
* faster execution, as implementations can trust the type and forget type checking
Imagine in the case of @NotEmpty I could create an appropriate delegate at initialization time, and always use that one when validate(..) is called, instead of type-testing at each call.