I am attempting to gain a better understanding of lower bounded wildcards on a site called Codecademy. For this purpose, I have created a TwoNListTester method in a custom ListTester class. I am using a pair of classes I have created called EvenNumber and EvenPowerOfTwo, where EvenNumber extends Number and EvenPowerOfTwo extends EvenNumber. The current code for the classes is as follows:
EvenNumber.java
import java.lang.IllegalArgumentException; public class EvenNumber extends Number { private int value; private boolean isEven(Number n) { return n.intValue() > 1 && n.intValue() % 2 == 0; } public EvenNumber() {} public EvenNumber(Number value) throws IllegalArgumentException { if (isEven(value)) { this.value = value.intValue(); } else { throw new IllegalArgumentException("Is not an even number"); } } public EvenNumber(String value) throws IllegalArgumentException, NumberFormatException { int parsed_value = Integer.parseInt(value,10); if (isEven(parsed_value)) { this.value = parsed_value; } else { throw new IllegalArgumentException("Is not an even number"); } } public Integer getValue() { return this.value; } public void setValue(Number value) throws IllegalArgumentException { if (isEven(value)) { this.value = value.intValue(); } else { throw new IllegalArgumentException("Is not an even number"); } } @Override public String toString() { return String.valueOf(this.value); } @Override public double doubleValue() { return (double) this.value; } @Override public float floatValue() { return (float) this.value; } @Override public long longValue() { return (long) this.value; } @Override public int intValue() { return (int) this.value; } }
EvenPowerOfTwo.java
import java.lang.IllegalArgumentException; public class EvenPowerOfTwo extends EvenNumber { private boolean isEvenPowerOfTwo(Number n) { /* First n in the below expression is for the case when n is 0 or 1 */ int n_int = n.intValue(); return n_int > 1 && ((n_int & (n_int - 1)) == 0); } public EvenPowerOfTwo() {}; public EvenPowerOfTwo(Number value) throws IllegalArgumentException { super(); if (isEvenPowerOfTwo(value)) { super.setValue(value.doubleValue()); } else { throw new IllegalArgumentException("Is not an even power of two."); } } public EvenPowerOfTwo(String value) throws IllegalArgumentException, NumberFormatException { super(); int parsed_value = Integer.parseInt(value, 10); if (isEvenPowerOfTwo(parsed_value)) { super.setValue((Integer) parsed_value); } else { throw new IllegalArgumentException("Is not an even power of two."); } } @Override public void setValue(Number value) { if (isEvenPowerOfTwo(value)) { super.setValue((Integer) value); } else { throw new IllegalArgumentException("Is not an even power of two."); } } }
ListTester.java
import java.util.List; import java.util.ArrayList; import java.util.function.Function; public class ListTester { public static void TwoNListTester( int count, List<? super EvenPowerOfTwo> wildList, Function<Number, ? super EvenPowerOfTwo> f) { for (int i = 0; i < count; i++) { Integer j = i + 1; EvenPowerOfTwo result = (EvenPowerOfTwo) f.apply(j); //These lines are the part wildList.add(result); //that are giving me trouble } } }
The intended design of the method inside the 'ListTester class' is to take the Function argument for parameter 'f' and populate List argument for parameter 'wildList' a specific number of objects, using the argument for 'count' to determine the number of objects to produce. The values returned by 'f' and the values added to the 'wildList' should both be the type EvenPowerOfTwo or one of its supertypes. Note the two lines of code that are followed by commented text. Ideally, this function should allow the user to also work with supertypes EvenPowerOfTwo, not just EvenPowerOfTwo itself. However, when I instead define the 'result' variable as an EvenNumber and pass the referenced EvenNumber object to the proceeding add command, it produces the following error.
no suitable method found for add(EvenNumber) wildList.add(result); ^ method Collection.add(CAP#1) is not applicable (argument mismatch; EvenNumber cannot be converted to CAP#1) method List.add(CAP#1) is not applicable (argument mismatch; EvenNumber cannot be converted to CAP#1) where CAP#1 is a fresh type-variable: CAP#1 extends Object super: EvenPowerOfTwo from capture of ? super EvenPowerOfTwo
The argument I am passing for 'wildList' is a List<EvenNumber> object. I am not sure why this is not working, despite EvenNumber being the super class of EvenPowerOfTwo. If anyone could shed some light on this, it would be greatly appreciated.