违反检查通用对象列表的方法

Violate the method that checks a list of generic objects

这是来自 Hyperskill.org 的任务。

任务说明是;

You need to add implementation to Violator.defraud() method that will do the following:

Create List of Boxes according to method signature Put Paper object in at least one Box in the list The resulting list should pass NaiveQualityControl check You shouldn't change method signature or change code of any other classes, just add implementaiton to defraud method.

/* This class and its subclasses should pass quality check */
class Bakery {}

class Cake extends Bakery {}

/* But this should not */
class Paper {}

/* These boxes are used to pack stuff */
class Box<T> {
    void put(T item) { /* implementation omitted */ }
    T get() { /* implementation omitted */ }
}

/* This quality checker ensures that boxes for sale contain Bakery and anything else */
class NaiveQualityControl {

  public static boolean check(List<Box<? extends Bakery>> boxes) {
    /* Method signature guarantees that all illegal 
       calls will produce compile-time error... or not? */  
    return true;  
  }

}

这是实现的方法;

class Violator {

    public static List<Box<? extends Bakery>> defraud() {
        // Add implementation here
    }

}

到目前为止我已经得到了这个;

public static List<Box<? extends Bakery>> defraud() {
        List<Box<? extends Bakery>> boxList = new ArrayList<>();

        Box<Paper> paperBox = new Box<>();
        Box<Bakery> bakeryBox = new Box<>();
        Box<Cake> cakeBox = new Box<>();

        boxList.add(bakeryBox);
        boxList.add(cakeBox);
        boxList.add(paperBox); // compile time error, required type <? extends Bakery>

        return boxList;
    }

显然这不会 运行。我曾尝试使用 Object 作为类型,但这超出了 <? extends Bakery> 的类型范围。我无法将 paperBox 转换为 <? extends Bakery Box 类型。

您可以使用 raw types 来绕过它(通过删除 boxList 的泛型)。事实上,如果这样做,您几乎可以添加任何类型的 Object:

public List<Box<? extends Bakery>> defraud() {
    List<Box<? extends Bakery>> boxList = new ArrayList<>();

    Box<Paper> paperBox = new Box<>();
    Box<Bakery> bakeryBox = new Box<>();
    Box<Cake> cakeBox = new Box<>();

    boxList.add(bakeryBox);
    boxList.add(cakeBox);

    List rawTypedList = boxList;    // Drop the generics to use raw types. 
    rawTypedList.add(paperBox);
    rawTypedList.add(new Object()); // Acutally, you can add any object, not just Boxes.

    return boxList;
}

您会收到来自编译器的警告或 IDE 使用 raw types 尽管它被认为是 不好的做法