// Java Language Specification
// Third Edition
// CHAPTER 4
// Types, Values, and Variables
// 4.11 Where Types Are Used
class MiscMath {
int divisor;
MiscMath(int divisor) {
this.divisor = divisor;
}
float ratio(long l) {
try {
l /= divisor;
} catch (Exception e) {
if (e instanceof ArithmeticException)
l = Long.MAX_VALUE;
else
l = 0;
}
return (float)l;
}
double gausser() {
Random r = new Random();
double[] val = new double[2];
val[0] = r.nextGaussian();
val[1] = r.nextGaussian();
return (val[0] + val[1]) / 2;
}
Collection<Number> fromArray(Number[] na) {
Collection<Number> cn = new ArrayList<Number>();
for (Number n : na) {
cn.add(n);
}
return cn;
}
void <S> loop(S s) {
this.<S>loop(s);
}
}[/code]
Observando o último método void <S> loop(S s), aparece a seguinte dúvida. Há alguma diferença entre colocar <S> depois de void como está no exemplo da especificação e que repeti abaixo na classe Depois ou se deveria colocar <S> void loop (S s) tal como na classe Antes.
public class Depois {
void <S> loop(S s) {
this.<S>loop(s);
}
}
public class Antes {
<S> void loop(S s) {
this.<S>loop(s);
}
}
Porque o tipo genérico pode se referir a todo o contexto do método, inclusive seu tipo de retorno. Então eu acho que ele geraria um erro de compilação porque caso o método mude para retornar uma variável S, ela não poderia ser resolvida porque a declaração do tipo genérico estaria depois do tipo de retorno.
Tirando o fato de estar faltando um ponto-e-vírgula num foreach, o erro acontece porque o void é tratado como um modificador de acesso e o tipo de retorno fica indeterminado pelo compilador. Tudo isso por causa do estar no lugar “errado” que na verdade é tratado como se ele estivesse após o último modificador de acesso (o “void”) e antes do retorno do método (o “”). O compilador se perde por causa disso.