Isso é uma feature do Java Generics que serve para limitar o escopo de tipos que podem ser usados. Se você não entende como funciona o Java Generics, dá uma pesquisada antes de continuar lendo essa resposta, senão não vai fazer sentido nenhum.
Digamos que você quer implementar uma estrutura de dados qualquer, chamada Struct. Nela você quer guardar apenas números, sendo eles de qualquer tipo numérico, porque por algum motivo você precisa usar o método byteValue na implementação (e.g. Number, Double, etc.). Se você declarar a classe como: class Struct<E> { e chamar o método byteValue em algum lugar da implementação dessa classe, o código não vai compilar. Por exemplo:
class Struct<E> {
void foo (E n) {
System.out.println(n.byteValue());
}
}
Esse código não compila, porque o tipo E pode ser qualquer coisa e não é garantido que ele vai ter o método byteValue.
Agora, você pode especificar para o compilador que o tipo E é qualquer tipo que herda da classe Number, que tem o método byteValue. Esse código funciona:
class Struct<E extends Number> {
void foo (E n) {
System.out.println(n.byteValue());
}
}
Agora a classe Struct só pode ser utilizada com tipos que herdam de Number. Existe também a keyword super, que vai no mesmo lugar do extends, e funciona ao contrário: o tipo genérico pode ser de qualquer classe da qual o tipo específico herda.