The java developers' slogan is “100% Java,” meaning “Don't taint your Java software by incorporating non-Java components.” Yet, Java itself is neither 100% pure object nor 100% pure object-oriented; it is “tainted” with components of the procedural programming paradigm. The Java designers have borrowed many ideas from diverse sources—other object-oriented languages, especially C++ and Smalltalk, design patterns (see Gamma, E. et al. Design Patterns: Elements of Reusable Object-Oriented Software, Addison-Wesley, 1995), and basic object-oriented design principles—picking and choosing good ideas from each. And they've done a truly fine job. However, at one particular juncture, I believe the language architects made the wrong choice, and that was the decision to incorporate non-object primitive types into the otherwise uniform object-oriented language model.
There are two types of types in Java. By primitive types, I mean elementary variable types such as int, boolean, float, long, short, and so on. These are sometimes referred to as “built-in” types. The other type of type is objects: a variable can be declared to be of type Object or String or any other class. Referring to the two types of types as metatypes, we have primitive and object metatypes (the truth is, the two metatypes are primitive and reference, which includes not only objects, but interfaces and arrays—more on why they are “reference” types later). By incorporating both metatypes, Java is not populated purely with objects.