Well, you could adapt some of the examples of that same chapter to reproduce a case of this.
For example, consider the following generic class:
class Node<E> {
private E value;
@Override public String toString(){ return value.toString(); }
}
Now, imagine that you write the following piece of code, which is wrong:
Object o = new Node<Integer>(10);
Node<String> node = new Node<>("Hello");
if(o instanceof Node) {
Node other = (Node) o;
other.value = node.value; //Uh oh! Warning
}
System.out.println(node); //Hello
System.out.println(other); //Hello - WTH!
If you try to compile this, you would only get a warning, but it would still compile just fine:
javac -Xlint:unchecked Node.java
Node.java:21: warning: [unchecked] unchecked assignment to variable value as member of raw type Node
other.value = node.value;
^
1 warning
However, if you change the code to use unbounded wildcards:
Object o = new Node<Integer>(10);
Node<String> node = new Node<>("Hello");
if(o instanceof Node<?>) {
Node<?> other = (Node<?>) o;
other.value = node.value; //Uh oh! Compiler error
}
Now you would get the following error when compiling:
javac -Xlint:unchecked Node.java
Node.java:21: error: incompatible types: String cannot be converted to CAP#1
other.value = node.value;
^
where CAP#1 is a fresh type-variable:
CAP#1 extends Object from capture of ?
1 error
So, as you can see the unbounded wildcard offers better type checking guarantees than the raw type.