I don't know about the practicality of the approach though. Seems like it could get tedious to define types for potentially hundreds of different attributes. I immediately start thinking of base classes for StringWrapper, IntegerWrapper (redundant?), etc. Then you'll get into having to decide on overriding equals() and hashCode(), delegating built-in String methods like substr, split, contains, etc. and other things you tend to take for granted when you deal with native/standard types. I don't know if it's going to be more trouble than it's worth. The other thing too is that it's not a very common approach and you'd have to explain it to the rest of your team and leave documentation for others coming in after you to explain the design choices. Without that documentation, "WTF?!" can certainly be an understandable reaction from anyone who sees the code for the first time.
Give it a try and let us know how it works out for you.
It reminds me the issue with Hungarian notation. Given two data types which are technically equivalent, might be different in their usage. A String if identifies a person is of different use from a String identifying, say, a flight and it is not good to intermix them. Whether this issue should be addressed by using different types, a naming convention or meticulous care to the parameter names, depends on the very situation.