Programação Orientada a Objetos Aula 11 – Tipos Genéricos Qual a diferença? List l1 = new ArrayList(); List<String> l2 = new ArrayList<String>(); 2 Qual a diferença? 3 Antes do Java 5 4 Do Java 5 em diante 5 Diferenças 6 Isso pode! 7 Isso não pode! 8 Antes do Java 5 era +- assim... 9 Semelhanças entre Pré e Pós Java 5 10 Misturando Pré e Pós Java 5 Generics 11 Misturando Pré e Pós Java 5 Generics 12 Misturando Pré e Pós Java 5 Generics 13 Misturando Pré e Pós Java 5 Generics Remember that compiler warnings are NOT considered a compiler failure. The compiler generated a perfectly valid class file from the compilation, but it was kind enough to tell you by saying, in so many words, "I seriously hope you know what you are doing because this old code has NO respect (or even knowledge) of your <Integer> typing, and can do whatever the heck it wants to your precious ArrayList<Integer>." 14 Misturando Pré e Pós Java 5 Generics • There's one Big Truth you need to know to understand why it runs without problems—the JVM has no idea that your ArrayList was supposed to hold only Integers. The typing information does not exist at runtime! All your generic code is strictly for the compiler. Through a process called "type erasure," the compiler does all of its verifications on your generic code and then strips the type information out of the class bytecode. At runtime, ALL collection code—both legacy and new Java 5 code you write using generics— looks exactly like the pre-generic version of collections. None of your typing information exists at runtime. In other words, even though you WROTE 15 Resumindo (DICA) Nunca misture o estilo antigo pré Java 5 (sem Generics) com o estilo novo (Java 5 em diante) que inclui GENERICS!! 16 Polimorfismo e Generics • Já sabemos que uma referência de List pode apontar para um ArrayList... porque ArrayList é um List. • E isto? 17 Polimorfismo e Generics • Não, isto não compilará! • A regra é simples: o tipo da variável declarada deve corresponder ao do tipo do objeto que ela aponta! 18 Polimorfismo e Generics • Se você declarar List<Foo> foo, então, o que quer que você atribua à referência foo DEVE ser do tipo genérico <Foo>. – Não um subtipo de <Foo> – Nem um supertipo de <Foo> – Apenas <Foo> 19 Polimorfismo e Generics • Mas esses estão corretos: • Até aqui tudo bem... • Em outras palavras, o polimorfismo só se aplica ao tipo “base” (List e ArrayList) • Uma coleção de <JButton> não pode ser atribuída a uma referência de <Object>, mesmo que JButton seja um Object. 20 Parece estranho? Polimorfismo não funciona com Generics da mesma forma que funciona com arrays!! 21 Polimorfismo – AnimalDoctor Example 22 Polimorfismo – AnimalDoctor Example • Na classe AnimalDoctor, você poderia ter o seguinte método: 23 Polimorfismo – AnimalDoctor Example 24 Polimorfismo – AnimalDoctor Example 25 Polimorfismo – AnimalDoctor Example • Porém, nós poderíamos passar essa lista: 26 Polimorfismo – AnimalDoctor Example • Para arrays já sabemos que funciona: E por que para Coleções não funciona de modo semelhante? Por causa do apagamento dos TIPOS GENÉRICOS em tempo de execução! Em tempo de execução, a JVM sabe o tipo dos arrays mas não o tipo de uma coleção! 27 Polimorfismo – AnimalDoctor Example • As long as the only thing you pass to the addAnimals(List<Animal>) is an ArrayList<Animal>, the compiler is pleased—knowing that any Animal subtype you add will be valid (you can always add a Dog to an Animal collection, yada, yada, yada). But if you try to invoke addAnimal() with an argument of any OTHER ArrayList type, the compiler will stop you, since at runtime the JVM would have no way to stop you from adding a Dog to what was created as a Cat collection. 28 Polimorfismo – AnimalDoctor Example • O código abaixo não compilará: 29 O coringa <?> • A solução para este problema é usar o coringa <?> Tudo que passar no teste É-UM Animal! • Contanto que você não adicione nada nessa lista! 30 O coringa <?> 31 O coringa <?> • Com o super você pode adicionar a lista! – Pare e pense... Faz sentido? 32 O coringa <?> • If there IS a difference (and we're not yet saying there is), what is it? There IS a huge difference. List<?>, which is the wildcard <?> without the keywords extends or super, simply means "any type." So that means any type of List can be assigned to the argument. That could be a List of <Dog>, <Integer>, <JButton>, <Socket>, whatever. And using the wildcard alone, without the keyword super (followed by a type), means that you cannot ADD anything to the list referred to as List<?>. List<Object> is completely different from List<?>. • List<Object> means that the method can take ONLY a List<Object>. Not a List<Dog>, or a List<Cat>. It does, however, mean that you can add to the list, since the compiler has already made certain that you're passing only a valid List<Object> into the method. 33 O coringa <?> • Compila? Sim ou não (por que?)? 34 O coringa <?> • Compila? Sim ou não (por que?)? 35 O coringa <?> • By the way, List<? extends Object> and List<?> are absolutely identical! They both say, "I can refer to any type of object." But as you can see, neither of them are the same as List<Object>. One way to remember this is that if you see the wildcard notation (a question mark ?), this means "many possibilities". If you do NOT see the question mark, then it means the <type> in the brackets, and absolutely NOTHING ELSE. List<Dog> means List<Dog> and not List<Beagle>, List<Poodle>, or any other subtype of Dog. But List<? extends Dog> could mean List<Beagle>, List<Poodle>, and so on. Of course List<?> could be... anything at all. 36 O coringa <?> 37 Declarações de Genéricos • O <E> representa o tipo que você deve passar. • Quando você codificar, você poderá criar um List<Dog> ou um List<Integer>, e daí por diante. • By the way, o “E” é apenas uma convenção. Qualquer identificador Java funcionaria aqui, mas “E” significa “Element”, e é geralmente utilizado para genéricos em coleções. • Outra convenção é utilizar “T” (para “Type”) para qualquer outra coisa que não coleções. 38 Declarações de Genéricos • Em outras palavras, o que quer que seja “E” quando você instanciar a Lista, é isto que você poderá adicionar a ele. 39 Criando sua própria classe Genérica • Vamos criar uma classe para gerenciar os aluguéis de algum empreendimento: 40 Criando sua própria classe Genérica • Suponha agora que você quer torná-la específica para carros: 41 Criando sua própria classe Genérica • O jeito correto: 42 Criando sua própria classe Genérica 43 Outro exemplo 44 Outro exemplo 45 Outro exemplo • Tipos genéricos “limitados”: 46 Criando métodos genéricos Declaração do tipo genérico Chamando o método com um objeto Dog 47 Referências • SCJP 6 – Livro de certificação do Java 48