dúvida generics

Olá,

Estou estudando para certificação e vi no livro que podemos ter uma interface genérica e um método static genérico também. Tentei fazer um código para ver como funciona na prática. Montei esse código:


public interface InterfaceGenerica<X extends Number, Y extends Number> {
    void somaNumeros(X x, Y y);
}

public class ImplementacaoGenerica implements InterfaceGenerica<Double, Integer> {
    public void somaNumeros(Double d, Integer i){
        System.out.println(d + i);
    }
    
    static public <T, U> void concatenarTextos(T t, U u){
        System.out.println((String)t + (String)u);
    }
    
    static public void main(String... args){
        new ImplementacaoGenerica().somaNumeros(2.1, 1);
        
        concatenarTextos("Teste", " com generics");
    }
}

Compila OK. O problema é quando tento fazer isso:

static public <T super String, U super String> void concatenarTextos(T t, U u){
        System.out.println(t + u);
    }

Gera erro:

java.lang.ClassFormatError: Duplicate field name&signature in class file certificacao/generics/ImplementacaoGenerica

Porque?

Outra coisa também. Alguém poderia me explicar onde uma interface genérica ou um método static genérico são úteis? Alguém tem um exemplo mais funcional e útil melhor do que o meu?

Obrigado.

static public <T super String, U super String> void concatenarTextos(T t, U u){  
        System.out.println(t + u);  
   } 

Não sei onde você colocou esse outro método, mas métodos estáticos não podem ser sobrescritos talvez seja isso o erro.

rafadelnero, esse outro método que você não achou não compila, por isso deixei no meu código assim:

static public <T, U> void concatenarTextos(T t, U u){ System.out.println((String)t + (String)u); }

Mas quando troco o método acima que compila pelo método:

static public <T super String, U super String> void concatenarTextos(T t, U u){ System.out.println(t + u); }

dá erro. Sacou? Queria saber o motivo do erro, pois o código me parece normal, não consigo identificar qual o problema com o código.

Olá o erro ocorre porque vc ta usando soma para tipos Genéricos, e daí o compilador não entende se é uma concatenação ou uma soma matemática, já quando vc faz um downcast para String ele entende que é uma concatenação, se fosse para Number ele entederia como soma.

Se vc colocar somente System.out.print(t); e depois system.out.println(u); vai funcionar .

Eu já tentei comentar essa linha

mas o erro continua. O erro parece ser na declaração:

Tem algo errado nessa declaração de método?

não o problema não é a declaração do método genérico e sim na hora de dar o Println();

vc colocou uma soma t+ u , Como o compilador não sabe ql operação está sendo realizado se é de concatenação ou de soma ele acusa o erro . Tente colocar uma string no meio das variáveis locais t e u, tipo: t + " qualquer coisa " + u , ai da certo, pois é uma operação de concatenação.

Eu estava usando o Netbeans, mas ajustei e rodei pelo Eclipse agora esse código:

[code]interface InterfaceGenerica<X extends Number, Y extends Number> {
void somaNumeros(X x, Y y);
}

public class ImplementacaoGenerica implements InterfaceGenerica<Double, Integer> {
public void somaNumeros(Double d, Integer i) {
System.out.println(d + i);
}

static public <T super String, U super String> void concatenarTextos(T t, U u) {
System.out.println(t + " " + u);
}

static public void main(String... args) {
new ImplementacaoGenerica().somaNumeros(2.1, 1);

concatenarTextos("Teste", " com generics");
}

}[/code]

Deu esse erro agora:
Exception in thread “main” java.lang.Error: Unresolved compilation problem:
The method concatenarTextos(T, U) from the type ImplementacaoGenerica refers to the missing type T

at ImplementacaoGenerica.main(ImplementacaoGenerica.java:17)

Se passo o mouse em cima da palavra super aparece: “Syntax error on token super , , expected”

Qual o problema desse código?

Obrigado.

A é q java não permite que se use limite inferior para tipos genéricos, tal como exemplo1 . a razão disso talvez seja que o compilador permitiria usar objetos do tipo ou mas não permitiria ou , mas como não permitiria se um é um Number e por ai vai , seria uma ambiguidade na linguagem.
No entanto java permite coisas do tipo List<? super Number> lista =new ArrayList();
lista.add(3.2) ; lista(new Long(222L)); e por ai vai …

Desculpe mas não entendi muito bem ainda.

Essa é uma ótima pergunta, eu também não sei explicar na verdade só sei que as regras são essas : ponto de interrogação + super somente para variáveis de referência e tipos parametrizaveis somente para metodos e classes :?

Dá uma olhada nesse exemplo :
class A{}
class GenClass{
public A<? super T> getNow(A<? super T> a){
return new A();
}
}

Compila ?

Sim , pois o uso de tipos parametrizáveis é somente nas classes e nos métodos nas variáveis usa-se a notação de interrogação + super.
Ainda sim é complicado pois como seria a descrição desse exemplo a classe A do tipo parametrizado E. A classe GenClass com tipo parametrizável E que estende A . Ela possui um método getNow que declara um tipo parametrizável T que estende E também e retorna A , sendo A qualquer tipo superior da hierarquia do T . Só que lembre que E estende A então T estende também A , certo? Então o parâmetro para o método getNow poderia ser qq tipo E ou tipo A ou qualquer super de T (para o tipo parametrizável) .

Agora porque da regra realmente não sei pergunta na parte avançada do Fórum .

Abraços