Existential
CodeGenerator.scala
import scala.language.existentials
没明白这行代码在这个文件里的作用,注释掉好像没什么影响???
Java Wildcard
public void addRectangle(List<? extends Shape> shapes) {
// Compile-time error!
shapes.add(0, new Rectangle());
}
You should be able to figure out why the code above is disallowed. The type of the second parameter to shapes.add() is ? extends Shape-- an unknown subtype of Shape. Since we don't know what type it is, we don't know if it is a supertype of Rectangle; it might or might not be such a supertype, so it isn't safe to pass a Rectangle there.
意思是shapes是List<>不知道啥类型,所以不能加Rectangle?
java Unbounded Wildcards
Java Upper Bounded WildcardsIt's important to note that List<Object> and List<?> are not the same. You can insert an Object, or any subtype of Object, into a List<Object>. But you can only insert null into a List<?>
It would be reasonable to write the following code:
B b = new B();
A a = b;
This example shows that inheritance of regular classes follows this rule of subtyping: class B is a subtype of class A if B extends A. This rule does not apply to generic types:
List<B> lb = new ArrayList<>();
List<A> la = lb; // compile-time error
Although Integer is a subtype of Number, List<Integer> is not a subtype of List<Number> and, in fact, these two types are not related. The common parent of List<Number> and List<Integer> is List<?>.
public class WildcardError {
void foo(List<?> i) {
i.set(0, i.get(0));
}
}
When the foo method invokes List.set(int, E), the compiler is not able to confirm the type of object that is being inserted into the list, and an error is produced.
According to Programming in Scala
An existential type includes references to type variables that are unknown. For example, Array[T] forSome { type T } is an existential type. It is an array of T , where T is some completely unknown type. All that is assumed about T is that it exists at all. This assumption is weak, but it means at least that an Array[T] forSome { type T } is indeed an array and not a banana.
Existential types are a fully supported part of the language, but in practice
they are mainly used when accessing Java types from Scala.
The general form of an existential type is as follows: type forSome { declarations }
A Java Iterator<?> would be written in Scala as: Iterator[T] forSome { type T }