Java Generics offer adaptability and type security when working with collections and data structures. A fundamental concept related to generics is PECS, which stands for “Producer Extends, Consumer Super.” Advocated by Joshua Bloch, this guideline aids developers in determining the most appropriate wildcard while handling generic types. This article elaborates on PECS and its related themes such as covariance, contravariance, and invariance.
A class, interface, or method that operates on a specified data type is referred to as a generic entity.
In Java, generics empower you to design classes, interfaces, and methods that can manipulate various data types while ensuring type safety at compile time, thus eliminating the necessity for casting and enhancing code clarity.
The Object class is the parent class of all other classes, and its reference can be utilized to point to any object. Such types of objects lack type safety. Consequently, generics introduce a form of safety by utilizing a specific data type.
Wildcards in Java
In generic code, the question mark (?) is termed as the wildcard in generic programming. It signifies an unknown type. The wildcard can be employed in various contexts, such as for parameters, fields, or local variables. Unlike arrays, distinct objects of a generic type are not compatible with one another, even implicitly. This can be addressed through the wildcard when it serves as an actual type parameter.
Java Training
This is a thorough training program in Java programming language that will facilitate your advancement in your software coding career.
In Java Generics, these principles describe how data types are interconnected when utilizing wildcards.
Covariance (? extends T) permits a generic type to be a subtype of another generic type, e.g., a List<? extends Number> can contain an Integer, Double, or Float value, and it is read-only, meaning new elements cannot be added.
List<? extends Number> numbers = new ArrayList<Integer>(); Number num = numbers.get(0); // Allowed // numbers.add(10); // Not permitted
Contravariance (? super T) allows a generic type to be a supertype of another generic type, i.e., a List<? super Integer> can contain Integer, Number, or Object values, enabling elements to be added but requiring safe retrieval as Object.
List<? super Integer> numbers = new ArrayList<Number>(); numbers.add(10); // Allowed Object obj = numbers.get(0); // Reading results in Object
Invariance (No Wildcards) signifies that a generic type must match exactly, so a List<Number> can only hold Number and not its subtypes like Integer. These rules ensure safety and provide flexibility.
List<Number> nums = new ArrayList<>(); nums.add(1); // Allowed // List<Integer> ints = nums; // Not permitted
What is PECS?
The principle of PECS is divided into two segments:
1. Producer Extends: If you solely produce items from a structure, use <? extends T>
2. Consumer Super: If you exclusively consume items from a structure, use <? super T>
PECS, Producer Extends, Consumer Super is a guideline in Java Generics that assists in determining whether to use extends or super when addressing wildcard types (?).
It was introduced by Joshua Bloch to enhance the flexibility and security of generic code.
For instance, the Mammal class is a subclass of the Animal class (Animal serves as the superclass of Mammal). The Cat/Dog class inherits from the Mammal class (Mammal is the superclass of Cat/Dog).
Producer Extends
The <? extends T> wildcard is applied when you aim to solely produce items from a structure. This signifies that you will only read items from the structure and refrain from writing to it. The extends keyword is employed to denote that the wildcard signifies a subtype of T.
Example
List<? extends Number> numbers = new ArrayList<Double>();
Number num = numbers.get(0); // Allowed (reading)
numbers.add(10); // writing not permitted
Consumer Super
The <? super T> wildcard is utilized when you wish to solely consume items from a structure. This means that you will exclusively write items to the structure and never read from it. The super keyword is used to indicate that the wildcard signifies a supertype of T.
Example
List<? super Integer> numbers = new ArrayList<Number>();
numbers.add(10); // Allowed (writing)
Integer num = numbers.get(0); // reading is not safe
Producing and Consuming
In scenarios where a collection both produces and consumes elements simultaneously, PECS (Producer Extends, Consumer Super) does not apply. Instead, it is advisable to use an exact generic type (T) without wildcards, allowing for both reading and writing.
Example: Modifying a List
“““html Duplicate Code
Code Successfully Copied!
var isMobile = window.innerWidth “);
editor48466.setValue(decodedContent); // Set the default text
editor48466.clearSelection();
editor48466.setOptions({
maxLines: Infinity
});
function decodeHTML48466(input) {
var doc = new DOMParser().parseFromString(input, “text/html”);
return doc.documentElement.textContent;
}
// Function to copy code to clipboard
function copyCodeToClipboard48466() {
const code = editor48466.getValue(); // Get code from the editor
navigator.clipboard.writeText(code).then(() => {
// alert(“Code copied to clipboard!”);
function closeoutput48466() {
var code = editor48466.getSession().getValue();
jQuery(".maineditor48466 .code-editor-output").hide();
}
// Attach event listeners to the buttons
document.getElementById("copyBtn48466").addEventListener("click", copyCodeToClipboard48466);
document.getElementById("runBtn48466").addEventListener("click", runCode48466);
document.getElementById("closeoutputBtn48466").addEventListener("click", closeoutput48466);
Outcome:
Clarification: The code mentioned above illustrates both production (reading) and consumption (writing) within a list. The alterList function reads each element from the list and displays it. Subsequently, it adds a new element to the list. Given that the function processes both reading and writing, it utilizes List<T> without wildcards.
Real-Life Analogy
Envision you have two water vessels: a larger one and a smaller one.
You cannot transfer water from a larger vessel into a smaller one without causing spills. You CAN ONLY transfer water from a smaller vessel into a larger one.
Therefore,
When you apply <? super SomeType>, you depict a vessel that is equal in size or larger
When you apply <? extends SomeType>, you depict a vessel that is equal in size or smaller
Now, you can conceptualize it by viewing Producers and Consumers in this manner:
A ‘Producer’ is akin to a vessel from which we only extract water. i.e., we can withdraw water from it, but we cannot add more because we are unaware of its precise type A ‘Consumer’ is similar to a vessel into which we only deposit water. i.e., we can pour water into it, but we lack knowledge of its content, so we must exercise caution
Free Online Java Certification Course
This self-directed Java course will assist you in building a solid foundation and job-ready skills in Java development.
PECS is a pivotal concept in Java Generics that ensures safety when dealing with wildcard types. Producers are limited to reading, while Consumers are confined to writing. If both reading and writing are essential, a generic type (T) devoid of wildcards is recommended. This enhances the versatility and security of generic code, enabling Java collections to be more efficient and type-safe.
If you wish to expand your knowledge of Java, consider consulting our Java Course.
PECS is an acronym for Producer Extends Consumer Super. It serves as a mnemonic to assist us in recalling these principles and their consequences when working with generics in Java.
“““html
Q2. What is super and super () in Java?
The super keyword in Java serves as a reference variable that points to the parent class’s objects, variables, and methods. Conversely, the super() in Java is utilized to invoke the constructor of the parent class. super() can be leveraged to access parent class variables and methods, but it is solely designated for calling parent class constructors.
Q3. How many extends in Java?
In Java, classes can only extend one superclass.
Q4. What is a superclass in Java?
The class from which the subclass originates is referred to as a superclass (also known as a base class or parent class).
Q5. What is the distinction between extends and super in Java?
Extends keyword introduces flexibility to return types while restricting method parameter types. Super keyword enhances flexibility for method parameter types but renders return types ineffective.
To provide the best experiences, we use technologies like cookies to store and/or access device information. Consenting to these technologies will allow us to process data such as browsing behavior or unique IDs on this site. Not consenting or withdrawing consent, may adversely affect certain features and functions.
Functional
Always active
The technical storage or access is strictly necessary for the legitimate purpose of enabling the use of a specific service explicitly requested by the subscriber or user, or for the sole purpose of carrying out the transmission of a communication over an electronic communications network.
Preferences
The technical storage or access is necessary for the legitimate purpose of storing preferences that are not requested by the subscriber or user.
Statistics
The technical storage or access that is used exclusively for statistical purposes.The technical storage or access that is used exclusively for anonymous statistical purposes. Without a subpoena, voluntary compliance on the part of your Internet Service Provider, or additional records from a third party, information stored or retrieved for this purpose alone cannot usually be used to identify you.
Marketing
The technical storage or access is required to create user profiles to send advertising, or to track the user on a website or across several websites for similar marketing purposes.