Dúvida Generics

22 respostas
evertonsilvagomesjav

Fala ai pessoal, bom tem um exercicio aqui de Generics que me gerou uma dúvida.

Dado o método declarado como:

public static <E extends Number> List<? super E> process(List<E> nums)

Um programador deseja usar o método da seguinte forma:

// INSIRA AS DECLARAÇÕES AQUI!!!

output = process(input);

Quais declarações poderiam ser colocadas para permitir a compilação do codigo:

A) ArrayList input = null;
ArrayList output = null;

B) ArrayList input = null;
List output = null;

C) ArrayList input = null;
List output = null;

D) List input = null;
ArrayList output = null;

E) List input = null;
List output = null;

F) List input = null;
List output = null;

Bom galera eu entendi pelo método o seguinte, o Elemento "E" pode ser um "Number" ou algo que estenda "Number" e o retorno pode ser algo que estenda "Number" ou um "Number" e algum de seu "Supertipo". Nesse caso a resposta no livro esta B, E, F. Se eu posso passar um ArrayList para um List por argumento no método porque eu nao posso retornar um ArrayList quando o retorno é um List? A letra "C" nao esta correta nao? Porque o retorno esta List ou seja se eu passar um eu poderia retornar o seu SuperTipo nao?

Grato!!!

22 Respostas

V

vc pode retornar um arraylist sim porém vc só pode atribuir a um List por questão de segurança, por examplo imagine que o seu método retorne um List e esse List por exemplo seja uma outra classe diferente de ArrayList…
ex: isso não funciona

class MyList implements List {
  
  //métodos

}

class Teste {

 public List criarLista() {
    
    //percebeu o problema???? quando o meu tipo de retorno é List eu posso retornar qualquer classe que implementa List
    return MyList();
 
 }  

 public static void main(String[] args) {
   
    List myList = criarLista();
    //opa erro aqui estaria atribuindo ao ArrayList um MyList(minha classe que criei acima), esse código não compilaria por causa dessa linha abaixo
    ArrayList myList2 = criarLista();
  }
  
}
evertonsilvagomesjav

vmsb mas no caso de cima nao e possivel?

V

qual caso???rsrs…
o código que eu coloquei não funciona por causa da última linha…
a letra C está incorreta porq o tipo de retorno é List<? super E> ou seja eu posso retornar um Number, mas eu tb posso retornar um Object
por isso a linha: ArrayList<Integer> input = null; List<Number> output = null; output = process(input);
está incorreta…

sergiotaborda
evertonsilvagomesjava:
Fala ai pessoal, bom tem um exercicio aqui de Generics que me gerou uma dúvida.

Dado o método declarado como:

public static <E extends Number> List<? super E> process(List<E> nums)

Um programador deseja usar o método da seguinte forma:

// INSIRA AS DECLARAÇÕES AQUI!!!

output = process(input);

Quais declarações poderiam ser colocadas para permitir a compilação do codigo:

A) ArrayList input = null;
ArrayList output = null;

B) ArrayList input = null;
List output = null;

C) ArrayList input = null;
List output = null;

D) List input = null;
ArrayList output = null;

E) List input = null;
List output = null;

F) List input = null;
List output = null;

Bom galera eu entendi pelo método o seguinte, o Elemento "E" pode ser um "Number" ou algo que estenda "Number" e o retorno pode ser algo que estenda "Number" ou um "Number" e algum de seu "Supertipo". Nesse caso a resposta no livro esta B, E, F. Se eu posso passar um ArrayList para um List por argumento no método porque eu nao posso retornar um ArrayList quando o retorno é um List? A letra "C" nao esta correta nao? Porque o retorno esta List ou seja se eu passar um eu poderia retornar o seu SuperTipo nao?

Pela assinatura vc sabe que o retorno tem que ser do mesmo tipo do argumento. logo as opções C e D estão erradas.
Pela assinatura o retorno é List e não ArrayList , logo A está errada.

B, E e F estão corretas porque o tipo generico é o mesmo e o retorno é List ( não arraylist)

o super é apenas para distrair.

evertonsilvagomesjav

Cara pra ser sincero ainda nao entedi…

Eu tenho o seguinte codigo:

Eu posso passar por exemplo:

ArrayList<Integer> teste; process(teste); // e valido pq ArrayList implementa List certo?

Agora o retorno não esta falando que pode ser um Integer ou um Double ou um Float ou um Number ou um Object? Isso que nao estou entendendo…

V

vou explicar:
a instrução:

public static <E extends Number> List<? super E> process(List<E> nums)

está querendo dizer isso: eu posso passar como argumento qualquer classe que implemente List e este E pode ser qualquer classe que extenda Number, e o meu tipo de retorno é um List de qualquer superclasse de E

evertonsilvagomesjav

mas eu poderia retornar dessa fora por exemplo

se eu passar para o método:

retorno:

isso nao valeria?

V

outros exemplos de chamada válida para este método

List<? super Number> l1 = process(new ArrayList<Number>());
List<? super Integer> l2 = process(new ArrayList<Integer>());
V

evertonsilvagomesjava:
mas eu poderia retornar dessa fora por exemplo

se eu passar para o método:

retorno:

isso nao valeria?

não o tipo de retorno só pode List… mas no argumento do método vc pode passar qualquer classe que implemente List

evertonsilvagomesjav

nossa que treta, entao no argumento pode ter herança e no retorno nao, é isso?

V

é que o tipo de retorno só pode ser List porq vc pode retornar qualquer classe que implemente List, não só ArrayList…
conseguiu entender aquele exemplo que eu fiz
vou postar de novo:

class MyList implements List {   
     
  //métodos   
  
}   
  
class Teste {   
  
public List criarLista() {   
       
    //percebeu o problema???? quando o meu tipo de retorno é List eu posso retornar qualquer classe que implementa List(até aqui o código funciona)   
    return MyList();   
  
}     
  
public static void main(String[] args) {   
     
    List myList = criarLista();   
    //opa erro aqui estaria atribuindo ao ArrayList um MyList(minha classe que criei acima), esse código não compilaria por causa dessa linha abaixo   
    ArrayList myList2 = criarLista();   
  }   
     
}
evertonsilvagomesjav

to fazendo os teste aqui isso era pra compilar nao era nao?

package com.collections;

import java.util.ArrayList;
import java.util.List;

public class Generics {

	public static <E extends Number> List<? super E> teste(List<E> lista){
		
		return lista;
		
	}
	
	public static void main(String[] args) {
				
		ArrayList<Integer> lista = null;
		
		teste(lista);
		
		List<Integer> listaTeste = teste(lista);
		
	}
	
}
V

troque por

List<? super Integer> listaTeste = process(lista);

que funciona…ah e só mais um detalhe se eu não me engano esse exercicio está errado no livro…
vou pesquisar aqui mas acho que é isso msm…

V

por exemplo quando o retorno é List<? extends Number>
na hora que vc for chamar o método tem que ser assim:

List<? extends Number> lista = ...
evertonsilvagomesjav

vmsb troquei pelos dois pra fazer o teste

List<? extends Number> listaTeste = teste // nao compila(lista); List<? super Integer> listaTeste1 = teste(lista); // compila

Mas olha só no primeiro caso era pra ter compilado tb nao?

V

vc deve obdecer o tipo de retorno por exemplo:
se no tipo de retorno é List<? super …> na atribuição vc só pode user List<? super…>
entendeu??? :slight_smile:

V

se vc tiver o livro da katy ai da uma olhada em um outro exercicio quase = a esse…
esse é bom exemplo pra estudar, geralmente nos simulados até msm no ExamLab que é muito dificil não tem questões com nível de dificuldade acima desse da questão…

evertonsilvagomesjav

NOSSSSA cara que treta veio na logica seria mesma coisa nao? kkk, entao todas as alternativas que eu aprensentai la em cima no primeiro post nao compila certo? Esse exercicio e do livro da kathy mesmo.

V

eh isso msm testei aqui e não compilou…tem um tópico antigo aqui no fórum msm a respeito desse exercicio e acho que ele ta errado msm…
é a parte mais complicada da prova msm…mas não creio que caia questões de nivel de dificuldade acima desse exercicio…

evertonsilvagomesjav

nossa depois dessa eu vou debugar todos exercicios aqui de Generics rs

V

realmente o exercicio do livro está errado evertonsilvagomesjava de uma olhada la em http://www.coderanch.com/t/257589/Programmer-Certification-SCJP/certification/K-B-SCJP-Errata-Updated e procura na página 620 eu acho na versão inglesa a sintaxe correta do método é:

public static <E extends Number> List<E> process(List<E> nums) { 

}

e com isso as respostas corretas são B, E, F

evertonsilvagomesjav

hummm ok vmsb ai sim as respostas eheh vlwww

Criado 19 de janeiro de 2010
Ultima resposta 21 de jan. de 2010
Respostas 22
Participantes 3