In this course, you'll explore how wildcards and type capture work, as well as how type erasure manifests itself in compiled bytecode. You'll start by examining how the wildcard operator, represented in syntax by the ? character, can be used in situations where you don't know up-front what type argument to specify for a particular type parameter. Next, you'll learn the three types of wildcard type parameters. Unbounded wildcards, where you know nothing at all about the type; upper bounded wildcards, which define type parameters that must inherit from a specific base class or interface; and finally lower bounded wildcards, which can be used to specify constraints in the other direction - namely that the type must be a super-class of a specified type. Next, you'll see that capture errors occur when Java is unable to infer the correct type to pencil in as the type argument for a given type parameter. Finally, you'll examine bytecode to see that whenever you create a class or method with a type parameter, Java creates just one single copy of such code, and pencils in a type parameter of java.lang.Object. It also adds various type checks to ensure that the code is used correctly. This is known as type erasure and forms the basis of the great performance of Java generics.