diff --git a/05-generics/snippets/src/LowerBoundedWildcardGenerics.java b/05-generics/snippets/src/LowerBoundedWildcardGenerics.java index 5796b773..49f393f6 100644 --- a/05-generics/snippets/src/LowerBoundedWildcardGenerics.java +++ b/05-generics/snippets/src/LowerBoundedWildcardGenerics.java @@ -1,3 +1,5 @@ +// Imagine we cannot modify the Shape interface (e.g. it comes from a 3rd-party library), +// or we don't want to force all implementers to be comparable. interface Shape { double area(); } @@ -39,18 +41,15 @@ public String toString() { } } -// A utility class that will use lower-bounded wildcard generics class ShapeUtils { // This method leverages generics and bounded wildcards to handle a flexible range of types - // while maintaining type safety. - public static T findLargestShape(T[] shapes) { + // while maintaining type safety. The lower bound (`super`) wildcard allows the method to accept + // an array of shapes that are comparable based on the interface of the same type or a supertype. + public static > T findLargestShape(T[] shapes) { T largest = shapes[0]; for (T shape : shapes) { - // The expression `Comparable` is used to cast `shape` to ensure compatibility - // with the `compareTo` method. The lower bound (`super`) is necessary for handling the case where `T` - // could be a subtype of `Rectangle`, allowing comparison across derived classes like `Square`. - if (((Comparable) shape).compareTo(largest) > 0) { + if (shape.compareTo(largest) > 0) { largest = shape; } } @@ -60,11 +59,11 @@ public static T findLargestShape(T[] shapes) { // Note that if we change the generic type of the method above to >, // the `shapes` array can only contain elements of the same type `T`, because `Comparable` restricts `T` // to be compared only with objects of the same type. - // As a result, it would not be possible to use this method with an array of mixed types like - // `[Rectangle, Rectangle, Square, Square]`, reducing its flexibility. + // As a result, it would not be possible to use this method with an array of mixed types like `rectangles` below, + // reducing its flexibility. + } -// Main class to test the implementation public class LowerBoundedWildcardGenerics { public static void main(String[] args) { Rectangle rect1 = new Rectangle(4, 5); @@ -77,10 +76,11 @@ public static void main(String[] args) { Square[] squares = {square1, square2}; // Find the largest shape - Shape largestShape = ShapeUtils.findLargestShape(shapes); - //Shape largestRectangle = ShapeUtils.findLargestShape(rectangles); - //Shape largestSquare = ShapeUtils.findLargestShape(squares); + //Shape largestShape = ShapeUtils.findLargestShape(shapes); // Won't compile: not every shape is comparable + Shape largestRectangle = ShapeUtils.findLargestShape(rectangles); + Shape largestSquare = ShapeUtils.findLargestShape(squares); - System.out.println("The largest shape is: " + largestShape); + System.out.println(largestRectangle); + System.out.println(largestSquare); } }