java-generics-pecs-–-producer-extends-consumer-super

“`html

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.

Table of Contents:

What are Generics in Java?

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.
quiz-icon

Covariance, Contravariance, and Invariance

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!”);

jQuery(“.maineditor48466 .copymessage”).show(); setTimeout(function() { jQuery(“.maineditor48466 .copymessage”).hide(); }, 2000); }).catch(err => { console.error(“Error copying code: “, err); }); }

function runCode48466() {

var code = editor48466.getSession().getValue();

jQuery(“#runBtn48466 i.run-code”).show(); jQuery(“.output-tab”).click();

jQuery.ajax({ url: “https://intellipaat.com/blog/wp-admin/admin-ajax.php”, type: “post”,

data: { language: “java”, code: code, cmd_line_args: “”, variablenames: “”, action:”compilerajax” }, success: function(response) { var myArray = response.split(“~”); var data = myArray[1];

jQuery(“.output48466”).html(“

"+data+"");
									jQuery(".maineditor48466 .code-editor-output").show();
									jQuery("#runBtn48466 i.run-code").hide();

} })

}

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:

Producing and Consuming

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.
quiz-icon

Conclusion

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.

Java Generics PECS – Frequently Asked Questions

Q1.What does PECS signify in Java?

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.

The post Java Generics PECS – Producer Extends Consumer Super appeared first on Intellipaat Blog.

“`


Leave a Reply

Your email address will not be published. Required fields are marked *

Share This