Tipologia <T> como fazer isntanceof T

[quote=Lavieri]Que o compilador some com o T, eu sei… so que da mesma forma que ele subistitui os T por Cidade e cria os métodos correspondentes…

ele poderia subistituir

candidate instanceof T

por

candidate instanceof Cidade

é tão simples substituir isso quando subistituir no resto, não entendo a dificuldade real de fazer isso… mais enfim… paciencia…[/quote]

Aí é que está o porém. O COMPILADOR NÃO FAZ ISSO. Ele substitui T por Object e ponto-final. Daí ele cria alguns casts e alguns métodos ocultos para lidar com a incompatibilidade.

Na verdade, a forma como generics foi implementado é uma gambiarra. E como toda boa gambiarra está cheia de problemas estranhos e regras obscuras. Eles implementaram assim para que não houvessem problemas de compatibilidade com java 1.4 e inferiores.

C++, por exemplo, faz essa substituição mais ou menos da mesma forma que você falou. Mas isso gera dois problemas:

  1. Você tem centenas de classes sintéticas. Em C++, coisas como List<Cachorro>, List<Gato> e List<Integer> são diferentes. Além disso, trabalhar com coringas (aquele ?) seria muito mais complexo no java (C++ não tem coringas). No java, como o generic é apagado, você tem List simplesmente.
  2. Problemas de compatibilidade com o java 1.4. Se o generic não fosse apagado do bytecode, seria necessário adicionar alguns atributos ocultos em diversas classes.

Além disso, há casos onde substituir não seria possível. Por exemplo:

public class Foo<T> { public T foo(Object o) { return (T) o; // *** } }public class Moo { public static void main(String[] args) { Object x = 42; Foo<Integer> a = new Foo<Integer>(); a.foo(x); x = "batatinha"; Foo<String> b = new Foo<String>(); b.foo(x); } }Aqui, essa substituição não funcionaria. Na linha com o ***, ele deveria colocar o que? Integer? String? A única coisa que dá é Object mesmo. Se fosse substituir por Integer ou por String, teria que fazer isso para cada objeto, e isso iria requerer uma classe para cada tipo de objeto. Ainda assim ia ter alguns probleminhas quando uma superclasse tivesse um generic em um método final. Outra alternativa seria simplesmente mandar a compatibilidade com o java 1.4 e inferiores para o espaço, mas uma das bandeiras do java é justamente a retrocompatibilidade.

sem sentido??

eu vi sentido no que o Lavieri falou e concordo.

não entendi na falta de sentido ai.

uma justificativa pra que ele não faça isso pode ser:

não um modelo da Linguagem Java.

pois é, também acho que faz todo sentido…

quando se começar a usar generics cedo ou tarde você acaba tendo necessidade (ou desejo) similar…

os artigos abaixo explicam bem os motivos que fizeram generics ser implementado assim:

http://www.ibm.com/developerworks/java/library/j-jtp01255.html
http://blog.caelum.com.br/2008/04/28/nao-posso-descobrir-nem-instanciar-tipos-genericos-porque/

e esse aqui uma forma NÃO recomendada de (talvez) contornar esse problema:
http://blog.caelum.com.br/2006/10/29/brincando-com-generics-o-bizarregenericdao/

apesar de entender os motivos dessa técnica de erasure eu realmente gostaria que generics tivesse mais poder…