A segurança de tipos pode impedir certas construções válidas, como comparar valores absolutos de diferentes tipos numéricos.
Um exemplo é o método
absEqual()
, que verifica se dois objetosNumericFns
contêm números com valores absolutos iguais, mesmo que sejam de tipos diferentes, comoDouble
eFloat
.O método compara o valor absoluto do objeto chamador com o do argumento passado.
NumericFns<Double> dOb = new NumericFns<Double>(1.25);
NumericFns<Float> fOb = new NumericFns<Float>(-1.25);
if(dOb.absEqual(fOb))
System.out.println("Absolute values are the same.");
else
System.out.println("Absolute values differ.");
Criar o método
absEqual()
parece simples, mas surgem problemas ao definir o parâmetro de tipo paraNumericFns
.A dúvida está em qual tipo usar como parâmetro de
NumericFns
, já que ele deve lidar com diferentes tipos numéricos.Uma solução inicial seria usar o mesmo tipo genérico
T
, mas isso pode não atender a todos os casos.
Exemplo: Example1.java
// Este código não funcionará!
// Determina se os valores absolutos de dois objetos são iguais.
boolean absEqual(NumericFns<T> ob) {
if(Math.abs(num.doubleValue()) ==
Math.abs(ob.num.doubleValue()) return true;
return false;
}
Usar
Math.abs()
para comparar valores absolutos emabsEqual()
só funciona se ambos os objetosNumericFns
forem do mesmo tipo, comoNumericFns<Integer>
.Essa abordagem não é genérica e impede a comparação entre diferentes tipos, como
NumericFns<Integer>
eNumericFns<Double>
.Para criar uma solução genérica, utiliza-se o argumento curinga
(?)
, que representa um tipo desconhecido em Java.
// Determina se os valores absolutos de
// dois objetos são iguais.
boolean absEqual(NumericFns<?> ob) { // Observe o curinga.
if(Math.abs(num.doubleValue()) ==
Math.abs(ob.num.doubleValue())) return true;
return false;
}
NumericFns<?>
permite comparar dois objetosNumericFns
de qualquer tipo, tornando o método genérico.Isso possibilita a comparação de valores absolutos entre objetos
NumericFns
com diferentes tipos numéricos.
// Usa um curinga.
class NumericFns<T extends Number> {
T num;
// Passa para o construtor uma referência
// a um objeto numérico.
NumericFns(T n) {
num = n;
}
// Retorna o recíproco.
double reciprocal() {
return 1 / num.doubleValue();
}
// Retorna o componente fracionário.
double fraction() {
return num.doubleValue() - num.intValue();
}
// Determina se os valores absolutos de
// dois objetos são iguais.
boolean absEqual(NumericFns<?> ob) {
if(Math.abs(num.doubleValue()) ==
Math.abs(ob.num.doubleValue())) return true;
return false;
}
// ...
}
// Demonstra um curinga.
class WildcardDemo {
public static void main(String args[]) {
NumericFns<Integer> iOb =
new NumericFns<Integer>(6);
NumericFns<Double> dOb =
new NumericFns<Double>(-6.0);
NumericFns<Long> lOb =
new NumericFns<Long>(5L);
System.out.println("Testing iOb and dOb.");
// Nesta chamada, o tipo curinga equivale a Double.
if(iOb.absEqual(dOb))
System.out.println("Absolute values are equal.");
else
System.out.println("Absolute values differ.");
System.out.println();
System.out.println("Testing iOb and lOb.");
// Nesta chamada, o curinga equivale a Long.
if(iOb.absEqual(lOb))
System.out.println("Absolute values are equal.");
else
System.out.println("Absolute values differ.");
}
}
Observe estas duas chamadas a absEqual( ):
if(iOb.absEqual(dOb))
if(iOb.absEqual(lOb))Com o curinga
(<?>)
, é possível chamarabsEqual()
com objetosNumericFns
de tipos diferentes, comoNumericFns<Integer>
eNumericFns<Double>
, ouNumericFns<Long>
.O curinga não altera os tipos permitidos para criar objetos
NumericFns
; isso continua sendo controlado pela cláusula extends na declaração.Ele apenas permite que qualquer objeto válido de
NumericFns
seja usado no método.
Top comments (0)