Generics no Objeto e não na referencia

Galera qual a diferença de:

ArrayList a = new ArrayList<Integer>();
para

ArrayList<Integer> b = new ArrayList<Integer>();

Bem ao fazer a primeira opção

ArrayList a = new ArrayList<Integer>();

você está criando um arrayList que só recebe Integer, só que a referencia desde array list (a forma que você “ver” ele) é como se fosse um arrayList generico

a segunda forma

ArrayList<Integer> b = new ArrayList<Integer>();

você está criando um array list que so recebe Integer, e “visualiza” ele como sendo um arrayList que só recebe Integer.

Blz observe que a diferença é so na forma de “Visualizar” eles mas ele SÃO em ambos os casos ArrayList, e só iram funcionar como ArrayList

[quote=Victor Gerin]Bem ao fazer a primeira opção

ArrayList a = new ArrayList<Integer>();

você está criando um arrayList que só recebe Integer, só que a referencia desde array list (a forma que você “ver” ele) é como se fosse um arrayList generico

a segunda forma

ArrayList<Integer> b = new ArrayList<Integer>();

você está criando um array list que so recebe Integer, e “visualiza” ele como sendo um arrayList que só recebe Integer.

Blz observe que a diferença é so na forma de “Visualizar” eles mas ele SÃO em ambos os casos ArrayList, e só iram funcionar como ArrayList[/quote]
mas porque no primeiro caso se eu for fazer um for each eu tenho que fazer com object

for(Object obj: a)

Enquanto que da segunda forma eu posso fazer um com Integer

for(Integer obj: b)

Alias eu posso até adicionar uma String que compila normalmente

	int go(){
		return id;
	}
	public static void main(String[] args) {
		ArrayList d = new ArrayList<Integer>();
		d.add(1);
		d.add(2);
		d.add(3);
		d.add("4");
		
		for(Object a: d){
			System.out.println(a+"");
		
			
		}
	}
}

interesante, acho que isso deve está acontecendo depois do update que o java teve, pois não é necessário declarar o generics na hora de contruir o objeto tipo assim

ArrayList<int> Lista = new ArrayList();

so na referencia você precisa colocar o tipo, isso agora é assim mas antigamente era assim

ArrayList<int> Lista = new ArrayList<int>();

você tinha que escrever no dois lados

dai acho que por causa desse update do java é o generics da referencia (esqueda que faz diferença) e o outro é “inutil” só n é mais usado, talvez seja por isso

ou seja se você deixa em branco ele vai contar como o ArrayList, se vc define fica o definido

Como assim não é mais utilizado? Até onde eu sei só foi implementada a notação diamante, que é mais ou menos assim:List<Integer> lista = new ArrayList<>() Você não precisa escrever Integer de novo, mas o diamante está ali.

A diferença entre colocar ou não o tipo na variável, é que em tempo de compilação você pode definir o tipo de elementos que a lista contém, caso você não especifique, o compilador deduz que pode possuir qualquer coisa, ou seja, Object (já que todas as classes são subclasses de Object).

Mas lembre-se que isso existe somente em tempo de compilação. Em tempo de execução os generics não existem mais.

Ah, e não é possível definir um tipo primitivo com generics, então: List<int> // errado List<Integer> // corrreto

verdade exemplo mal formulado rsrs, mas ainda sim o segundo diamante não é necessário colocar, ele se tornou opcional (o que isso tenho certa pode testa) tipo ele nem ali precisa está.

Agora também a notação generics ate onde sei (me corriga se eu erra) ela serve para que o código fique mais fácil de entender e escrever alem também que ajuda o copilador java a encontrar erros em tempo de copilação, se parar para pensar então no fundo o objeto que você trabalha é o mesmo sem diferença nenhuma.

tipo o que to querendo dizer é que na essência o objeto será o mesmo, isso é só um recurso para o copilador e o programador, não para a jvm.

[quote=Victor Gerin]verdade exemplo mal formulado rsrs, mas ainda sim o segundo diamante não é necessário colocar, ele se tornou opcional (o que isso tenho certa pode testa) tipo ele nem ali precisa está.

Agora também a notação generics ate onde sei (me corriga se eu erra) ela serve para que o código fique mais fácil de entender e escrever alem também que ajuda o copilador java a encontrar erros em tempo de copilação, se parar para pensar então no fundo o objeto que você trabalha é o mesmo sem diferença nenhuma.

tipo o que to querendo dizer é que na essência o objeto será o mesmo, isso é só um recurso para o copilador e o programador, não para a jvm.[/quote]

Não creio que seja isso não, creio ser útil apenas para polimorfismo, além do mais essa declaração:

ArrayList a = new ArrayList<Integer>();

Pode complicar a vida do compilador e muito, além de dificultar a manutenção, pois como foi declarado em uma única linha tranquilo, mas e se fosse assim:

ArrayList a; // aqui sabemos que extende-se a Object diretamente
...
...
...
// vinte/trinta linhas depois preciso inicializá-lo:
a = new ArrayList<Integer>(); // começa a complicar aqui, mas ainda funciona tranquilo...

...
...

Integer b = a.get(0); // ixi, agora foi...

E agora, o elemento em a.get(0) é um Object ou Integer? Será necessário casting ou o compilador vai aceitar numa boa?

Pelo o teste que fiz aqui o copilador entende que esse o seu caso mostrado ele trata o ArrayList sendo um ArrayList de Object como se você não tivesse declarado nada

[code]
ArrayList a;

    a = new ArrayList<Integer>();
    
    
    a.add("1");
    
    
    System.out.println(a.get(0).getClass().getName());[/code]

ele trata assim por que na primeira parte não foi definido o generics e pelo visto para o copilador é ela que conta

[quote=Victor Gerin]Pelo o teste que fiz aqui o copilador entende que esse o seu caso mostrado ele trata o ArrayList sendo um ArrayList de Object como se você não tivesse declarado nada

[code]
ArrayList a;

    a = new ArrayList<Integer>();
    
    
    a.add("1");
    
    
    System.out.println(a.get(0).getClass().getName());[/code]

ele trata assim por que na primeira parte não foi definido o generics e pelo visto para o copilador é ela que conta[/quote]

Sim e isso não é ruim para o entendimento, afinal você inicializou a lista como sendo de Integer’s correto, deveria buscar seu primeiro ancestral, ou seja, Integer e não Object certo?

Tentou atribuir o elemento dessa forma?

int b = a.get(0).intValue();

Será que o compilador vai reclamar?

acabei de tentar o copilador reclama porque ele toma como base o generics passado quando você gera a referencia, como eu disse antes o segundo é opcional colocar e pelo visto o segundo n tem efeito nenhum alem de visual

É importante lembrar que Generics só existe em tempo de compilação. Por motivos de compatibilidade o bytecode gerado não possui informação nenhuma de tipos genéricos, a não ser via reflection, onde é possível descobrir o tipo dos objetos.

E não usar a notação diamante gera warnings no compilador, então não é exatamente a mesma coisa, apesar do código rodar.